aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorTobias Gunkel2012-01-22 22:58:10 +0100
committerTobias Gunkel2012-02-11 08:29:13 +0100
commit96f8fc6ca9889d30db11b854c95ffd65bb88034d (patch)
treee8c765f1f68123433f6f36063b7e4e2479c83d58 /engines/scumm
parentfd4a3501ede75d87c06980b5ac563402da834f25 (diff)
downloadscummvm-rg350-96f8fc6ca9889d30db11b854c95ffd65bb88034d.tar.gz
scummvm-rg350-96f8fc6ca9889d30db11b854c95ffd65bb88034d.tar.bz2
scummvm-rg350-96f8fc6ca9889d30db11b854c95ffd65bb88034d.zip
SCUMM: Fix actor ID handling in v0
Some object functions allow actor IDs and object IDs as parameters. They are easily distinguishable in engines > 0 as actor IDs are < _numActors and object IDs are bigger. In v0 this is not the case as there are objects with IDs like 3 and 5 (e.g. the hamster). So object ID handling was unified for v0 and the other engines by introducing objIsActor(), objToActor() and ActorToObj().
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/debugger.cpp4
-rw-r--r--engines/scumm/object.cpp67
-rw-r--r--engines/scumm/script_v0.cpp21
-rw-r--r--engines/scumm/script_v2.cpp4
-rw-r--r--engines/scumm/script_v5.cpp8
-rw-r--r--engines/scumm/scumm.h3
-rw-r--r--engines/scumm/scumm_v0.h2
7 files changed, 69 insertions, 40 deletions
diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp
index 5d1396633f..edcf2e6fea 100644
--- a/engines/scumm/debugger.cpp
+++ b/engines/scumm/debugger.cpp
@@ -382,8 +382,8 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) {
DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume);
}
} else if (!strcmp(argv[2], "name")) {
- int actor = (_vm->_game.version != 0 ? actnum : OBJECT_V0(actnum, kObjectV0TypeActor));
- DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actor));
+ DebugPrintf("Name of actor %d: %s\n", actnum,
+ _vm->getObjOrActorName(_vm->actorToObj(actnum)));
} else if (!strcmp(argv[2], "condmask")) {
if (argc > 3) {
a->_heCondMask = value;
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index bf871d7fa5..4ef8707714 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -357,8 +357,8 @@ int ScummEngine::whereIsObject(int object) const {
int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
Actor *act;
- if (object < _numActors) {
- act = derefActorSafe(object, "getObjectOrActorXY");
+ if (objIsActor(object)) {
+ act = derefActorSafe(objToActor(object), "getObjectOrActorXY");
if (act && act->isInCurrentRoom()) {
x = act->getRealPos().x;
y = act->getRealPos().y;
@@ -371,7 +371,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
case WIO_NOT_FOUND:
return -1;
case WIO_INVENTORY:
- if (_objectOwnerTable[object] < _numActors) {
+ if (objIsActor(_objectOwnerTable[object])) {
act = derefActor(_objectOwnerTable[object], "getObjectOrActorXY(2)");
if (act && act->isInCurrentRoom()) {
x = act->getRealPos().x;
@@ -463,11 +463,11 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
Actor *acta = NULL;
Actor *actb = NULL;
- if (a < _numActors)
- acta = derefActorSafe(a, "getObjActToObjActDist");
+ if (objIsActor(a))
+ acta = derefActorSafe(objToActor(a), "getObjActToObjActDist");
- if (b < _numActors)
- actb = derefActorSafe(b, "getObjActToObjActDist(2)");
+ if (objIsActor(b))
+ actb = derefActorSafe(objToActor(b), "getObjActToObjActDist(2)");
if (acta && actb && acta->getRoom() == actb->getRoom() && acta->getRoom() && !acta->isInCurrentRoom())
return 0;
@@ -1143,11 +1143,8 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
byte *objptr;
int i;
- if ((_game.version == 0 && OBJECT_V0_TYPE(obj) == kObjectV0TypeActor) ||
- (_game.version != 0 && obj < _numActors)) {
- int actorNr = (_game.version != 0 ? obj : OBJECT_V0_ID(obj));
- return derefActor(actorNr, "getObjOrActorName")->getActorName();
- }
+ if (objIsActor(obj))
+ return derefActor(objToActor(obj), "getObjOrActorName")->getActorName();
for (i = 0; i < _numNewNames; i++) {
if (_newNames[i] == obj) {
@@ -1183,7 +1180,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
void ScummEngine::setObjectName(int obj) {
int i;
- if (obj < _numActors && _game.version != 0)
+ if (objIsActor(obj))
error("Can't set actor %d name with new-name-of", obj);
for (i = 0; i < _numNewNames; i++) {
@@ -1491,11 +1488,34 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
}
}
+bool ScummEngine::objIsActor(int obj) {
+ // object IDs < _numActors are used in v0 for objects too (e.g. hamster)
+ if (_game.version == 0)
+ return OBJECT_V0_TYPE(obj) == kObjectV0TypeActor;
+ else
+ return obj < _numActors;
+}
+
+int ScummEngine::objToActor(int obj) {
+ if (_game.version == 0)
+ return OBJECT_V0_ID(obj);
+ else
+ return obj;
+}
+
+int ScummEngine::actorToObj(int actor) {
+ if (_game.version == 0)
+ return OBJECT_V0(actor, kObjectV0TypeActor);
+ else
+ return actor;
+}
+
int ScummEngine::getObjX(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjX")->getRealPos().x;
+ if (obj < 1)
+ return 0; /* fix for indy4's map */
+
+ if (objIsActor(obj)) {
+ return derefActor(objToActor(obj), "getObjX")->getRealPos().x;
} else {
if (whereIsObject(obj) == WIO_NOT_FOUND)
return -1;
@@ -1506,10 +1526,11 @@ int ScummEngine::getObjX(int obj) {
}
int ScummEngine::getObjY(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjY")->getRealPos().y;
+ if (obj < 1)
+ return 0; /* fix for indy4's map */
+
+ if (objIsActor(obj)) {
+ return derefActor(objToActor(obj), "getObjY")->getRealPos().y;
} else {
if (whereIsObject(obj) == WIO_NOT_FOUND)
return -1;
@@ -1525,8 +1546,8 @@ int ScummEngine::getObjOldDir(int obj) {
int ScummEngine::getObjNewDir(int obj) {
int dir;
- if (obj < _numActors) {
- dir = derefActor(obj, "getObjNewDir")->getFacing();
+ if (objIsActor(obj)) {
+ dir = derefActor(objToActor(obj), "getObjNewDir")->getFacing();
} else {
int x, y;
getObjectXYPos(obj, x, y, dir);
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index b0e3a958e4..7dc8945595 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -81,7 +81,7 @@ void ScummEngine_v0::setupOpcodes() {
/* 24 */
OPCODE(0x24, o_ifNotEqualActiveObject2);
OPCODE(0x25, o5_loadRoom);
- OPCODE(0x26, o_getClosestObjActor);
+ OPCODE(0x26, o_getClosestActor);
OPCODE(0x27, o2_getActorY);
/* 28 */
OPCODE(0x28, o5_equalZero);
@@ -161,7 +161,7 @@ void ScummEngine_v0::setupOpcodes() {
/* 64 */
OPCODE(0x64, o_ifEqualActiveObject2);
OPCODE(0x65, o_stopCurrentScript);
- OPCODE(0x66, o_getClosestObjActor);
+ OPCODE(0x66, o_getClosestActor);
OPCODE(0x67, o5_getActorFacing);
/* 68 */
OPCODE(0x68, o5_isScriptRunning);
@@ -884,31 +884,30 @@ void ScummEngine_v0::o_ifNotEqualActiveObject2() {
jumpRelative(!equal);
}
-void ScummEngine_v0::o_getClosestObjActor() {
- int obj;
- int act;
+void ScummEngine_v0::o_getClosestActor() {
+ int act, check_act;
int dist;
// This code can't detect any actors farther away than 255 units
// (pixels in newer games, characters in older ones.) But this is
// perfectly OK, as it is exactly how the original behaved.
- int closest_obj = 0xFF, closest_dist = 0xFF;
+ int closest_act = 0xFF, closest_dist = 0xFF;
getResultPos();
act = getVarOrDirectByte(PARAM_1);
- obj = (_opcode & PARAM_2) ? 25 : 7;
+ check_act = (_opcode & PARAM_2) ? 25 : 7;
do {
- dist = getObjActToObjActDist(act, obj);
+ dist = getObjActToObjActDist(actorToObj(act), actorToObj(check_act));
if (dist < closest_dist) {
closest_dist = dist;
- closest_obj = obj;
+ closest_act = check_act;
}
- } while (--obj);
+ } while (--check_act);
- setResult(closest_obj);
+ setResult(closest_act);
}
void ScummEngine_v0::o_cutscene() {
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 6f6138d411..59500deaf5 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1315,7 +1315,7 @@ void ScummEngine_v2::o2_getActorX() {
getResultPos();
a = getVarOrDirectByte(PARAM_1);
- setResult(getObjX(a));
+ setResult(getObjX(actorToObj(a)));
}
void ScummEngine_v2::o2_getActorY() {
@@ -1323,7 +1323,7 @@ void ScummEngine_v2::o2_getActorY() {
getResultPos();
a = getVarOrDirectByte(PARAM_1);
- setResult(getObjY(a));
+ setResult(getObjY(actorToObj(a)));
}
void ScummEngine_v2::o2_isGreater() {
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 707c3c2397..a5591b701f 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1095,10 +1095,16 @@ void ScummEngine_v5::o5_getClosestObjActor() {
void ScummEngine_v5::o5_getDist() {
int o1, o2;
int r;
+
getResultPos();
+
o1 = getVarOrDirectWord(PARAM_1);
o2 = getVarOrDirectWord(PARAM_2);
- r = getObjActToObjActDist(o1, o2);
+
+ if (_game.version == 0) // in v0 both parameters are always actor IDs, never objects
+ r = getObjActToObjActDist(actorToObj(o1), actorToObj(o2));
+ else
+ r = getObjActToObjActDist(o1, o2);
// FIXME: MI2 race workaround, see bug #597022. We never quite figured out
// what the real cause of this, or if it maybe occurs in the original, too...
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index fadc3902c0..042a3a5d47 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -787,6 +787,9 @@ protected:
void setOwnerOf(int obj, int owner);
void clearOwnerOf(int obj);
int getObjectRoom(int obj) const;
+ bool objIsActor(int obj);
+ int objToActor(int obj);
+ int actorToObj(int actor);
int getObjX(int obj);
int getObjY(int obj);
void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); }
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index c5c0c0950c..10ae18ace5 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -138,7 +138,7 @@ protected:
void o_doSentence();
void o_ifEqualActiveObject2();
void o_ifNotEqualActiveObject2();
- void o_getClosestObjActor();
+ void o_getClosestActor();
void o_printEgo_c64();
void o_print_c64();
void o_unlockRoom();