[Scummvm-cvs-logs] CVS: scummvm/scumm intern.h,2.412,2.413 script_v72he.cpp,2.230,2.231 script_v90he.cpp,2.207,2.208

Gregory Montoir cyx at users.sourceforge.net
Sat Apr 2 09:20:40 CEST 2005


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16886/scumm

Modified Files:
	intern.h script_v72he.cpp script_v90he.cpp 
Log Message:
initial implementation of o72_arrayOps_127 and o90_sortArray

Index: intern.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/intern.h,v
retrieving revision 2.412
retrieving revision 2.413
diff -u -d -r2.412 -r2.413
--- intern.h	1 Apr 2005 13:05:38 -0000	2.412
+++ intern.h	2 Apr 2005 17:19:43 -0000	2.413
@@ -739,6 +739,10 @@
 	virtual void writeArray(int array, int idx2, int idx1, int value);
 	void redimArray(int arrayId, int newDim2start, int newDim2end, 
 					int newDim1start, int newDim1end, int type);
+	void checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end);
+	void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end, 
+					int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end);
+	void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
 	virtual int setupStringArray(int size);
 	int readFileToArray(int slot, int32 size);
 	void writeFileFromArray(int slot, int resID);
@@ -902,6 +906,9 @@
 	int isWizPixelNonTransparent(int resnum, int state, int x, int y, int flags);
 	uint8 getWizPixelColor(int resnum, int state, int x, int y, int flags);
 	int computeWizHistogram(int resnum, int state, int x, int y, int w, int h);
+
+	void getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end);
+	void sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder);
 	
 	uint8 *getHEPalette(int palSlot);
 	void setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b);

Index: script_v72he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v72he.cpp,v
retrieving revision 2.230
retrieving revision 2.231
diff -u -d -r2.230 -r2.231
--- script_v72he.cpp	1 Apr 2005 08:51:12 -0000	2.230
+++ script_v72he.cpp	2 Apr 2005 17:19:43 -0000	2.231
@@ -1423,18 +1423,19 @@
 		break;
 	case 127:
 		{
-		// TODO
-		//Array1
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
-		//Array2
-		array = fetchScriptWord();
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
+			int a1_dim1end = pop();
+			int a1_dim1start = pop();
+			int a1_dim2end = pop();
+			int a1_dim2start = pop();
+			int array2 = fetchScriptWord();
+			int a2_dim1end = pop();
+			int a2_dim1start = pop();
+			int a2_dim2end = pop();
+			int a2_dim2start = pop();
+			if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
+				warning("Source and dest ranges size are mismatched");
+			}
+			copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
 		}
 		break;
 	case 128:
@@ -1977,6 +1978,107 @@
 	ah->dim2end = TO_LE_32(newDim2end);
 }
 
