diff options
| -rw-r--r-- | engines/scumm/object.cpp | 74 | ||||
| -rw-r--r-- | engines/scumm/object.h | 8 | ||||
| -rw-r--r-- | engines/scumm/script.cpp | 2 | ||||
| -rw-r--r-- | engines/scumm/script_v0.cpp | 65 | ||||
| -rw-r--r-- | engines/scumm/script_v2.cpp | 2 | ||||
| -rw-r--r-- | engines/scumm/scumm.cpp | 11 | ||||
| -rw-r--r-- | engines/scumm/scumm.h | 7 | ||||
| -rw-r--r-- | engines/scumm/scumm_v0.h | 29 | ||||
| -rw-r--r-- | engines/scumm/verbs.cpp | 542 | 
9 files changed, 360 insertions, 380 deletions
| diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index a9e2a76345..53dc0151d9 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -178,10 +178,7 @@ void ScummEngine::clearOwnerOf(int obj) {  		// Alternatively, scan the inventory to see if the object is in there...  		for (i = 0; i < _numInventory; i++) {  			if (_inventory[i] == obj) { -				if (_game.version == 0) -					assert(WIO_INVENTORY == whereIsObjectInventory(obj)); -				else -					assert(WIO_INVENTORY == whereIsObject(obj)); +				assert(WIO_INVENTORY == whereIsObject(obj));  				// Found the object! Nuke it from the inventory.  				_res->nukeResource(rtInventory, i); @@ -310,52 +307,50 @@ int ScummEngine::getObjectRoom(int obj) const {  int ScummEngine::getObjectIndex(int object) const {  	int i; +	int nr = (_game.version != 0) ? object : OBJECT_V0_NR(object); -	if (object < 1) +	if (nr < 1)  		return -1;  	for (i = (_numLocalObjects-1); i > 0; i--) { -		if (_game.version == 0 ) -			if( _objs[i].obj_type != _v0ObjectFlag ) -				continue; +		if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object)) +			continue; -		if (_objs[i].obj_nr == object) +		if (_objs[i].obj_nr == nr)  			return i;  	}  	return -1;  } -int ScummEngine::whereIsObjectInventory(int object) { -	int res = 0; -	_v0ObjectInInventory = true; -	res = whereIsObject(object); -	_v0ObjectInInventory = false; - -	return res; -} -  int ScummEngine::whereIsObject(int object) const {  	int i; -	if (object >= _numGlobalObjects) +	// Note: in MMC64 bg objects are greater _numGlobalObjects +	if (_game.version != 0 && object >= _numGlobalObjects)  		return WIO_NOT_FOUND;  	if (object < 1)  		return WIO_NOT_FOUND; -	if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) { +	if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) && +		 _objectOwnerTable[object] != OF_OWNER_ROOM)  +	{  		for (i = 0; i < _numInventory; i++)  			if (_inventory[i] == object)  				return WIO_INVENTORY;  		return WIO_NOT_FOUND;  	} -	for (i = (_numLocalObjects-1); i > 0; i--) -		if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) { +	for (i = (_numLocalObjects-1); i > 0; i--) { +		int nr = (_game.version != 0) ? object : OBJECT_V0_NR(object); +		if (_objs[i].obj_nr == nr) { +			if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object)) +				continue;  			if (_objs[i].fl_object_index)  				return WIO_FLOBJECT;  			return WIO_ROOM;  		} +	}  	return WIO_NOT_FOUND;  } @@ -396,7 +391,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {   * Returns X, Y and direction in angles   */  void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { -	int idx = (_v0ObjectIndex) ? object : getObjectIndex(object); +	int idx = getObjectIndex(object);  	assert(idx >= 0);  	ObjectData &od = _objs[idx];  	int state; @@ -497,6 +492,7 @@ int ScummEngine::findObject(int x, int y) {  	byte a;  	const int mask = (_game.version <= 2) ? kObjectState_08 : 0xF; +	// FIXME(TOBIAS): <= _numLocalObjects?  	for (i = 1; i < _numLocalObjects; i++) {  		if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))  			continue; @@ -522,11 +518,8 @@ int ScummEngine::findObject(int x, int y) {  #endif  				if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&  				    _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) { -					// MMC64: Set the object search flag  					if (_game.version == 0) -						_v0ObjectFlag = _objs[i].obj_type; -					if (_game.version == 0 && _v0ObjectIndex) -						return i; +						return OBJECT_V0(_objs[i].obj_nr, _objs[i].obj_type);  					else  						return _objs[i].obj_nr;  				} @@ -1165,7 +1158,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {  		}  	} -	objptr = getOBCDFromObject(obj); +	objptr = getOBCDFromObject(obj, true);  	if (objptr == NULL)  		return NULL; @@ -1218,15 +1211,14 @@ void ScummEngine::setObjectName(int obj) {  uint32 ScummEngine::getOBCDOffs(int object) const {  	int i; -	if ((_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0))  || _v0ObjectInInventory) +	if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) && +		_objectOwnerTable[object] != OF_OWNER_ROOM)  		return 0; -	// V0 MM Return by Index -	if (_v0ObjectIndex) -		return _objs[object].OBCDoffset; -  	for (i = (_numLocalObjects-1); i > 0; i--) {  		if (_objs[i].obj_nr == object) { +			if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object)) +				continue;  			if (_objs[i].fl_object_index != 0)  				return 8;  			return _objs[i].OBCDoffset; @@ -1235,21 +1227,25 @@ uint32 ScummEngine::getOBCDOffs(int object) const {  	return 0;  } -byte *ScummEngine::getOBCDFromObject(int obj) { -	bool useInventory = _v0ObjectInInventory; +byte *ScummEngine::getOBCDFromObject(int obj, bool v0CheckInventory) {  	int i;  	byte *ptr; -	_v0ObjectInInventory = false; - -	if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) { +	if ((_game.version != 0 || OBJECT_V0_TYPE(obj) == 0) && +		_objectOwnerTable[obj] != OF_OWNER_ROOM)  +	{ +		if (_game.version == 0 && !v0CheckInventory) +			return 0;  		for (i = 0; i < _numInventory; i++) {  			if (_inventory[i] == obj)  				return getResourceAddress(rtInventory, i);  		}  	} else {  		for (i = (_numLocalObjects-1); i > 0; --i) { -			if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) { +			int nr = (_game.version != 0) ? obj : OBJECT_V0_NR(obj); +			if (_objs[i].obj_nr == nr) { +				if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(obj)) +					continue;  				if (_objs[i].fl_object_index) {  					assert(_objs[i].OBCDoffset == 8);  					ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index); diff --git a/engines/scumm/object.h b/engines/scumm/object.h index edbff38355..7e4a5b57ab 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -24,6 +24,14 @@  namespace Scumm { +static inline int OBJECT_V0(int id, byte type) { +	assert(id < 255); +	return (type << 8 | id); +} +#define OBJECT_V0_NR(obj)	(obj & 0xFF) +#define OBJECT_V0_TYPE(obj)	((obj >> 8) & 0xFF) + +  enum ObjectClass {  	kObjectClassNeverClip = 20,  	kObjectClassAlwaysClip = 21, diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 37ea3a9a9f..d04c3c0891 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -131,8 +131,6 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b  	initializeLocals(slot, vars); -	// V0 Ensure we don't try and access objects via index inside the script -	_v0ObjectIndex = false;  	runScriptNested(slot);  } diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 2bbde617ad..14df89b28d 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -365,7 +365,7 @@ uint ScummEngine_v0::fetchScriptWord() {  int ScummEngine_v0::getActiveObject() {  	if (_opcode & PARAM_2) -		return _activeObject; +		return _activeObjectNr;  	return fetchScriptByte();  } @@ -406,22 +406,9 @@ void ScummEngine_v0::decodeParseString() {  	actorTalk(buffer);  } -const byte *ScummEngine_v0::getObjectName(int object, int type) { -	const byte *temp; - -	if (type == kObjectTypeInventory) -		_v0ObjectInInventory = true; - -	temp = getObjOrActorName(object); - -	_v0ObjectInInventory = false; - -	return temp; -} -  void ScummEngine_v0::drawSentenceObject(int object, int type) {  	const byte *temp; -	temp = getObjectName(object, type); +	temp = getObjOrActorName(OBJECT_V0(object, type));  	if (temp) {  		_sentenceBuf += " ";  		_sentenceBuf += (const char *)temp; @@ -443,25 +430,25 @@ void ScummEngine_v0::drawSentence() {  		return;  	} -	if (_activeObject) { +	if (_activeObjectNr) {  		// Draw the 1st active object -		drawSentenceObject(_activeObject, _activeObjectType); +		drawSentenceObject(_activeObjectNr, _activeObjectType);  		// Append verb preposition -		int sentencePrep = verbPrep(); +		int sentencePrep = activeVerbPrep();  		if (sentencePrep) {  			drawPreposition(sentencePrep);  			// Draw the 2nd active object -			if (_activeObject2) { +			if (_activeObject2Nr) {  				// 2nd Object is an actor  				if (_activeObject2Type == kObjectTypeActor) { -					Actor *a = derefActor(_activeObject2, ""); +					Actor *a = derefActor(_activeObject2Nr, "");  					_sentenceBuf += " ";  					_sentenceBuf += (const char *)a->getActorName();  				// 2nd Object is an inventory or room object  				} else { -					drawSentenceObject(_activeObject2, _activeObject2Type); +					drawSentenceObject(_activeObject2Nr, _activeObject2Type);  				}  			}  		} @@ -705,26 +692,13 @@ void ScummEngine_v0::o_putActorAtObject() {  }  void ScummEngine_v0::o_pickupObject() { -	int obj = fetchScriptByte(); -	if (obj == 0) { -		if (_activeObject) { -			obj = _activeObject; -		} else { -			// might happen if an inventory item was picked again -			return; -		} -	} +	int objNr = fetchScriptByte(); +	int obj = OBJECT_V0((objNr ? objNr : _activeObjectNr), 0); -	if (obj < 1) { -		error("pickupObject received invalid index %d (script %d)", obj, vm.slot[_currentScript].number); -	} - -	if (getObjectIndex(obj) == -1) +	/* Don't take an object twice */ +	if (whereIsObject(obj) == WIO_INVENTORY)  		return; -	if (whereIsObjectInventory(_activeObject2) == WIO_INVENTORY)	/* Don't take an */ -		return;					/* object twice */ -  	addObjectToInventory(obj, _roomResource);  	markObjectRectAsDirty(obj);  	putOwner(obj, VAR(VAR_EGO)); @@ -822,8 +796,8 @@ void ScummEngine_v0::o_doSentence() {  bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {  	byte obj = fetchScriptByte(); -	if (!inventoryObject || (_activeObject2Type == kObjectTypeInventory)) -		return (obj == _activeObject2); +	if (!inventoryObject || (_activeObject2Type == kObjectTypeFG)) +		return (obj == _activeObject2Nr);  	return false;  } @@ -920,7 +894,7 @@ void ScummEngine_v0::o_setOwnerOf() {  	owner = getVarOrDirectByte(PARAM_2);  	if (obj == 0) -		obj = _activeObject; +		obj = _activeObjectNr;  	// FIXME: the original interpreter seems to set the owner of   	// an item to remove (new owner 0) to 13 (purple tentacle). @@ -939,16 +913,15 @@ void ScummEngine_v0::resetSentence(bool walking) {  	// If the actor is walking, or the screen is a keypad (no sentence verbs/objects are drawn)  	// Then reset all active objects (stops the radio crash, bug #3077966)  	if (!walking || !(_userState & 32)) { -		_v0ObjectFlag = 0; -		_activeObject = 0; -		_activeObject2 = 0; +		_activeObjectNr = 0; +		_activeObjectType = kObjectTypeBG; +		_activeObject2Nr = 0; +		_activeObject2Type = kObjectTypeBG;  	}  	_verbExecuting = false;  	_verbPickup = false; -	_activeObjectType = kObjectTypeRoom; -	_activeObject2Type = kObjectTypeRoom;  	_activeObjectObtained = false;  	_activeObject2Obtained = false;  } diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 003bafa27e..1ea3257c17 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1223,8 +1223,6 @@ void ScummEngine_v2::o2_walkActorToObject() {  	int obj;  	Actor *a; -	_v0ObjectFlag = 0; -  	a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");  	obj = getVarOrDirectWord(PARAM_2);  	if (whereIsObject(obj) != WIO_NOT_FOUND) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index d3dc702395..423ad79b00 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -151,9 +151,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)  	_fileHandle = 0;  	// Init all vars -	_v0ObjectIndex = false; -	_v0ObjectInInventory = false; -	_v0ObjectFlag = 0;  	_imuse = NULL;  	_imuseDigital = NULL;  	_musicEngine = NULL; @@ -720,10 +717,10 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)  	_currentMode = 0;  	_activeVerb = 0; -	_activeObject = 0; -	_activeObject2 = 0; -	_activeObjectType = kObjectTypeRoom; -	_activeObject2Type = kObjectTypeRoom; +	_activeObjectNr = 0; +	_activeObject2Nr = 0; +	_activeObjectType = kObjectTypeBG; +	_activeObject2Type = kObjectTypeBG;  	_activeObjectObtained = false;  	_activeObject2Obtained = false; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index d9237b2b30..f004176da1 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -502,10 +502,6 @@ protected:  	int32 *_scummVars;  	byte *_bitVars; -	bool _v0ObjectIndex;			// V0 Use object index, instead of object number -	bool _v0ObjectInInventory;		// V0 Use object number from inventory -	byte _v0ObjectFlag; -  	/* Global resource tables */  	int _numVariables, _numBitVariables, _numLocalObjects;  	int _numGlobalObjects, _numArray, _numVerbs, _numFlObject; @@ -799,7 +795,6 @@ protected:  	int getObjNewDir(int obj);  	int getObjectIndex(int object) const;  	int getObjectImageCount(int object); -	int whereIsObjectInventory(int object);  	int whereIsObject(int object) const;  	int findObject(int x, int y);  	void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room); @@ -820,7 +815,7 @@ protected:  	virtual void clearDrawQueues();  	uint32 getOBCDOffs(int object) const; -	byte *getOBCDFromObject(int obj); +	byte *getOBCDFromObject(int obj, bool v0CheckInventory = true);  	const byte *getOBIMFromObjectData(const ObjectData &od);  	const byte *getObjectImage(const byte *ptr, int state);  	virtual int getObjectIdFromOBIM(const byte *obim); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index d9629948fe..0bb4d1a4a9 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -33,9 +33,16 @@ namespace Scumm {  class ScummEngine_v0 : public ScummEngine_v2 {  protected:  	enum ObjectType { -		kObjectTypeInventory = 0, -		kObjectTypeRoom = 1, -		kObjectTypeActor = 2 +		kObjectTypeFG = 0,    // foreground object +		                      //   - with owner/state, might (but has not to) be pickupable +		                      //     -> with entry in _objectOwner/StateTable +		                      //     -> all objects in _inventory have this type +		                      //   - image can be exchanged (background overlay) +		kObjectTypeBG = 1,    // background object +		                      //   - without owner/state, not pickupable  (room only) +		                      //     -> without entry in _objectOwner/StateTable +		                      //   - image cannot be exchanged (part of background image) +		kObjectTypeActor = 2  // object is an actor  	};  protected: @@ -44,10 +51,10 @@ protected:  	bool _verbPickup;				// are we picking up an object during a verb execute  	int _activeVerb; -	int _activeObject;				// 1st Object Number -	int _activeObjectType;			// 1st Object Type (0: inventory, 1: room) -	int _activeObject2;				// 2nd Object Number -	int _activeObject2Type;			// 2nd Object Type (0: inventory, 1: room, 2: actor) +	int _activeObjectNr;			// 1st Object Number +	int _activeObjectType;			// 1st Object Type (0: inventory (or room), 1: room) +	int _activeObject2Nr;			// 2nd Object Number +	int _activeObject2Type;			// 2nd Object Type (0: inventory (or room), 1: room, 2: actor)  	bool _activeObjectObtained;		// collected _activeobject?  	bool _activeObject2Obtained;	// collected _activeObject2? @@ -73,20 +80,20 @@ protected:  	virtual void saveOrLoad(Serializer *s);  	// V0 MM Verb commands -	int  verbPrep(); +	int getVerbPrepId(); +	int activeVerbPrep();  	bool verbMove(int object, bool invObject);  	bool verbMoveToActor(int actor); -	bool verbObtain(int object, int objType); +	bool verbObtain(int object);  	bool verbExecutes(int object, bool inventory = false);  	bool verbExec();  	virtual void checkExecVerbs();  	virtual void handleMouseOver(bool updateInventory); +	int verbPrepIdType(int verbid);  	void resetVerbs();  	void setNewKidVerbs(); -	const byte *getObjectName(int object, int type); -  	void drawSentenceObject(int object, int type);  	void drawSentence(); diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index dc4a47a231..467b587b63 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -37,51 +37,82 @@ enum {  	kSentenceLine = 6  }; +enum VerbsV0 { +	kVerbNone    = 0, +	kVerbOpen    = 1, +	kVerbClose   = 2, +	kVerbGive    = 3, +	kVerbTurnOn  = 4, +	kVerbTurnOff = 5, +	kVerbFix     = 6, +	kVerbNewKid  = 7, +	kVerbUnlock  = 8, +	kVerbPush    = 9, +	kVerbPull    = 10, +	kVerbUse     = 11, +	kVerbRead    = 12, +	kVerbWalkTo  = 13, +	kVerbPickUp  = 14, +	kVerbWhatIs  = 15 +}; +  struct VerbSettings {  	int id;  	int x_pos;  	int y_pos; -	int prep;  	const char *name;  };  static const VerbSettings v0VerbTable_English[] = { -	{ 1,  8, 0,   0, "Open"}, -	{ 2,  8, 1,   0, "Close"}, -	{ 3,  0, 2,   4, "Give"}, -	{ 4, 32, 0,   0, "Turn on"}, -	{ 5, 32, 1,   0, "Turn off"}, -	{ 6, 32, 2,   2, "Fix"}, -	{ 7, 24, 0,   0, "New Kid"}, -	{ 8, 24, 1,   2, "Unlock"}, -	{ 9,  0, 0,   0, "Push"}, -	{10,  0, 1,   0, "Pull"}, -	{11, 24, 2, 255, "Use"}, -	{12,  8, 2,   0, "Read"}, -	{13, 15, 0,   0, "Walk to"}, -	{14, 15, 1,   0, "Pick up"}, -	{15, 15, 2,   0, "What is"} +	{kVerbOpen,     8, 0, "Open"}, +	{kVerbClose,    8, 1, "Close"}, +	{kVerbGive,     0, 2, "Give"}, +	{kVerbTurnOn,  32, 0, "Turn on"}, +	{kVerbTurnOff, 32, 1, "Turn off"}, +	{kVerbFix,     32, 2, "Fix"}, +	{kVerbNewKid,  24, 0, "New Kid"}, +	{kVerbUnlock,  24, 1, "Unlock"}, +	{kVerbPush,     0, 0, "Push"}, +	{kVerbPull,     0, 1, "Pull"}, +	{kVerbUse,     24, 2, "Use"}, +	{kVerbRead,     8, 2, "Read"}, +	{kVerbWalkTo,  15, 0, "Walk to"}, +	{kVerbPickUp,  15, 1, "Pick up"}, +	{kVerbWhatIs,  15, 2, "What is"}  };  // FIXME: Replace * with the correct character  static const VerbSettings v0VerbTable_German[] = { -	{ 1,  7, 0,   0, "$ffne"}, -	{ 2, 13, 1,   0, "Schlie*e"}, -	{ 3,  0, 2,   4, "Gebe"}, -	{ 4, 37, 1,   0, "Ein"}, -	{ 5, 37, 0,   0, "Aus"}, -	{ 6, 23, 1,   2, "Repariere"}, -	{ 7, 34, 2,   0, "Person"}, -	{ 8, 23, 0,   2, "Schlie*e auf"}, -	{ 9,  0, 0,   0, "Dr<cke"}, -	{10,  0, 1,   0, "Ziehe"}, -	{11, 23, 2, 255, "Benutz"}, -	{12,  7, 2,   0, "Lese"}, -	{13, 13, 0,   0, "Gehe zu"}, -	{14,  7, 1,   0, "Nimm"}, -	{15, 13, 2,   0, "Was ist"} +	{kVerbOpen,     7, 0, "$ffne"}, +	{kVerbClose,   13, 1, "Schlie*e"}, +	{kVerbGive,     0, 2, "Gebe"}, +	{kVerbTurnOn,  37, 1, "Ein"}, +	{kVerbTurnOff, 37, 0, "Aus"}, +	{kVerbFix,     23, 1, "Repariere"}, +	{kVerbNewKid,  34, 2, "Person"}, +	{kVerbUnlock,  23, 0, "Schlie*e auf"}, +	{kVerbPush,     0, 0, "Dr<cke"}, +	{kVerbPull,     0, 1, "Ziehe"}, +	{kVerbUse,     23, 2, "Benutz"}, +	{kVerbRead,     7, 2, "Lese"}, +	{kVerbWalkTo,  13, 0, "Gehe zu"}, +	{kVerbPickUp,   7, 1, "Nimm"}, +	{kVerbWhatIs,  13, 2, "Was ist"}  }; +int ScummEngine_v0::verbPrepIdType(int verbid) { +	switch (verbid) { +	case kVerbUse: // depends on object1 +		return 0xFF; +	case kVerbGive:  +		return 4; +	case kVerbUnlock: case kVerbFix: +		return 2; +	default: +		return 0; +	} +} +  void ScummEngine_v0::resetVerbs() {  	VirtScreen *virt = &_virtscr[kVerbVirtScreen];  	VerbSlot *vs; @@ -112,7 +143,7 @@ void ScummEngine_v0::resetVerbs() {  		vs->key = 0;  		vs->center = 0;  		vs->imgindex = 0; -		vs->prep = vtable[i - 1].prep; +		vs->prep = verbPrepIdType(vtable[i - 1].id);  		vs->curRect.left = vtable[i - 1].x_pos * 8;  		vs->curRect.top = vtable[i - 1].y_pos * 8 + virt->topline + 8;  		loadPtrToResource(rtVerb, i, (const byte*)vtable[i - 1].name); @@ -433,9 +464,7 @@ void ScummEngine_v2::redrawV2Inventory() {  		_string[1].right = _mouseOverBoxesV2[i].rect.right - 1;  		_string[1].color = _mouseOverBoxesV2[i].color; -		_v0ObjectInInventory = true;  		const byte *tmp = getObjOrActorName(obj); -		_v0ObjectInInventory = false;  		assert(tmp);  		// Prevent inventory entries from overflowing by truncating the text @@ -518,7 +547,7 @@ void ScummEngine_v2::handleMouseOver(bool updateInventory) {  }  void ScummEngine_v0::handleMouseOver(bool updateInventory) { -	drawSentence(); +	//drawSentence();  	ScummEngine_v2::handleMouseOver(updateInventory);  } @@ -713,8 +742,6 @@ void ScummEngine_v2::checkExecVerbs() {  }  void ScummEngine_v0::runObject(int obj, int entry) { -	bool prev = _v0ObjectInInventory; -  	if (getVerbEntrypoint(obj, entry) == 0) {  		// If nothing was found, attempt to find the 'WHAT-IS' verb script  		// (which is not really the what-is script, as this verb never actually executes @@ -724,23 +751,20 @@ void ScummEngine_v0::runObject(int obj, int entry) {  		}  	} -	_v0ObjectInInventory = prev; -  	if (getVerbEntrypoint(obj, entry) != 0) { -		_v0ObjectInInventory = prev;  		runObjectScript(obj, entry, false, false, NULL);  	} else if (entry != 13 && entry != 15) { -		if (_activeVerb != 3) { +		if (_activeVerb == kVerbGive) { +			// For some reasons, certain objects don't have a "give" script +			if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) { +				if (OBJECT_V0_TYPE(obj) == kObjectTypeFG) { +					assert(false); +					setOwnerOf(obj, VAR(VAR_ACTIVE_ACTOR)); +				} +			} +		} else {  			VAR(VAR_ACTIVE_VERB) = entry;  			runScript(3, 0, 0, 0); - -		// For some reasons, certain objects don't have a "give" script -		} else if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) { -			// TODO -			/* -			if (_activeInventory) -				setOwnerOf(_activeInventory, VAR(VAR_ACTIVE_ACTOR)); -			*/  		}  	}  } @@ -785,13 +809,16 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) {  	} else {  		// Finished walk, are we picking up the item?  		if (_verbPickup) { -			int oldActive = _activeObject; -			_activeObject = object; +			int oldActive = OBJECT_V0(_activeObjectNr, _activeObjectType); + +			_activeObjectNr = OBJECT_V0_NR(object); +			_activeObjectType = OBJECT_V0_TYPE(object);  			// Execute pickup  			runObject(object, 14); -			_activeObject = oldActive; +			_activeObjectNr = OBJECT_V0_NR(oldActive); +			_activeObjectType = OBJECT_V0_TYPE(oldActive);  			// Finished picking up  			_verbPickup = false; @@ -801,7 +828,7 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) {  	return false;  } -bool ScummEngine_v0::verbObtain(int obj, int objType) { +bool ScummEngine_v0::verbObtain(int obj) {  	bool didPickup = false;  	int prep;  	int where; @@ -809,11 +836,11 @@ bool ScummEngine_v0::verbObtain(int obj, int objType) {  	if (!obj)  		return false; -	where = whereIsObjectInventory(obj); +	where = whereIsObject(obj);  	// Object in inventory ?  	if (where != WIO_INVENTORY) { -		prep = verbPrep(); +		prep = activeVerbPrep();  		if (prep == 1 || prep == 4) {  			if (_activeVerb != 13 && _activeVerb != 14) { @@ -837,79 +864,63 @@ bool ScummEngine_v0::verbObtain(int obj, int objType) {  		if (didPickup && (prep == 1 || prep == 4))  			if (_activeVerb != 13 && _activeVerb != 14) { -				// TODO -				/* -				_v0ObjectInInventory = true; - +// TODO(TOBIAS) +#if 0  				if (whereIsObject(obj) == WIO_INVENTORY)  					_activeInventory = obj;  				else  					resetSentence(false); - -				_v0ObjectInInventory = false; -				*/ +#endif  			}  	}  	return false;  } -int ScummEngine_v0::verbPrep() { +int ScummEngine_v0::getVerbPrepId() {  	if (_verbs[_activeVerb].prep != 0xFF) {  		return _verbs[_activeVerb].prep;  	} else { -		if (!_v0ObjectInInventory) -			_v0ObjectIndex = true; -		else -			_v0ObjectIndex = false; - -		byte *ptr = getOBCDFromObject(_activeObject); -		_v0ObjectIndex = false; +		byte *ptr = getOBCDFromObject(OBJECT_V0(_activeObjectNr, _activeObjectType), true);  		assert(ptr);  		return (*(ptr + 11) >> 5);  	}  } -bool ScummEngine_v0::verbExecutes(int object, bool inventory) { -	_v0ObjectInInventory = inventory; -	int prep = verbPrep(); - -	if (prep == 2 || prep == 0) { -		return true; -	} - -	return false; +int ScummEngine_v0::activeVerbPrep() { +	if (!_activeVerb || !_activeObjectNr) +		return 0; +	return getVerbPrepId();  }  bool ScummEngine_v0::verbExec() {  	int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; -	if (_activeObject && getObjectIndex(_activeObject) == -1) { +	if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) {  		resetSentence(false);  		return false;  	}  	// Lets try walk to the object -	if (_activeObject && !_activeObjectObtained && _currentMode != 0) { -		if (verbObtain(_activeObject, _activeObjectType)) +	if (_activeObjectNr && !_activeObjectObtained && _currentMode != 0) { +		if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType)))  			return true;  		_activeObjectObtained = true;  	}  	// Attempt to obtain/reach object2 -	if (_activeObject2 && !_activeObject2Obtained && _currentMode != 0) { -		_v0ObjectInInventory = false; -		if (verbObtain(_activeObject2, _activeObject2Type)) +	if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != 0) { +		if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type)))  			return true;  		_activeObject2Obtained = true;  	}  	// Give-To -	if (_activeVerb == 3 && _activeObject && _activeObject2 && _activeObject2Type == kObjectTypeActor) { +	if (_activeVerb == 3 && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {  		// FIXME: Actors need to turn and face each other -		if (verbMoveToActor(_activeObject2)) { +		if (verbMoveToActor(_activeObject2Nr)) {  			// Ignore verbs?  			Actor *a = derefActor(VAR(VAR_EGO), "verbExec");  			if (((ActorC64 *)a)->_miscflags & 0x40) { @@ -919,18 +930,16 @@ bool ScummEngine_v0::verbExec() {  			return true;  		} -		_v0ObjectInInventory = true; -		VAR(VAR_ACTIVE_ACTOR) = _activeObject2; -		runObject(_activeObject , 3); -		_v0ObjectInInventory = false; +		VAR(VAR_ACTIVE_ACTOR) = _activeObject2Nr; +		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), 3);  		resetSentence(false);  		return false;  	}  	// Where we performing an action on an actor? -	if (_activeObject2 && _activeObject2Type == kObjectTypeActor) { -		runObject(_activeObject2, entry); +	if (_activeObject2Nr && _activeObject2Type == kObjectTypeActor) { +		runObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type), entry);  		_verbExecuting = false;  		resetSentence(false); @@ -938,8 +947,8 @@ bool ScummEngine_v0::verbExec() {  	}  	// If we've finished walking (now near target), execute the action -	if (_activeObject && verbPrep() == 2) { -		runObject(_activeObject, entry); +	if (_activeObjectNr && activeVerbPrep() == 2) { +		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);  		_verbExecuting = false;  		if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13) @@ -950,9 +959,8 @@ bool ScummEngine_v0::verbExec() {  	}  	// We acted on an inventory item -	if (/*_activeInventory && verbExecutes(_activeInventory, true) &&*/ _activeVerb != 3) { -		_v0ObjectInInventory = true; -		runObject(_activeObject/*2*/, _activeVerb); +	if (_activeVerb != 3) { +		runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb);  		_verbExecuting = false; @@ -965,36 +973,8 @@ bool ScummEngine_v0::verbExec() {  		return false;  	} -	// Item not in inventory is executed -	if (_activeObject) { -		runObject(_activeObject, entry); -	} else if (/*_activeInventory*/false) { -#if 0 -		// Not sure this is the correct way to do this, -		// however its working for most situations - segra -		if (verbExecutes(_activeInventory, true) == false) { -			if (_activeObject2 && _activeObject2Type == kObjectTypeInventory && verbExecutes(_activeObject2, true)) { -				_v0ObjectInInventory = true; - -				_activeObject = _activeInventory; -				_activeInventory = _activeObject2; - -				runObject(_activeObject, _activeVerb); -			} else { -				_v0ObjectInInventory = true; - -				if (_activeObject2) { -					_activeObject = _activeObject2; - -					runObject(_activeObject, _activeVerb); -				} else -					runObject(_activeInventory, _activeVerb); -			} -		} else { -			_v0ObjectInInventory = true; -			runObject(_activeInventory, _activeVerb); -		} -#endif +	if (_activeObjectNr) { +		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);  	}  	_verbExecuting = false; @@ -1009,17 +989,182 @@ bool ScummEngine_v0::verbExec() {  	return false;  } +#if 0 +verbExec() { +	cmdStackMaxLeft = 6; +	cmdStackPos = 0xFF; +	if (verbSelectedID == 15) // WHAT IS +		return; +		 +	if (verbSelectedID != 13 || objectSelectedID != 0) { +		cmdStackPos++; +		cmdVerbID[cmdStackPos] = verbSelectedID; +		cmdObjectID[cmdStackPos] = objectSelectedID; +		cmdObjectType[cmdStackPos] = objectSelectedType; +		cmdVerbPrepID[cmdStackPos] = verbPrepID; +		cmdObject2ID[cmdStackPos] = objectSelected2ID; +		cmdObject2Type[cmdStackPos] = objectSelected2Type; +		 +		if (verbSelectedID != 13) { // WALK TO +			verbSelectedID = 13; +			objectSelectedID = 0; +			verbPrepID = 0; +		} +		scriptUpdateSkip = 0; +		return; +	} +	 +	currentActor = scriptVARS[0]; +	roomActor = gActorInRoom[currentActor]; +	tmpX = cursorX(); +	tmpY = cursorY(); +	actorSetPosInBox(); + +	scriptVARS[6] = tmpX; +	scriptVARS[7] = tmpY; +	 +	if (gActor_miscFlags[scriptVARS[0]] & 0x40) { +		rActor_scriptWalkToX[roomActor] = tmpX; +		rActor_scriptWalkToX[roomActor] = tmpY; +		walk_1C4A(); +	} +} +#endif +  void ScummEngine_v0::checkExecVerbs() {  	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");  	VirtScreen *zone = findVirtScreen(_mouse.y); +	int scriptUpdateSkip; +	int sentenceLineChanged = false; + +	/* +	if (_userPut <= 0 || _mouseAndKeyboardStat == 0) +		return; +	*/ + +	// Check if mouse click +	if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { +		int over = findVerbAtPos(_mouse.x, _mouse.y); +		if (over && _activeVerb != over) { +			_activeVerb = over; +			//_activeVerbPrep = 0; +			_activeObjectNr = 0; +			_activeObjectType = 0; +			_activeObject2Nr = 0; +			_activeObject2Type = 0; +			sentenceLineChanged = true; +		} +	} + +	if (a->_miscflags & 0x80) { +		if (_activeVerb != kVerbNewKid) { +			_activeVerb = kVerbNone; +		} +	} + +	// mode 1: kid selection, 3: normal +	if (_currentMode != 0) { +		if (_currentMode == 1) { +			// kid selection or dial pad +			_activeVerb = kVerbPush; +		} + +		if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) { +			int id; +			byte type; +			if (_activeVerb == kVerbGive && _activeObjectNr) { +				id = getActorFromPos(_virtualMouse.x, _virtualMouse.y); +				type = kObjectTypeActor; +			} else { +				int obj = findObject(_virtualMouse.x, _virtualMouse.y); +				id = OBJECT_V0_NR(obj); +				type = OBJECT_V0_TYPE(obj); +				debug("found 0x%03x", obj); +			} +			if (!id) { +				if (_activeVerb == kVerbWalkTo) { +					_activeObjectNr = 0; +					_activeObject2Nr = 0; +				} +			} else { +				//_activeVerbPrep: +				// 0: no activeObject or activeObject but no prep +				// > 0: activeObject + prep +				if (activeVerbPrep() == 0) { +					if (id == _activeObjectNr && type == _activeObjectType) { +						_verbExecuting = true; +					} else { +						_activeObjectNr = id; +						_activeObjectType = type; +					} +					//sentenceLineChanged = true; +					if (_currentMode == 1) +						_verbExecuting = true; +				} else { +					if (id == _activeObject2Nr && type == _activeObject2Type) +						_verbExecuting = true; +					if (!(id == _activeObjectNr && type == _activeObjectType)) { +						_activeObject2Nr = id; +						_activeObject2Type = type; +						if (_currentMode == 1) +							_verbExecuting = true; +					} +				} +			} + +			sentenceLineChanged = true; +			if (_activeVerb == kVerbWalkTo) { +				scriptUpdateSkip = 0; +				_verbExecuting = true; +			} +		} +	} + +	if (sentenceLineChanged) +		drawSentence(); + +	if (_activeVerb == kVerbNewKid) { +		// TODO +		if (_currentMode == 3) { +			// get kid +			_activeVerb = kVerbWalkTo; +			resetSentence(false); +			//switchActor(_verbs[over].verbid - 1); +		} +		_activeVerb = kVerbWalkTo; +	} + +	if (_activeVerb == kVerbWalkTo) { +		//exec(); +	} + +	/* +	if (_activeVerbPrep == 0) { +		int prep = activeVerbPrep(); +		if (prep == 0) +			; //exec(); +		else { +			_activeVerbPrep = prep; +			; // draw() +		} +	} else { +		if (_activeObject2 == 0) +			; //drawSentence(); +		else +			; // exec(); +	} +	*/ + +#if 0  	// Is a verb currently executing  	if (_verbExecuting) {  		// Check if mouse click  		if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {  			int over = findVerbAtPos(_mouse.x, _mouse.y);  			int act  = getActorFromPos(_virtualMouse.x, _virtualMouse.y); -			int obj  = findObject(_virtualMouse.x, _virtualMouse.y); +			byte type; +			int obj  = findObject(_virtualMouse.x, _virtualMouse.y, &type);  			if (over && over != _activeVerb) {  				_activeVerb = over; @@ -1039,17 +1184,6 @@ void ScummEngine_v0::checkExecVerbs() {  		}  	} -	// What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo -	if (_activeVerb == 15) { -		int obj = findObject(_virtualMouse.x, _virtualMouse.y); -		_activeObject = obj; - -		if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK)) -			_activeVerb = 13;	// Walk-To - -		return; -	} -  	if (_userPut <= 0 || _mouseAndKeyboardStat == 0)  		return; @@ -1060,78 +1194,19 @@ void ScummEngine_v0::checkExecVerbs() {  		if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {  			// TODO  		} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { -#if 0 -			int prevInventory = _activeInventory; -#endif  			int invOff = _inventoryOffset; -			// GIVE: actor must be selected (not possible via inventory) -			if ((_activeVerb == 3) && _activeObject) -				return; -  			// Click into V2 inventory  			checkV2Inventory(_mouse.x, _mouse.y);  			// Did the Inventory position changed (arrows pressed, do nothing)  			if (invOff != _inventoryOffset)  				return; - -#if 0 -			// No inventory selected? -			if (!_activeInventory) -				return; - -			// Did we just change the selected inventory item? -			if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) { -				// Setup object2 -				_activeObject = 0; -				_activeObject2Type = kObjectTypeInventory; -				_activeObject2 = _activeInventory; -				_activeInventory = prevInventory; -				return; -			} - -			// is the new selected inventory the same as the last selected?, reset to previous if it is -			if (_activeInventory == _activeObject2) -				_activeInventory = prevInventory; - -			// Inventory Selected changed -			if (prevInventory != _activeInventory) -				if (!_activeObject2 || prevInventory != _activeObject2) -					return; -#endif - -			if (_activeVerb == 11 && !(_activeObject || !_activeObject2)) -				return;  		} else {  			int over = findVerbAtPos(_mouse.x, _mouse.y);  			int act  = getActorFromPos(_virtualMouse.x, _virtualMouse.y);  			int obj  = findObject(_virtualMouse.x, _virtualMouse.y); -			if (a->_miscflags & 0x80) { -				if (_activeVerb != 7 && over != 7) { -					_activeVerb = 0; -					over = 0; -				} -			} - -			// Handle New Kid verb options -			if (_activeVerb == 7 || over == 7) { -				// Disable New-Kid (in the secret lab) -				if (_currentMode == 2 || _currentMode == 0) -					return; - -				if (_activeVerb == 7 && over) { -					_activeVerb = 13; -					switchActor(_verbs[over].verbid - 1); -					return; -				} - -				setNewKidVerbs(); -				_activeVerb = 7; - -				return; -			}  			// Clicked on nothing, walk here?  			if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) { @@ -1154,77 +1229,10 @@ void ScummEngine_v0::checkExecVerbs() {  				}  				return;  			} - -			// No new verb, use previous -			if (over == 0) -				over = _activeVerb; - -			// No verb selected, use walk-to -			if (!_activeVerb) -				_activeVerb = over = 13;		// Walk-To - -			// New verb selected -			if (_activeVerb != over) { -				_activeVerb = over; -				if (_activeVerb == 13) { -					resetSentence(false); -				} -				return; -			} - -			// Only allowing targetting actors if its the GIVE verb -			if (_activeVerb == 3) { -				if (_activeObject) { -					// Once selected the object cannot be changed -					obj = 0; - -					// Different actor selected? -					if (act) { -						if (_activeObject2 != act || _activeObject2Type != kObjectTypeActor) { -							_activeObject2 = act; -							_activeObject2Type = kObjectTypeActor; -							return; -						} -					} else { -						return; -					} -				} else { -					// An object has to be selected first -					act = 0; -					if (!obj) -						return; -				} -			} - -			if (obj && obj != _activeObject) { -				// USE / UNLOCK -				if (_activeVerb == 11 || _activeVerb == 8) { -					if (obj != _activeObject && obj != _activeObject2) { -						if (!_activeObject) { -							_activeObject = obj; -							return; -						} else { -							if (_activeObject2 != obj) { -								_activeObject2 = obj; -								return; -							} -						} -					} -				} else { -					a->stopActorMoving(); - -					_activeObject = obj; -					if (_activeVerb != 13) -						return; - -					//return; -				} -			} -		} -  		_verbExecuting = true;  	}	// mouse k/b action +#endif  }  void ScummEngine::verbMouseOver(int verb) { | 
