diff options
| -rw-r--r-- | scumm/intern.h | 1 | ||||
| -rw-r--r-- | scumm/object.cpp | 46 | ||||
| -rw-r--r-- | scumm/resource.cpp | 2 | ||||
| -rw-r--r-- | scumm/resource_v2.cpp | 2 | ||||
| -rw-r--r-- | scumm/resource_v3.cpp | 2 | ||||
| -rw-r--r-- | scumm/saveload.cpp | 15 | ||||
| -rw-r--r-- | scumm/script_v2.cpp | 52 | ||||
| -rw-r--r-- | scumm/script_v5.cpp | 104 | ||||
| -rw-r--r-- | scumm/script_v6.cpp | 27 | ||||
| -rw-r--r-- | scumm/scumm.h | 1 |
10 files changed, 57 insertions, 195 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index 1a2813e564..f0857b0aa2 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -281,7 +281,6 @@ protected: void o2_setActorElevation(); void o2_setBitVar(); void o2_setCameraAt(); - void o2_setObjectName(); void o2_setObjPreposition(); void o2_setOwnerOf(); void o2_setState01(); diff --git a/scumm/object.cpp b/scumm/object.cpp index 1c96e3c5b3..8a305a127b 100644 --- a/scumm/object.cpp +++ b/scumm/object.cpp @@ -892,13 +892,10 @@ const byte *ScummEngine::getObjOrActorName(int obj) { if (obj < _numActors) return derefActor(obj, "getObjOrActorName")->getActorName(); - if (_version >= 6) { - for (i = 0; i < _numNewNames; i++) { - if (_newNames[i] == obj) { - debug(5, "Found new name for object %d at _newNames[%d]", obj, i); - return getResourceAddress(rtObjectName, i); - break; - } + for (i = 0; i < _numNewNames; i++) { + if (_newNames[i] == obj) { + debug(5, "Found new name for object %d at _newNames[%d]", obj, i); + return getResourceAddress(rtObjectName, i); } } @@ -922,6 +919,41 @@ const byte *ScummEngine::getObjOrActorName(int obj) { return findResourceData(MKID('OBNA'), objptr); } +void ScummEngine::setObjectName(int obj) { + int i; + + if (obj < _numActors) + error("Can't set actor %d name with new-name-of", obj); + + const byte *objptr = getOBCDFromObject(obj); + if (_version <= 5 && !objptr) { + // WORKAROUND bug #587553 and possibly other related script bug. + // We do not error out but rather just generate a warning. + debug(2, "Can't find OBCD to rename object %d", obj); + return; + } else if (_version == 6 && !objptr) + error("Can't set name of object %d", obj); + + for (i = 0; i < _numNewNames; i++) { + if (_newNames[i] == obj) { + nukeResource(rtObjectName, i); + _newNames[i] = 0; + break; + } + } + + for (i = 0; i < _numNewNames; i++) { + if (_newNames[i] == 0) { + loadPtrToResource(rtObjectName, i, NULL); + _newNames[i] = obj; + runInventoryScript(0); + return; + } + } + + error("New name of %d overflows name table (max = %d)", obj, _numNewNames); +} + uint32 ScummEngine::getOBCDOffs(int object) const { int i; diff --git a/scumm/resource.cpp b/scumm/resource.cpp index 65cb582e84..4137668e52 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -2101,7 +2101,7 @@ void ScummEngine::readMAXS() { _numLocalObjects = _fileHandle.readUint16LE(); // 200 _numArray = 50; _numVerbs = 100; - _numNewNames = 0; + _numNewNames = 50; _objectRoomTable = NULL; _fileHandle.readUint16LE(); // 50 diff --git a/scumm/resource_v2.cpp b/scumm/resource_v2.cpp index c1ef5a44f5..8026d173ff 100644 --- a/scumm/resource_v2.cpp +++ b/scumm/resource_v2.cpp @@ -187,7 +187,7 @@ void ScummEngine_v2::readMAXS() { _numLocalObjects = 200; // 200 _numArray = 50; _numVerbs = 100; - _numNewNames = 0; + _numNewNames = 50; _objectRoomTable = NULL; _numCharsets = 9; // 9 _numInventory = 80; // 80 diff --git a/scumm/resource_v3.cpp b/scumm/resource_v3.cpp index 4080d129d8..7acff39842 100644 --- a/scumm/resource_v3.cpp +++ b/scumm/resource_v3.cpp @@ -199,7 +199,7 @@ void ScummEngine_v3::readMAXS() { _numLocalObjects = 200; // 200 _numArray = 50; _numVerbs = 100; - _numNewNames = 0; + _numNewNames = 50; _objectRoomTable = NULL; _numCharsets = 9; // 9 _numInventory = 80; // 80 diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index b2e40ff1b1..4171b63eb1 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -706,11 +706,16 @@ void ScummEngine::saveOrLoad(Serializer *s, uint32 savegameVersion) { // Old, fragile resource save/load system. Doesn't save resources // with index 0, and breaks whenever we change the limit on a given // resource type. - for (type = rtFirst; type <= rtLast; type++) - if (res.mode[type] != 1) - for (idx = 1; idx < res.num[type]; idx++) - if (type != rtTemp && type != rtBuffer) - saveLoadResource(s, type, idx); + for (type = rtFirst; type <= rtLast; type++) + if (res.mode[type] != 1 && type != rtTemp && type != rtBuffer) { + // For V1-V5 games, there used to be no object name resources. + // At some point this changed. But since old savegames rely on + // unchanged resource counts, we have to hard code the following check + if (_version < 6 && type == rtObjectName) + continue; + for (idx = 1; idx < res.num[type]; idx++) + saveLoadResource(s, type, idx); + } } s->saveLoadArrayOf(_objectOwnerTable, _numGlobalObjects, sizeof(_objectOwnerTable[0]), sleByte); diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index 661491656d..c3d3d1b398 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -141,7 +141,7 @@ void ScummEngine_v2::setupOpcodes() { OPCODE(o5_actorFollowCamera), OPCODE(o2_actorOps), /* 54 */ - OPCODE(o2_setObjectName), + OPCODE(o5_setObjectName), OPCODE(o2_actorFromPos), OPCODE(o5_getActorMoving), OPCODE(o2_setState02), @@ -301,7 +301,7 @@ void ScummEngine_v2::setupOpcodes() { OPCODE(o5_actorFollowCamera), OPCODE(o2_actorOps), /* D4 */ - OPCODE(o2_setObjectName), + OPCODE(o5_setObjectName), OPCODE(o2_actorFromPos), OPCODE(o5_getActorMoving), OPCODE(o2_setState02), @@ -1484,54 +1484,6 @@ void ScummEngine_v2::o2_pickupObject() { runInventoryScript(1); } -void ScummEngine_v2::o2_setObjectName() { - int obj = getVarOrDirectWord(PARAM_1); - int size = 0; - int a; - int i = 0; - byte *name = NULL; - byte work[256]; - - // Read in new name - do { - a = fetchScriptByte(); - work[i++] = a; - } while (a); - - if (obj < _numActors) - error("Can't set actor %d name with new-name-of", obj); - - // TODO: Would be nice if we used rtObjectName resource for pre-V6 - // games, too. The only problem with that which I can see is that this - // would break savegames. I.e. it would require yet another change to - // the save/load system. - - // FIXME: This is rather nasty code. - // Find the object name in the OBCD resource. - byte *objptr; - objptr = getOBCDFromObject(obj); - if (objptr == NULL) - return; // Silently fail for now - name = objptr + *(objptr + 14); - - while (name[size++]) - ; - - if (i > size) { - warning("New name of object %d too long (old *%s* new *%s*)", obj, name, work); - i = size; - } - - while (i < size) { - work[i - 1] = '@'; - i++; - } - work[i - 1] = 0; - - memcpy(name, work, i); - runInventoryScript(0); -} - void ScummEngine_v2::o2_cursorCommand() { // TODO: Define the magic numbers uint16 cmd = getVarOrDirectWord(PARAM_1); byte state = cmd >> 8; diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp index 263e23539c..146a16cad0 100644 --- a/scumm/script_v5.cpp +++ b/scumm/script_v5.cpp @@ -2055,109 +2055,7 @@ void ScummEngine_v5::o5_setCameraAt() { void ScummEngine_v5::o5_setObjectName() { int obj = getVarOrDirectWord(PARAM_1); - int size; - int a; - int i = 0; - byte *name = NULL; - unsigned char work[256]; - - // Read in new name - while ((a = fetchScriptByte()) != 0) { - work[i++] = a; - if (a == 0xFF) { - work[i++] = fetchScriptByte(); - work[i++] = fetchScriptByte(); - work[i++] = fetchScriptByte(); - } - } - work[i++] = 0; - - if (obj < _numActors) - error("Can't set actor %d name with new-name-of", obj); - - // TODO: Would be nice if we used rtObjectName resource for pre-V6 - // games, too. The only problem with that which I can see is that this - // would break savegames. I.e. it would require yet another change to - // the save/load system. - - byte *objptr; - objptr = getOBCDFromObject(obj); - if (objptr == NULL) { - // WORKAROUND bug #587553: This is an odd one and looks more like - // an actual bug in the original script. Usually we would error - warning("Can't find OBCD to rename object %d to %s", obj, work); - return; - } - - if (_features & GF_SMALL_HEADER) { - byte offset = 0; - - if (_features & GF_OLD_BUNDLE) - offset = *(objptr + 16); - else - offset = *(objptr + 18); - - size = READ_LE_UINT16(objptr) - offset; - name = objptr + offset; - } else { - name = 0; -#if 0 - name = findResourceData(MKID('OBNA'), objptr); -#else - // FIXME: we can't use findResourceData anymore, because it returns const - // data, while this function *must* return a non-const pointer. That is so - // because in o2_setObjectName / o5_setObjectName we directly modify this - // data. Now, we could add a non-const version of findResourceData, too - // (C++ makes that easy); but this here is really the *only* place in all - // of ScummVM where it wold be needed! That seems kind of a waste... - // - // So for now, I duplicate some code from findResourceData / findResource - // here. However, a much nicer solution might be (with stress on "might") - // to use the same technique as in V6 games: that is, use a separate - // resource for changed names. That would be the cleanest solution, but - // might proof to be infeasible, as it might lead to unforseen regressions. - - const uint32 tag = MKID('OBNA'); - byte *searchin = objptr; - uint32 curpos, totalsize; - - assert(searchin); - - searchin += 4; - totalsize = READ_BE_UINT32(searchin); - curpos = 8; - searchin += 4; - - while (curpos < totalsize) { - if (READ_UINT32(searchin) == tag) { - name = searchin + _resourceHeaderSize; - break; - } - - size = READ_BE_UINT32(searchin + 4); - if ((int32)size <= 0) { - error("(OBNA) Not found... illegal block len %d", size); - } - - curpos += size; - searchin += size; - } -#endif - size = getResourceDataSize(name); - } - - if (name == 0) - return; // Silently bail out - - - if (i > size) { - warning("New name of object %d too long: old 's' (%d), new '%s' (%d))", - obj, name, i, work, size); - i = size; - } - - memcpy(name, work, i); - runInventoryScript(0); + setObjectName(obj); } void ScummEngine_v5::o5_setOwnerOf() { diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index 81c1940e1a..30983a573c 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -1427,32 +1427,7 @@ void ScummEngine_v6::o6_endOverride() { void ScummEngine_v6::o6_setObjectName() { int obj = pop(); - int i; - - if (obj < _numActors) - error("Can't set actor %d name with new-name-of", obj); - - if (_version < 7 && !getOBCDFromObject(obj)) - error("Can't set name of object %d", obj); - - for (i = 0; i < _numNewNames; i++) { - if (_newNames[i] == obj) { - nukeResource(rtObjectName, i); - _newNames[i] = 0; - break; - } - } - - for (i = 0; i < _numNewNames; i++) { - if (_newNames[i] == 0) { - loadPtrToResource(rtObjectName, i, NULL); - _newNames[i] = obj; - runInventoryScript(0); - return; - } - } - - error("New name of %d overflows name table (max = %d)", obj, _numNewNames); + setObjectName(obj); } void ScummEngine_v6::o6_isSoundRunning() { diff --git a/scumm/scumm.h b/scumm/scumm.h index 3f77f509b9..7db438f49e 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -700,6 +700,7 @@ public: protected: int getObjActToObjActDist(int a, int b); // Not sure how to handle const byte *getObjOrActorName(int obj); // these three.. + void setObjectName(int obj); void addObjectToDrawQue(int object); void clearDrawObjectQueue(); |
