diff options
author | Tobias Gunkel | 2012-01-22 22:58:10 +0100 |
---|---|---|
committer | Tobias Gunkel | 2012-02-11 08:29:13 +0100 |
commit | 96f8fc6ca9889d30db11b854c95ffd65bb88034d (patch) | |
tree | e8c765f1f68123433f6f36063b7e4e2479c83d58 /engines/scumm | |
parent | fd4a3501ede75d87c06980b5ac563402da834f25 (diff) | |
download | scummvm-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.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/object.cpp | 67 | ||||
-rw-r--r-- | engines/scumm/script_v0.cpp | 21 | ||||
-rw-r--r-- | engines/scumm/script_v2.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/script_v5.cpp | 8 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 3 | ||||
-rw-r--r-- | engines/scumm/scumm_v0.h | 2 |
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(); |