[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