[Scummvm-cvs-logs] CVS: scummvm/scumm intern.h,2.127,2.128 resource.cpp,1.183,1.184 resource.h,1.8,1.9 script.cpp,1.147,1.148 script_v6.cpp,1.279,1.280 script_v8.cpp,2.224,2.225 scumm.h,1.365,1.366

Max Horn fingolfin at users.sourceforge.net
Mon Jan 19 12:28:01 CET 2004


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv13762

Modified Files:
	intern.h resource.cpp resource.h script.cpp script_v6.cpp 
	script_v8.cpp scumm.h 
Log Message:
fix endian bug when dealing with ArrayHeader's; added a hack to permit save games broken due to this to still work; moved the whole 'Array' stuff into ScummEngine_v6

Index: intern.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/intern.h,v
retrieving revision 2.127
retrieving revision 2.128
diff -u -d -r2.127 -r2.128
--- intern.h	19 Jan 2004 19:47:47 -0000	2.127
+++ intern.h	19 Jan 2004 20:27:18 -0000	2.128
@@ -29,6 +29,7 @@
 namespace Scumm {
 
 class NutRenderer; // V8 Font Renderer
+struct ArrayHeader;
 
 class ScummEngine_v5 : public ScummEngine {
 protected:
@@ -348,11 +349,20 @@
 
 	virtual void setupScummVars();
 	virtual void decodeParseString(int a, int b);
+	virtual void readArrayFromIndexFile();
 
 	virtual void palManipulateInit(int resID, int start, int end, int time);
 
 	int getStackList(int *args, uint maxnum);
 	int popRoomAndObj(int *room);
+
+	ArrayHeader *getArray(int array);
+	ArrayHeader *defineArray(int array, int type, int dim2, int dim1);
+	int findFreeArrayId();
+	void nukeArray(int array);
+	int readArray(int array, int index, int base);
+	void writeArray(int array, int index, int base, int value);
+
 	void shuffleArray(int num, int minIdx, int maxIdx);
 	void unknownEA_func(int a, int b, int c, int d, int e);
 	int readFileToArray(int slot, int32 size);
@@ -575,6 +585,7 @@
 
 	virtual void setupScummVars();
 	virtual void decodeParseString(int m, int n);
+	virtual void readArrayFromIndexFile();
 
 	virtual uint fetchScriptWord();
 	virtual int fetchScriptWordSigned();

Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.cpp,v
retrieving revision 1.183
retrieving revision 1.184
diff -u -d -r1.183 -r1.184
--- resource.cpp	10 Jan 2004 11:01:46 -0000	1.183
+++ resource.cpp	19 Jan 2004 20:27:19 -0000	1.184
@@ -437,36 +437,7 @@
 }
 
 void ScummEngine::readArrayFromIndexFile() {
-	int num;
-	int a, b, c;
-
-	if (_version == 8) {
-		while ((num = _fileHandle.readUint32LE()) != 0) {
-			a = _fileHandle.readUint32LE();
-			b = _fileHandle.readUint32LE();
-			
-			// FIXME - seems the COMI scripts have a bug related to array 436.
-			// and visible in script 2015, room 20. Basically, the dimensions
-			// are swapped in the definition of the array, but its obvious
-			// that this must be a script bug simply by looking at the defintions
-			// of other arrays and how they are used.
-			// Talk to fingolfin if you have questions about this :-)
-			if (num == 436)
-				defineArray(num, 5, b, a);
-			else
-				defineArray(num, 5, a, b);
-		}
-	} else {
-		while ((num = _fileHandle.readUint16LE()) != 0) {
-			a = _fileHandle.readUint16LE();
-			b = _fileHandle.readUint16LE();
-			c = _fileHandle.readUint16LE();
-			if (c == 1)
-				defineArray(num, 1, a, b);
-			else
-				defineArray(num, 5, a, b);
-		}
-	}
+	error("readArrayFromIndexFile() not supported in pre-V6 games");
 }
 
 void ScummEngine::readResTypeList(int id, uint32 tag, const char *name) {

Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- resource.h	6 Jan 2004 12:45:30 -0000	1.8
+++ resource.h	19 Jan 2004 20:27:31 -0000	1.9
@@ -31,6 +31,13 @@
 	uint32 tag, size;
 } GCC_PACK;
 
+struct ArrayHeader {
+	int16 dim1;
+	int16 type;
+	int16 dim2;
+	byte data[1];
+} GCC_PACK;
+
 #if !defined(__GNUC__)
 	#pragma END_PACK_STRUCTS
 #endif
@@ -52,15 +59,6 @@
 };
 
 
