aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/intern.h1
-rw-r--r--scumm/object.cpp46
-rw-r--r--scumm/resource.cpp2
-rw-r--r--scumm/resource_v2.cpp2
-rw-r--r--scumm/resource_v3.cpp2
-rw-r--r--scumm/saveload.cpp15
-rw-r--r--scumm/script_v2.cpp52
-rw-r--r--scumm/script_v5.cpp104
-rw-r--r--scumm/script_v6.cpp27
-rw-r--r--scumm/scumm.h1
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();