diff options
| -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(); | 