-#define ARRAY_HDR_SIZE 6
-struct ArrayHeader {
-	int16 dim1_size;
-	int16 type;
-	int16 dim2_size;
-	byte data[1];
-};
-
-
 const byte *findResource(uint32 tag, const byte *searchin);
 const byte *findResourceSmall(uint32 tag, const byte *searchin);
 

Index: script.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script.cpp,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -d -r1.147 -r1.148
--- script.cpp	15 Jan 2004 06:25:57 -0000	1.147
+++ script.cpp	19 Jan 2004 20:27:31 -0000	1.148
@@ -980,76 +980,6 @@
 	return false;
 }
 
-int ScummEngine::defineArray(int array, int type, int dim2, int dim1) {
-	int id;
-	int size;
-	ArrayHeader *ah;
-
-	if (type != 4)
-		type = 5;
-
-	nukeArray(array);
-
-	id = getArrayId();
-
-	if (_version == 8) {
-		if (array & 0x40000000) {
-		}
-	
-		if (array & 0x80000000) {
-			error("Can't define bit variable as array pointer");
-		}
-
-		size = (type == 5) ? 32 : 8;
-	} else {
-		if (array & 0x4000) {
-		}
-	
-		if (array & 0x8000) {
-			error("Can't define bit variable as array pointer");
-		}
-
-		size = (type == 5) ? 16 : 8;
-	}
-
-	writeVar(array, id);
-
-	size *= dim2 + 1;
-	size *= dim1 + 1;
-	size >>= 3;
-
-	ah = (ArrayHeader *)createResource(rtString, id, size + sizeof(ArrayHeader));
-
-	ah->type = type;
-	ah->dim1_size = dim1 + 1;
-	ah->dim2_size = dim2 + 1;
-
-	return id;
-}
-
-void ScummEngine::nukeArray(int a) {
-	int data;
-
-	data = readVar(a);
-
-	if (data)
-		nukeResource(rtString, data);
-
-	writeVar(a, 0);
-}
-
-int ScummEngine::getArrayId() {
-	byte **addr = _baseArrays;
-	int i;
-
-	for (i = 1; i < _numArray; i++) {
-		if (!addr[i])
-			return i;
-	}
-	error("Out of array pointers, %d max", _numArray);
-	return -1;
-}
-
 void ScummEngine::copyScriptString(byte *dst) {
 	int len = resStrLen(_scriptPointer) + 1;
 	while (len--)

Index: script_v6.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6.cpp,v
retrieving revision 1.279
retrieving revision 1.280
diff -u -d -r1.279 -r1.280
--- script_v6.cpp	19 Jan 2004 20:23:27 -0000	1.279
+++ script_v6.cpp	19 Jan 2004 20:27:31 -0000	1.280
@@ -396,24 +396,111 @@
 	return obj;
 }
 