+void ScummEngine_v72he::checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end) {
+	if (dim1end < dim1start) {
+		warning("Across max %d smaller than min %d", dim1end, dim1start);
+ 	}
+ 	if (dim2end < dim2start) {
+	 	warning("Down max %d smaller than min %d", dim2end, dim2start);
+ 	}
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+	assert(ah);
+	if (ah->dim2start > dim2start || ah->dim2end < dim2end || ah->dim1start > dim1start || ah->dim1end < dim1end) {
+		warning("Invalid array access (%d,%d,%d,%d) limit (%d,%d,%d,%d)", dim2start, dim2end, dim1start, dim1end, ah->dim2start, ah->dim2end, ah->dim1start, ah->dim1end);
+	}
+}
+
+void ScummEngine_v72he::copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end, 
+				int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end)
+{
+	debug(5, "ScummEngine_v72he::copyArray(%d, [%d,%d,%d,%d], %d, [%d,%d,%d,%d])", array1, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
+	byte *dst, *src;
+	int dstPitch, srcPitch;
+	int rowSize;
+	checkArrayLimits(array1, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end);
+	checkArrayLimits(array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
+	int a12_num = a1_dim2end - a1_dim2start + 1;
+	int a11_num = a1_dim1end - a1_dim1start + 1;	
+	int a22_num = a2_dim2end - a2_dim2start + 1;
+	int a21_num = a2_dim1end - a2_dim1start + 1;
+	if (a22_num != a12_num || a21_num != a11_num) {
+		warning("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
+	}	
+
+	if (array1 != array2) {
+		ArrayHeader *ah1 = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
+		assert(ah1);
+		ArrayHeader *ah2 = (ArrayHeader *)getResourceAddress(rtString, readVar(array2));
+		assert(ah2);
+		if (FROM_LE_32(ah1->type) == FROM_LE_32(ah2->type)) {
+			copyArrayHelper(ah1, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
+			copyArrayHelper(ah2, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
+			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
+				memcpy(dst, src, rowSize);
+				dst += dstPitch;
+				src += srcPitch;
+			}
+		} else {
+			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start) {
+				int a2dim1 = a2_dim1start;
+				int a1dim1 = a1_dim1start;
+				for(; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1) {
+					int val = readArray(array2, a2_dim2start, a2dim1);
+					writeArray(array1, a1_dim2start, a1dim1, val);
+				}
+			}
+		}
+	} else {
+		if (a2_dim2start != a1_dim2start || a2_dim1start != a1_dim1start) {
+			ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
+			assert(ah);
+			if (a2_dim2start > a1_dim2start) {
+				copyArrayHelper(ah, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
+				copyArrayHelper(ah, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
+			} else {
+				copyArrayHelper(ah, a1_dim2end, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
+				copyArrayHelper(ah, a2_dim2end, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);				
+			}
+			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
+				memcpy(dst, src, rowSize);
+				dst += dstPitch;
+				src += srcPitch;
+			}
+		}
+	}
+}
+
+void ScummEngine_v72he::copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num) {
+	const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
+	const int offset = pitch * (idx2 - FROM_LE_32(ah->dim2start)) + idx1 - FROM_LE_32(ah->dim1start);
+
+	switch (FROM_LE_32(ah->type)) {
+	case kByteArray:
+	case kStringArray:
+		*num = len1 - idx1 + 1;
+		*size = pitch;
+		*data = ah->data + offset;
+		break;
+	case kIntArray:
+		*num = (len1 - idx1 + 1) * 2;
+		*size = pitch * 2;
+		*data = ah->data + offset * 2;
+		break;
+	case kDwordArray:
+		*num = (len1 - idx1 + 1) * 4;
+		*size = pitch * 4;
+		*data = ah->data + offset * 4;
+		break;
+	default:
+		error("Invalid array type", FROM_LE_32(ah->type));
+		break;
+	}
+}
+
 void ScummEngine_v72he::o72_checkGlobQueue() {
 	byte subOp = fetchScriptByte();
 	int idx = pop();

Index: script_v90he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v90he.cpp,v
retrieving revision 2.207
retrieving revision 2.208
diff -u -d -r2.207 -r2.208
--- script_v90he.cpp	2 Apr 2005 14:24:41 -0000	2.207
+++ script_v90he.cpp	2 Apr 2005 17:19:44 -0000	2.208
@@ -1960,6 +1960,103 @@
 	}
 }
 
+void ScummEngine_v90he::getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end) {
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+	assert(ah);
+	if (dim2start && *dim2start == -1) {
+		*dim2start = ah->dim2start;
+	}
+	if (dim2end && *dim2end == -1) {
+		*dim2end = ah->dim2end;
+	}
+	if (dim1start && *dim1start == -1) {
+		*dim1start = ah->dim1start;
+	}
+	if (dim1end && *dim1end == -1) {
+		*dim1end = ah->dim1end;
+	}
+}
+
+static int sortArrayOffset;
+
+static int compareByteArray(const void *a, const void *b) {
+	int va = *((const uint8 *)a + sortArrayOffset);
+	int vb = *((const uint8 *)a + sortArrayOffset);
+	return va - vb;
+}
+
+static int compareByteArrayReverse(const void *a, const void *b) {
+	int va = *((const uint8 *)a + sortArrayOffset);
+	int vb = *((const uint8 *)a + sortArrayOffset);
+	return vb - va;
+}
+
+static int compareIntArray(const void *a, const void *b) {
+	int va = READ_LE_UINT16((const uint8 *)a + sortArrayOffset * 2);
+	int vb = READ_LE_UINT16((const uint8 *)b + sortArrayOffset * 2);
+	return va - vb;
+}
+
+static int compareIntArrayReverse(const void *a, const void *b) {
+	int va = READ_LE_UINT16((const uint8 *)a + sortArrayOffset * 2);
+	int vb = READ_LE_UINT16((const uint8 *)b + sortArrayOffset * 2);
+	return vb - va;
+}
+
+static int compareDwordArray(const void *a, const void *b) {
+	int va = READ_LE_UINT32((const uint8 *)a + sortArrayOffset * 4);
+	int vb = READ_LE_UINT32((const uint8 *)b + sortArrayOffset * 4);
+	return va - vb;
+}
+
+static int compareDwordArrayReverse(const void *a, const void *b) {
+	int va = READ_LE_UINT32((const uint8 *)a + sortArrayOffset * 4);
+	int vb = READ_LE_UINT32((const uint8 *)b + sortArrayOffset * 4);
+	return vb - va;
+}
+
+void ScummEngine_v90he::sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder) {
+	debug(5, "sortArray(%d, [%d,%d,%d,%d], %d)", array, dim2start, dim2end, dim1start, dim1end, sortOrder);
+
+	assert(dim1start == dim1end);
+	checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+	assert(ah);
+
+	const int num = dim2end - dim2start + 1;
+	const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
+	const int offset = pitch * (dim2start - FROM_LE_32(ah->dim2start));
+	sortArrayOffset = dim1start - FROM_LE_32(ah->dim1start);
+
+	switch (FROM_LE_32(ah->type)) {
+	case kByteArray:
+	case kStringArray:
+		if (sortOrder <= 0) {
+			qsort(ah->data + offset, num, pitch, compareByteArray);
+		} else {
+			qsort(ah->data + offset, num, pitch, compareByteArrayReverse);
+		}
+		break;
+	case kIntArray:
+		if (sortOrder <= 0) {
+			qsort(ah->data + offset * 2, num, pitch * 2, compareIntArray);
+		} else {
+			qsort(ah->data + offset * 2, num, pitch * 2, compareIntArrayReverse);
+		}
+		break;
+	case kDwordArray:
+		if (sortOrder <= 0) {
+			qsort(ah->data + offset * 4, num, pitch * 4, compareDwordArray);
+		} else {
+			qsort(ah->data + offset * 4, num, pitch * 4, compareDwordArrayReverse);
+		}
+		break;
+	default:
+		error("Invalid array type", FROM_LE_32(ah->type));
+		break;
+	}
+}
+
 void ScummEngine_v90he::o90_sortArray() {
 	// Sorts array via qsort
 	byte subOp = fetchScriptByte();
@@ -1967,21 +2064,24 @@
 	switch (subOp) {
 	case 129:
 	case 134: // HE100
-		fetchScriptWord();
-		pop();
-		pop();
-		pop();
-		pop();
-		pop();
+		{	
+			int array = fetchScriptWord();
+			int sortOrder = pop();
+			int dim1end = pop();
+			int dim1start = pop();
+			int dim2end = pop();
+			int dim2start = pop();
+			getArrayDim(array, &dim2start, &dim2end, &dim1start, &dim1end);
+			sortArray(array, dim2start, dim2end, dim1start, dim1end, sortOrder);
+		}
 		break;
 	default:
 		error("o90_sortArray: Unknown case %d", subOp);
 	}
-	debug(1,"o90_sortArray stub (%d)", subOp);
 }
 
 void ScummEngine_v90he::o90_getObjectData() {
-	// Object releated
+	// Object related
 	byte subOp = fetchScriptByte();
 	subOp -= 32;
 





More information about the Scummvm-git-logs mailing list