[Scummvm-cvs-logs] CVS: scummvm/scumm resource.h,1.9,1.9.2.1 script_v6.cpp,1.293.2.21,1.293.2.22 script_v6he.cpp,2.15.2.7,2.15.2.8 script_v8.cpp,2.229.2.8,2.229.2.9
Max Horn
fingolfin at users.sourceforge.net
Fri Aug 13 02:11:01 CEST 2004
Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17290
Modified Files:
Tag: branch-0-6-0
resource.h script_v6.cpp script_v6he.cpp script_v8.cpp
Log Message:
Backported V6-V8 array fixes
Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.h,v
retrieving revision 1.9
retrieving revision 1.9.2.1
diff -u -d -r1.9 -r1.9.2.1
--- resource.h 19 Jan 2004 20:27:31 -0000 1.9
+++ resource.h 13 Aug 2004 09:10:19 -0000 1.9.2.1
@@ -31,6 +31,14 @@
uint32 tag, size;
} GCC_PACK;
+enum ArrayType {
+ kBitArray = 1,
+ kNibbleArray = 2,
+ kByteArray = 3,
+ kStringArray = 4,
+ kIntArray = 5
+};
+
struct ArrayHeader {
int16 dim1;
int16 type;
Index: script_v6.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6.cpp,v
retrieving revision 1.293.2.21
retrieving revision 1.293.2.22
diff -u -d -r1.293.2.21 -r1.293.2.22
--- script_v6.cpp 13 Aug 2004 02:02:04 -0000 1.293.2.21
+++ script_v6.cpp 13 Aug 2004 09:10:19 -0000 1.293.2.22
@@ -401,12 +401,21 @@
int size;
ArrayHeader *ah;
- if (!(_features & GF_HUMONGOUS)) {
- if (type != rtSound)
- type = rtInventory;
+ assert(0 <= type && type <= 5);
+
+
+ if (_features & GF_HUMONGOUS) {
+ if (type == kBitArray || type == kNibbleArray)
+ type = kByteArray;
} else {
- if (type == rtScript || type == rtRoom)
- type = rtCostume;
+ // NOTE: The following code turns all arrays except string arrays into
+ // integer arrays. There seems to be no reason for this, and it wastes
+ // space. However, we can't just remove this either, as that would
+ // break savegame compatibility. So do not touch this unless you are
+ // also adding code which updated old savegames, too. And of course
+ // readArray() and writeArray() would have to be updated, too...
+ if (type != kStringArray)
+ type = kIntArray;
}
nukeArray(array);
@@ -421,7 +430,7 @@
error("Can't define bit variable as array pointer");
}
- size = (type == 5) ? 32 : 8;
+ size = (type == kIntArray) ? 4 : 1;
} else {
if (array & 0x4000) {
}
@@ -430,14 +439,13 @@
error("Can't define bit variable as array pointer");
}
- size = (type == 5) ? 16 : 8;
+ size = (type == kIntArray) ? 2 : 1;
}
writeVar(array, id);
size *= dim2 + 1;
size *= dim1 + 1;
- size >>= 3;
ah = (ArrayHeader *)createResource(rtString, id, size + sizeof(ArrayHeader));
@@ -471,19 +479,21 @@
return -1;
}
+#define SWAP16(x) x = SWAP_BYTES_16(x)
+
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
+ // endianness, instead of a fixed endianness. 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);
+ if ((FROM_LE_16(ah->dim1) & 0xF000) || (FROM_LE_16(ah->dim2) & 0xF000) || (FROM_LE_16(ah->type) & 0xFF00)) {
+ SWAP16(ah->dim1);
+ SWAP16(ah->dim2);
+ SWAP16(ah->type);
}
return ah;
@@ -496,21 +506,30 @@
error("readArray: invalid array %d (%d)", array, readVar(array));
}
- base += idx * FROM_LE_16(ah->dim1);
+ // WORKAROUND bug #645711. This is clearly a script bug, as this script
+ // excerpt shows nicely:
+ // ...
+ // [03A7] (5D) if (isAnyOf(array-447[localvar13][localvar14],[0,4])) {
+ // [03BD] (5D) if ((localvar13 != -1) && (localvar14 != -1)) {
+ // [03CF] (B6) printDebug.begin()
+ // ...
+ if (_gameId == GID_FT && array == 447 && _currentRoom == 95 && vm.slot[_currentScript].number == 2010 && idx == -1 && base == -1) {
+ return 0;
+ }
- // 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 < FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2));
+ const int offset = base + idx * FROM_LE_16(ah->dim1);
- if (FROM_LE_16(ah->type) == 4 || (_features & GF_HUMONGOUS && FROM_LE_16(ah->type) == rtCostume)) {
- return ah->data[base];
+ if (offset < 0 || offset >= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2)) {
+ error("readArray: array %d out of bounds: [%d,%d] exceeds [%d,%d]",
+ array, base, idx, FROM_LE_16(ah->dim1), FROM_LE_16(ah->dim2));
+ }
+
+ if (FROM_LE_16(ah->type) != kIntArray) {
+ return ah->data[offset];
} else if (_version == 8) {
- return (int32)READ_LE_UINT32(ah->data + base * 4);
+ return (int32)READ_LE_UINT32(ah->data + offset * 4);
} else {
- return (int16)READ_LE_UINT16(ah->data + base * 2);
+ return (int16)READ_LE_UINT16(ah->data + offset * 2);
}
}
@@ -518,26 +537,20 @@
ArrayHeader *ah = getArray(array);
if (!ah)
return;
- base += idx * FROM_LE_16(ah->dim1);
- assert(base >= 0 && base < FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2));
+ const int offset = base + idx * FROM_LE_16(ah->dim1);
- if (FROM_LE_16(ah->type) == rtSound || (_features & GF_HUMONGOUS && FROM_LE_16(ah->type) == rtCostume)) {
- ah->data[base] = value;
+ if (offset < 0 || offset >= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2)) {
+ error("writeArray: array %d out of bounds: [%d,%d] exceeds [%d,%d]",
+ array, base, idx, FROM_LE_16(ah->dim1), FROM_LE_16(ah->dim2));
+ }
+
+ if (FROM_LE_16(ah->type) != kIntArray) {
+ ah->data[offset] = value;
} else if (_version == 8) {
-#if defined(SCUMM_NEED_ALIGNMENT)
- uint32 tmp = TO_LE_32(value);
- memcpy(&ah->data[base*4], &tmp, 4);
-#else
- ((uint32 *)ah->data)[base] = TO_LE_32(value);
-#endif
+ WRITE_LE_UINT32(ah->data + offset * 4, value);
} else {
-#if defined(SCUMM_NEED_ALIGNMENT)
- uint16 tmp = TO_LE_16(value);
- memcpy(&ah->data[base*2], &tmp, 2);
-#else
- ((uint16 *)ah->data)[base] = TO_LE_16(value);
-#endif
+ WRITE_LE_UINT16(ah->data + offset * 2, value);
}
}
@@ -549,10 +562,7 @@
a = _fileHandle.readUint16LE();
b = _fileHandle.readUint16LE();
c = _fileHandle.readUint16LE();
- if (c == 1)
- defineArray(num, 1, a, b);
- else
- defineArray(num, 5, a, b);
+ defineArray(num, c, a, b);
}
}
@@ -2044,7 +2054,7 @@
case 205: // SO_ASSIGN_STRING
b = pop();
len = resStrLen(_scriptPointer);
- ah = defineArray(array, 4, 0, len + 1);
+ ah = defineArray(array, kStringArray, 0, len + 1);
copyScriptString(ah->data + b);
break;
case 208: // SO_ASSIGN_INT_LIST
@@ -2052,7 +2062,7 @@
c = pop();
d = readVar(array);
if (d == 0) {
- defineArray(array, 5, 0, b + c);
+ defineArray(array, kIntArray, 0, b + c);
}
while (c--) {
writeArray(array, 0, b + c, pop());
@@ -2335,19 +2345,19 @@
switch (fetchScriptByte()) {
case 199: // SO_INT_ARRAY
- data = 5;
+ data = kIntArray;
break;
case 200: // SO_BIT_ARRAY
- data = 1;
+ data = kBitArray;
break;
case 201: // SO_NIBBLE_ARRAY
- data = 2;
+ data = kNibbleArray;
break;
case 202: // SO_BYTE_ARRAY
- data = 3;
+ data = kByteArray;
break;
case 203: // SO_STRING_ARRAY
- data = 4;
+ data = kStringArray;
break;
case 204: // SO_UNDIM_ARRAY
nukeArray(fetchScriptWord());
@@ -2367,19 +2377,19 @@
int a, b, data;
switch (fetchScriptByte()) {
case 199: // SO_INT_ARRAY
- data = 5;
+ data = kIntArray;
break;
case 200: // SO_BIT_ARRAY
- data = 1;
+ data = kBitArray;
break;
case 201: // SO_NIBBLE_ARRAY
- data = 2;
+ data = kNibbleArray;
break;
case 202: // SO_BYTE_ARRAY
- data = 3;
+ data = kByteArray;
break;
case 203: // SO_STRING_ARRAY
- data = 4;
+ data = kStringArray;
break;
default:
error("o6_dim2dimArray: default case");
@@ -2886,7 +2896,7 @@
if (state == 0)
state = 255;
- debug(6, "o6_stampObject: (%d at (%d,%d) scale %d)", object, x, y, state);
+ //debug(6, "o6_stampObject: (%d at (%d,%d) scale %d)", object, x, y, state);
Actor *a = derefActor(object, "o6_stampObject");
a->scalex = state;
a->scaley = state;
@@ -2912,7 +2922,7 @@
putState(object, state);
drawObject(objnum, 0);
- debug(6, "o6_stampObject: (%d at (%d,%d) state %d)", object, x, y, state);
+ //debug(6, "o6_stampObject: (%d at (%d,%d) state %d)", object, x, y, state);
}
void ScummEngine_v6::o6_stopTalking() {
@@ -2926,7 +2936,7 @@
if (a != _currentRoom)
warning("o6_findAllObjects: current room is not %d", a);
writeVar(0, 0);
- defineArray(0, 5, 0, _numLocalObjects + 1);
+ defineArray(0, kIntArray, 0, _numLocalObjects + 1);
writeArray(0, 0, 0, _numLocalObjects);
while (i < _numLocalObjects) {
@@ -2970,7 +2980,7 @@
int value = fetchScriptWord();
if (readVar(value) == 0) {
- defineArray(value, 5, 0, num + 1);
+ defineArray(value, kIntArray, 0, num + 1);
if (num > 0) {
int16 counter = 0;
do {
Index: script_v6he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6he.cpp,v
retrieving revision 2.15.2.7
retrieving revision 2.15.2.8
diff -u -d -r2.15.2.7 -r2.15.2.8
--- script_v6he.cpp 18 Jul 2004 22:15:52 -0000 2.15.2.7
+++ script_v6he.cpp 13 Aug 2004 09:10:20 -0000 2.15.2.8
@@ -965,7 +965,7 @@
// Fatty Bear's Birthday Surprise
// XXX gdi_virtScreen = 0;
writeVar(0, 0);
- defineArray(0, rtCostume, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
+ defineArray(0, kByteArray, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
retval = readVar(0);
ah = (ArrayHeader *)getResourceAddress(rtString, retval);
virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
@@ -1177,7 +1177,7 @@
writeVar(0, 0);
- ArrayHeader *ah = defineArray(0, rtCostume, 0, size);
+ ArrayHeader *ah = defineArray(0, kByteArray, 0, size);
_hFileTable[slot].read(ah->data, size);
return readVar(0);
@@ -1320,10 +1320,10 @@
subcode = fetchScriptByte();
switch (subcode) {
case 199:
- redimArray(fetchScriptWord(), newX, newY, rtInventory);
+ redimArray(fetchScriptWord(), newX, newY, kIntArray);
break;
case 202:
- redimArray(fetchScriptWord(), newX, newY, rtCostume);
+ redimArray(fetchScriptWord(), newX, newY, kByteArray);
break;
default:
break;
@@ -1332,7 +1332,7 @@
void ScummEngine_v6he::redimArray(int arrayId, int newX, int newY, int type) {
// Used in mini game at Cosmic Dust Diner in puttmoon
- int var_2, var_4, ax, cx;
+ int newSize, oldSize;
if (readVar(arrayId) == 0)
error("redimArray: Reference to zeroed array pointer");
@@ -1342,20 +1342,13 @@
if (!ah)
error("redimArray: Invalid array (%d) reference", readVar(arrayId));
- if (type == rtInventory)
- var_2 = 2;
- else // rtCostume
- var_2 = 1;
-
- if (FROM_LE_16(ah->type) == rtInventory)
- var_4 = 2;
- else
- var_4 = 1;
+ newSize = (type == kIntArray) ? 2 : 1;
+ oldSize = (ah->type == kIntArray) ? 2 : 1;
- cx = var_2 * (newX + 1) * (newY + 1);
- ax = var_4 * FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
+ newSize *= (newX + 1) * (newY + 1);
+ oldSize *= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
- if (ax != cx)
+ if (newSize != oldSize)
error("redimArray: array %d redim mismatch", readVar(arrayId));
ah->type = TO_LE_16(type);
Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.229.2.8
retrieving revision 2.229.2.9
diff -u -d -r2.229.2.8 -r2.229.2.9
--- script_v8.cpp 1 Aug 2004 01:23:53 -0000 2.229.2.8
+++ script_v8.cpp 13 Aug 2004 09:10:20 -0000 2.229.2.9
@@ -553,9 +553,9 @@
b = _fileHandle.readUint32LE();
if (b != 0)
- defineArray(num, 5, b, a);
+ defineArray(num, kIntArray, b, a);
else
- defineArray(num, 5, a, b);
+ defineArray(num, kIntArray, a, b);
}
}
@@ -623,10 +623,10 @@
switch (subOp) {
case 0x0A: // SO_ARRAY_SCUMMVAR
- defineArray(array, 5, 0, pop());
+ defineArray(array, kIntArray, 0, pop());
break;
case 0x0B: // SO_ARRAY_STRING
- defineArray(array, 4, 0, pop());
+ defineArray(array, kStringArray, 0, pop());
break;
case 0x0C: // SO_ARRAY_UNDIM
nukeArray(array);
@@ -644,12 +644,12 @@
case 0x0A: // SO_ARRAY_SCUMMVAR
b = pop();
a = pop();
- defineArray(array, 5, a, b);
+ defineArray(array, kIntArray, a, b);
break;
case 0x0B: // SO_ARRAY_STRING
b = pop();
a = pop();
- defineArray(array, 4, a, b);
+ defineArray(array, kStringArray, a, b);
break;
case 0x0C: // SO_ARRAY_UNDIM
nukeArray(array);
@@ -670,7 +670,7 @@
case 0x14: // SO_ASSIGN_STRING
b = pop();
len = resStrLen(_scriptPointer);
- ah = defineArray(array, 4, 0, len + 1);
+ ah = defineArray(array, kStringArray, 0, len + 1);
copyScriptString(ah->data + b);
break;
case 0x15: // SO_ASSIGN_SCUMMVAR_LIST
@@ -678,7 +678,7 @@
len = getStackList(list, ARRAYSIZE(list));
d = readVar(array);
if (d == 0) {
- defineArray(array, 5, 0, b + len);
+ defineArray(array, kIntArray, 0, b + len);
}
while (--len >= 0) {
writeArray(array, 0, b + len, list[len]);
More information about the Scummvm-git-logs
mailing list