+ArrayHeader *ScummEngine_v6::defineArray(int array, int type, int dim2, int dim1) {
+	int id;
+	int size;
+	ArrayHeader *ah;
 
-int ScummEngine::readArray(int array, int idx, int base) {
+	if (type != 4)
+		type = 5;
+
+	nukeArray(array);
+
+	id = findFreeArrayId();
+
+	if (_version == 8) {
+		if (array & 0x40000000) {
+		}
+	
+		if (array & 0x80000000) {
+			error("Can't define bit variable as array pointer");
+		}
+
+		size = (type == 5) ? 32 : 8;
+	} else {
+		if (array & 0x4000) {
+		}
+	
+		if (array & 0x8000) {
+			error("Can't define bit variable as array pointer");
+		}
+
+		size = (type == 5) ? 16 : 8;
+	}
+
+	writeVar(array, id);
+
+	size *= dim2 + 1;
+	size *= dim1 + 1;
+	size >>= 3;
+
+	ah = (ArrayHeader *)createResource(rtString, id, size + sizeof(ArrayHeader));
+
+	ah->type = TO_LE_16(type);
+	ah->dim1 = TO_LE_16(dim1 + 1);
+	ah->dim2 = TO_LE_16(dim2 + 1);
+
+	return ah;
+}
+
+void ScummEngine_v6::nukeArray(int a) {
+	int data;
+
+	data = readVar(a);
+
+	if (data)
+		nukeResource(rtString, data);
+
+	writeVar(a, 0);
+}
+
+int ScummEngine_v6::findFreeArrayId() {
+	byte **addr = _baseArrays;
+	int i;
+
+	for (i = 1; i < _numArray; i++) {
+		if (!addr[i])
+			return i;
+	}
+	error("Out of array pointers, %d max", _numArray);
+	return -1;
+}
+
+ArrayHeader *ScummEngine_v6::getArray(int array) {
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+	if (!ah)
+		return 0;
+	
+	// Workaround for a long standing bug where we save array headers in native
+	// endianess, instead of a fixed endianess. We try to detect savegames
+	// which were created on a big endian system and convert them to little
+	// endian.
+	if ((ah->dim1 & 0xF000) || (ah->dim2 & 0xF000) || (ah->type & 0xFF00)) {
+		SWAP_BYTES_16(ah->dim1);
+		SWAP_BYTES_16(ah->dim2);
+		SWAP_BYTES_16(ah->type);
+	}
+	
+	return ah;
+}
+
+int ScummEngine_v6::readArray(int array, int idx, int base) {
+	ArrayHeader *ah = getArray(array);
 
 	if (ah == NULL || ah->data == NULL) {
 		error("readArray: invalid array %d (%d)", array, readVar(array));
 	}
 
-	base += idx * ah->dim1_size;
+	base += idx * FROM_LE_16(ah->dim1);
 
 	// FIXME: comment this for the time being as it was causing ft to crash
 	// in the minefeild
 	// FIX THE FIXME: fixing an assert by commenting out is bad. It's evil.
 	// It's wrong. Find the proper cause, or at least, silently return
 	// from the function, but don't just go on overwriting memory!
-	assert(base >= 0 && base < ah->dim1_size * ah->dim2_size);
+	assert(base >= 0 && base < FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2));
 
-	if (ah->type == 4) {
+	if (FROM_LE_16(ah->type) == 4) {
 		return ah->data[base];
 	} else if (_version == 8) {
 		return (int32)READ_LE_UINT32(ah->data + base * 4);
@@ -422,15 +509,15 @@
 	}
 }
 
-void ScummEngine::writeArray(int array, int idx, int base, int value) {
-	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+void ScummEngine_v6::writeArray(int array, int idx, int base, int value) {
+	ArrayHeader *ah = getArray(array);
 	if (!ah)
 		return;
-	base += idx * ah->dim1_size;
+	base += idx * FROM_LE_16(ah->dim1);
 
-	assert(base >= 0 && base < ah->dim1_size * ah->dim2_size);
+	assert(base >= 0 && base < FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2));
 
-	if (ah->type == 4) {
+	if (FROM_LE_16(ah->type) == 4) {
 		ah->data[base] = value;
 	} else if (_version == 8) {
 #if defined(SCUMM_NEED_ALIGNMENT)
@@ -449,6 +536,21 @@
 	}
 }
 
+void ScummEngine_v6::readArrayFromIndexFile() {
+	int num;
+	int a, b, c;
+
+	while ((num = _fileHandle.readUint16LE()) != 0) {
+		a = _fileHandle.readUint16LE();
+		b = _fileHandle.readUint16LE();
+		c = _fileHandle.readUint16LE();
+		if (c == 1)
+			defineArray(num, 1, a, b);
+		else
+			defineArray(num, 5, a, b);
+	}
+}
+
 int ScummEngine_v6::getStackList(int *args, uint maxnum) {
 	uint num, i;
 
@@ -2024,8 +2126,7 @@
 	case 205:		// SO_ASSIGN_STRING
 		b = pop();
 		len = resStrLen(_scriptPointer);
-		c = defineArray(array, 4, 0, len + 1);
-		ah = (ArrayHeader *)getResourceAddress(rtString, c);
+		ah = defineArray(array, 4, 0, len + 1);
 		copyScriptString(ah->data + b);
 		break;
 	case 208:		// SO_ASSIGN_INT_LIST

Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.224
retrieving revision 2.225
diff -u -d -r2.224 -r2.225
--- script_v8.cpp	16 Jan 2004 08:34:42 -0000	2.224
+++ script_v8.cpp	19 Jan 2004 20:27:31 -0000	2.225
@@ -535,6 +535,27 @@
 	}
 }
 
+void ScummEngine_v8::readArrayFromIndexFile() {
+	int num;
+	int a, b;
+
+	while ((num = _fileHandle.readUint32LE()) != 0) {
+		a = _fileHandle.readUint32LE();
+		b = _fileHandle.readUint32LE();
+		
+		// FIXME - seems the COMI scripts have a bug related to array 436.
+		// and visible in script 2015, room 20. Basically, the dimensions
+		// are swapped in the definition of the array, but its obvious
+		// that this must be a script bug simply by looking at the defintions
+		// of other arrays and how they are used.
+		// Talk to fingolfin if you have questions about this :-)
+		if (num == 436)
+			defineArray(num, 5, b, a);
+		else
+			defineArray(num, 5, a, b);
+	}
+}
+
 void ScummEngine_v8::o8_mod() {
 	int a = pop();
 	push(pop() % a);
@@ -646,8 +667,7 @@
 	case 0x14:		// SO_ASSIGN_STRING
 		b = pop();
 		len = resStrLen(_scriptPointer);
-		c = defineArray(array, 4, 0, len + 1);
-		ah = (ArrayHeader *)getResourceAddress(rtString, c);
+		ah = defineArray(array, 4, 0, len + 1);
 		copyScriptString(ah->data + b);
 		break;
 	case 0x15:		// SO_ASSIGN_SCUMMVAR_LIST

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.365
retrieving revision 1.366
diff -u -d -r1.365 -r1.366
--- scumm.h	19 Jan 2004 20:23:27 -0000	1.365
+++ scumm.h	19 Jan 2004 20:27:31 -0000	1.366
@@ -635,7 +635,7 @@
 	void loadRoomObjectsSmall();
 	void loadRoomObjectsOldBundle();
 
-	void readArrayFromIndexFile();
+	virtual void readArrayFromIndexFile();
 	virtual void readMAXS();
 	virtual void readIndexFile();
 	virtual void loadCharset(int i);
@@ -648,12 +648,6 @@
 	void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
 
 protected:
-	int getArrayId();
-	void nukeArray(int a);
-	int defineArray(int a, int b, int c, int d);
-	int readArray(int array, int index, int base);
-	void writeArray(int array, int index, int base, int value);
-
 	void resourceStats();
 	void expireResources(uint32 size);
 	void freeResources();





More information about the Scummvm-git-logs mailing list