[Scummvm-cvs-logs] scummvm master -> ca781b5822a19b460afd2887e67302e46b280460

Kirben kirben at optusnet.com.au
Sun Jan 29 07:18:22 CET 2012


This automated email contains information about 26 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
22cd6290a0 SCUMM: Fix sound playback if fast-mode is on
d9325d3fe3 SCUMM: Fix meteor actor index
938e617eb6 SCUMM: Fix bug with tracker ID 3072094
3ffd1952a3 SCUMM: make verbs working better
32b9df2747 SCUMM: Fix pickupObject()
be8c9a2b74 SCUMM: changed handling of _activeInventory/_activeActor to _activeObject(2)/_activeObject(2)Type
f296bf8d57 SCUMM: fix ScummEngine_v0::o_stopCurrentScript()
8339e36b62 remove unneeded verbPrep() calls
1f445a7b1d - removed complicated and unnecessary _v0ObjectIndex, _v0ObjectInInventory, _v0ObjectFlag vars
f8bca7003a selecting inventory objects and inventory scrolling works again
71617abc29 use constants for c64 actor miscflags
ed67d54840 replace verb, prep and currentMode values with symbolic constants
fffcce2699 cleanup
b265f4ad82 - MM C64 uses command stack (SentenceTab, doSentence()) now
8233af6023 make START-button in kid selection screen work again
d57b483a27 - getVerbEntrypoint() should not handle walk-to differently (revert 0x0D handling back to original behavior)
f0b97b9ef8 kid selection working again
a2c4cf194c click into sentence line now performs the action
76675a7ad5 fix a regression that was found by segra.
716dfbe46c reset sentence line if sentence executed
c9dfdbac68 - execute sentence if verb was clicked twice
5cbf2df71c pop stack if command's object1 and 2 are the same, otherwise the command will never be removed and the stack overflows
9e93af921c reset object2 correctly. This fixes the issue that a kid will not enter the front door after opening it with the key.
b5fca08312 make what-is verb work again
f0172ba159 cleanup
ca781b5822 SCUMM: Fix minor compiler warnings.


Commit: 22cd6290a0fb7e07080173057dcb09a7ce9feae5
    https://github.com/scummvm/scummvm/commit/22cd6290a0fb7e07080173057dcb09a7ce9feae5
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:42-08:00

Commit Message:
SCUMM: Fix sound playback if fast-mode is on

Sounds are played that fast in fast-mode that the queue gets stuck.
This is just a workaround and only fixes the symptoms. Check the queue handling for a correct fix.

Changed paths:
    engines/scumm/actor.cpp



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index eb23c30..4a92d6d 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1355,7 +1355,10 @@ void ScummEngine::playActorSounds() {
 			} else {
 				sound = _actors[i]->_sound[0];
 			}
-			_sound->addSoundToQueue(sound);
+			// fast mode will flood the queue with walk sounds
+			if (!_fastMode) {
+				_sound->addSoundToQueue(sound);
+			}
 			for (j = 1; j < _numActors; j++) {
 				_actors[j]->_cost.soundCounter = 0;
 			}


Commit: d9325d3fe398561954e6fa1e32d0915fa3c967f5
    https://github.com/scummvm/scummvm/commit/d9325d3fe398561954e6fa1e32d0915fa3c967f5
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:42-08:00

Commit Message:
SCUMM: Fix meteor actor index

- Now the correct actor name is shown with "give ... to meteor". Formerly the name was "".
- Add actor names that do not have a string assigned

Changed paths:
    engines/scumm/actor.cpp



diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 4a92d6d..70e051e 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1323,23 +1323,23 @@ static const byte v0ActorSounds[24] = {
 	0x06, // Bernard
 	0x06, // Wendy
 	0x00, // Jeff
-	0x46, // ???
+	0x46, // Radiation Suit
 	0x06, // Dr Fred
 	0x06, // Nurse Edna
 	0x06, // Weird Ed
 	0x06, // Dead Cousin Ted
 	0xFF, // Purple Tentacle
 	0xFF, // Green Tentacle
-	0x06, // Meteor
-	0xC0, // Plant
-	0x06, // ???
-	0x06, // ???
-	0x00, // ???
-	0xC0, // ???
-	0xC0, // ???
-	0x00, // ???
-	0x06, // Sandy
-	0x06, // ???
+	0x06, // Meteor police
+	0xC0, // Meteor
+	0x06, // Mark Eteer
+	0x06, // Talkshow Host
+	0x00, // Plant
+	0xC0, // Meteor Radiation
+	0xC0, // Edsel (small, outro)
+	0x00, // Meteor (small, intro)
+	0x06, // Sandy (Lab)
+	0x06, // Sandy (Cut-Scene)
 };
 
 /* Used in Scumm v5 only. Play sounds associated with actors */
@@ -2298,22 +2298,23 @@ static const char *const v0ActorNames_English[25] = {
 	"Bernard",
 	"Wendy",
 	"Jeff",
-	"",
+	"", // Radiation Suit
 	"Dr Fred",
 	"Nurse Edna",
 	"Weird Ed",
 	"Dead Cousin Ted",
 	"Purple Tentacle",
 	"Green Tentacle",
+	"", // Meteor Police
 	"Meteor",
-	"",
-	"",
-	"",
+	"", // Mark Eteer
+	"", // Talkshow Host
 	"Plant",
-	"",
-	"",
-	"",
-	"Sandy"
+	"", // Meteor Radiation
+	"", // Edsel (small, outro)
+	"", // Meteor (small, intro)
+	"Sandy", // (Lab)
+	"", // Sandy (Cut-Scene)
 };
 
 static const char *const v0ActorNames_German[25] = {
@@ -2331,15 +2332,16 @@ static const char *const v0ActorNames_German[25] = {
 	"Ted",
 	"Lila Tentakel",
 	"Gr<nes Tentakel",
-	"Meteor",
 	"",
+	"Meteor",
 	"",
 	"",
 	"Pflanze",
 	"",
 	"",
 	"",
-	"Sandy"
+	"Sandy",
+	"",
 };
 
 const byte *Actor::getActorName() {


Commit: 938e617eb61e92cdfc416476f0703739f5e68df4
    https://github.com/scummvm/scummvm/commit/938e617eb61e92cdfc416476f0703739f5e68df4
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:43-08:00

Commit Message:
SCUMM: Fix bug with tracker ID 3072094

MANIAC C64: Bug while getting the stamps from the parcel - ID: 3072094
MMC64: use stamps with envelope - ID: 3095595

Changed paths:
    engines/scumm/script_v0.cpp



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index e2d3f40..71dfbc6 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -979,7 +979,15 @@ void ScummEngine_v0::o_setOwnerOf() {
 	owner = getVarOrDirectByte(PARAM_2);
 
 	if (obj == 0)
-		obj = _activeInventory;
+		obj = _activeObject;
+
+	// FIXME: the original interpreter seems to set the owner of 
+	// an item to remove (new owner 0) to 13 (purple tentacle).
+	// Ignore this behavior for now.
+	/*
+	if (owner == 0)
+		owner = 13;
+	*/
 
 	setOwnerOf(obj, owner);
 }


Commit: 3ffd1952a3d166677b3ba09be8bf91610089a706
    https://github.com/scummvm/scummvm/commit/3ffd1952a3d166677b3ba09be8bf91610089a706
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:43-08:00

Commit Message:
SCUMM: make verbs working better

Changed paths:
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 67ed17c..3398cca 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -1083,6 +1083,10 @@ void ScummEngine_v0::checkExecVerbs() {
 			int prevInventory = _activeInventory;
 			int invOff = _inventoryOffset;
 
+			// GIVE: actor must be selected (not possible via inventory)
+			if ((_activeVerb == 3) && (_activeObject || _activeInventory))
+				return;
+
 			// Click into V2 inventory
 			checkV2Inventory(_mouse.x, _mouse.y);
 
@@ -1137,13 +1141,6 @@ void ScummEngine_v0::checkExecVerbs() {
 			int obj  = findObject(_virtualMouse.x, _virtualMouse.y);
 			int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
 
-			// If we already have an object selected, and we just clicked an actor
-			// Clear any object we may of also clicked on
-			if ((_activeObject || _activeInventory) && act) {
-				obj = 0;
-				objIdx = 0;
-			}
-
 			if (a->_miscflags & 0x80) {
 				if (_activeVerb != 7 && over != 7) {
 					_activeVerb = 0;
@@ -1208,14 +1205,27 @@ void ScummEngine_v0::checkExecVerbs() {
 				return;
 			}
 
-			// Only allowing targetting actors if its the GIVE/USE verb
-			if (_activeVerb == 3 || _activeVerb == 11) {
-				// Different actor selected?
-				if (act) {
-					if (_activeActor != act) {
-						_activeActor = act;
+			// Only allowing targetting actors if its the GIVE verb
+			if (_activeVerb == 3) {
+				if (_activeObject || _activeInventory) {
+					// Once selected the object cannot be changed
+					obj = 0;
+					objIdx = 0;
+
+					// Different actor selected?
+					if (act) {
+						if (_activeActor != act) {
+							_activeActor = act;
+							return;
+						}
+					} else {
 						return;
 					}
+				} else {
+					// An object has to be selected first
+					act = 0;
+					if (!obj)
+						return;
 				}
 			}
 
@@ -1224,9 +1234,12 @@ void ScummEngine_v0::checkExecVerbs() {
 					if (_activeInventory)
 						_activeInvExecute = true;
 
-				// USE
+				// USE / UNLOCK
 				if (_activeVerb == 11 || _activeVerb == 8) {
-					if (obj != _activeObject || obj != _activeObject2) {
+					if (obj != _activeObject && obj != _activeObject2) {
+						if (_activeObject || _activeInventory) {
+							//verbPrep(
+						}
 						if (!_activeObject || _activeInventory) {
 							_activeObject = obj;
 							_activeObjectIndex = objIdx;


Commit: 32b9df2747eaae2adfd2e66e7b1feb85bc4d81ed
    https://github.com/scummvm/scummvm/commit/32b9df2747eaae2adfd2e66e7b1feb85bc4d81ed
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:44-08:00

Commit Message:
SCUMM: Fix pickupObject()

Changed paths:
    engines/scumm/script_v0.cpp



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 71dfbc6..cc59e60 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -777,7 +777,12 @@ void ScummEngine_v0::o_putActorAtObject() {
 void ScummEngine_v0::o_pickupObject() {
 	int obj = fetchScriptByte();
 	if (obj == 0) {
-		obj = _activeObject;
+		if (_activeObject) {
+			obj = _activeObject;
+		} else {
+			// might happen if an inventory item was picked again
+			return;
+		}
 	}
 
 	if (obj < 1) {


Commit: be8c9a2b747a43f92a5a5517817710d2572e28a2
    https://github.com/scummvm/scummvm/commit/be8c9a2b747a43f92a5a5517817710d2572e28a2
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:44-08:00

Commit Message:
SCUMM: changed handling of _activeInventory/_activeActor to _activeObject(2)/_activeObject(2)Type

Note: the transition is not completed yet. The code compiles but is probably not runnable as not every occurrence of _activeInventory has been properly replaced.
The usage of _v0ObjectIndex and _v0ObjectInInventory should be revised too and both variables should be replaced by another mechanism (maybe by using a single variable "obj = (type << 8) | id").

- moved v0 only vars _activeInventory, _activeObject, _activeVerb from  ScummEngine_v2 to ScummEngine_v0
- removed _activeActor, _activeInvExecute, _activeObject2Inv and _activeInventory. They are handled by _activeObject/_activeObjectType and _activeObject2/_activeObject2Type now.
- removed _activeObject(2)Index as they only bloat the code without any benefit (?)
- merge prep-name tables from ScummEngine_v2::drawPreposition() and ScummEngine_v0::drawSentenceWord() by introducing ScummEngine_v2::drawPreposition()
- rename ObjectData.flags -> obj_type (quick-fix only, needs review! Maybe obj_nr and obj_type can be merged into one var: obj_nr = (obj_type << 8) | obj_nr)
- o_unknown2 is negation of o_ifActiveObject (o_ifNotEqualActiveObject2)
- renamed o_ifActiveObject -> o_ifEqualActiveObject2 as it acts only on _activeObject2
- renamed ScummEngine_v0::drawSentenceWord() -> ScummEngine_v0::getObjectName()

Changed paths:
    engines/scumm/object.cpp
    engines/scumm/object.h
    engines/scumm/saveload.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/script_v2.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/scumm_v2.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index da238dc..a9e2a76 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -316,7 +316,7 @@ int ScummEngine::getObjectIndex(int object) const {
 
 	for (i = (_numLocalObjects-1); i > 0; i--) {
 		if (_game.version == 0 )
-			if( _objs[i].flags != _v0ObjectFlag )
+			if( _objs[i].obj_type != _v0ObjectFlag )
 				continue;
 
 		if (_objs[i].obj_nr == object)
@@ -492,14 +492,6 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
 	return getDist(x, y, x2, y2);
 }
 
-int ScummEngine_v0::findObjectIndex(int x, int y) {
-	int objIdx;
-	_v0ObjectIndex = true;
-	objIdx = findObject(x, y);
-	_v0ObjectIndex = false;
-	return objIdx;
-}
-
 int ScummEngine::findObject(int x, int y) {
 	int i, b;
 	byte a;
@@ -510,7 +502,7 @@ int ScummEngine::findObject(int x, int y) {
 			continue;
 
 		if (_game.version == 0) {
-			if (_objs[i].flags == 0 && _objs[i].state & kObjectStateUntouchable)
+			if (_objs[i].obj_type == 0 && _objs[i].state & kObjectStateUntouchable)
 				continue;
 		} else {
 			if (_game.version <= 2 && _objs[i].state & kObjectStateUntouchable)
@@ -532,7 +524,7 @@ int ScummEngine::findObject(int x, int y) {
 				    _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].flags;
+						_v0ObjectFlag = _objs[i].obj_type;
 					if (_game.version == 0 && _v0ObjectIndex)
 						return i;
 					else
@@ -844,7 +836,7 @@ void ScummEngine_v3old::resetRoomObjects() {
 			char buf[32];
 			sprintf(buf, "roomobj-%d-", _roomResource);
 			if (_game.version == 0)
-				sprintf(buf + 11, "%d-", od->flags);
+				sprintf(buf + 11, "%d-", od->obj_type);
 
 			dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
 		}
@@ -912,7 +904,7 @@ void ScummEngine_v0::resetRoomObject(ObjectData *od, const byte *room, const byt
 	ptr -= 2;
 
 	od->obj_nr = *(ptr + 6);
-	od->flags = *(ptr + 7);
+	od->obj_type = *(ptr + 7);
 
 	od->x_pos = *(ptr + 8) * 8;
 	od->y_pos = ((*(ptr + 9)) & 0x7F) * 8;
@@ -1072,8 +1064,8 @@ void ScummEngine::updateObjectStates() {
 	int i;
 	ObjectData *od = &_objs[1];
 	for (i = 1; i < _numLocalObjects; i++, od++) {
-		// V0 MM, Room objects with Flag == 1 are objects with 'no-state' (room specific objects, non-pickup)
-		if (_game.version == 0 && od->flags == 1)
+		// V0 MM, objects with type == 1 are room objects (room specific objects, non-pickup)
+		if (_game.version == 0 && od->obj_type == 1)
 			continue;
 
 		if (od->obj_nr > 0)
diff --git a/engines/scumm/object.h b/engines/scumm/object.h
index cdf8b09..edbff38 100644
--- a/engines/scumm/object.h
+++ b/engines/scumm/object.h
@@ -62,7 +62,12 @@ struct ObjectData {
 	byte parentstate;
 	byte state;
 	byte fl_object_index;
-	byte flags;
+	// extra engine specific data
+	union {
+		byte extra;
+		byte obj_type; // v0
+		byte flags; // v8
+	};
 };
 
 #include "common/pack-start.h"	// START STRUCT PACKING
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 38dbd82..1713562 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -822,7 +822,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
 		MKLINE(ObjectData, parent, sleByte, VER(8)),
 		MKLINE(ObjectData, state, sleByte, VER(8)),
 		MKLINE(ObjectData, fl_object_index, sleByte, VER(8)),
-		MKLINE(ObjectData, flags, sleByte, VER(46)),
+		MKLINE(ObjectData, extra, sleByte, VER(46)),
 		MKEND()
 	};
 
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index cc59e60..07923de 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -79,7 +79,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0x22, o4_saveLoadGame);
 	OPCODE(0x23, o_stopCurrentScript);
 	/* 24 */
-	OPCODE(0x24, o_unknown2);
+	OPCODE(0x24, o_ifNotEqualActiveObject2);
 	OPCODE(0x25, o5_loadRoom);
 	OPCODE(0x26, o_getClosestObjActor);
 	OPCODE(0x27, o2_getActorY);
@@ -159,7 +159,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0x62, o2_stopScript);
 	OPCODE(0x63, o_stopCurrentScript);
 	/* 64 */
-	OPCODE(0x64, o_ifActiveObject);
+	OPCODE(0x64, o_ifEqualActiveObject2);
 	OPCODE(0x65, o_stopCurrentScript);
 	OPCODE(0x66, o_getClosestObjActor);
 	OPCODE(0x67, o5_getActorFacing);
@@ -239,7 +239,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0xa2, o4_saveLoadGame);
 	OPCODE(0xa3, o_stopCurrentScript);
 	/* A4 */
-	OPCODE(0xa4, o_unknown2);
+	OPCODE(0xa4, o_ifNotEqualActiveObject2);
 	OPCODE(0xa5, o5_loadRoom);
 	OPCODE(0xa6, o_stopCurrentScript);
 	OPCODE(0xa7, o2_getActorY);
@@ -319,7 +319,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0xe2, o2_stopScript);
 	OPCODE(0xe3, o_stopCurrentScript);
 	/* E4 */
-	OPCODE(0xe4, o_ifActiveObject);
+	OPCODE(0xe4, o_ifEqualActiveObject2);
 	OPCODE(0xe5, o_loadRoomWithEgo);
 	OPCODE(0xe6, o_stopCurrentScript);
 	OPCODE(0xe7, o5_getActorFacing);
@@ -406,130 +406,67 @@ void ScummEngine_v0::decodeParseString() {
 	actorTalk(buffer);
 }
 
-void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) {
+const byte *ScummEngine_v0::getObjectName(int object, int type) {
 	const byte *temp;
-	int sentencePrep = 0;
 
-	// If object not in inventory, we except an index
-	if (!objInInventory)
-		_v0ObjectIndex = true;
-	else
+	if (type == kObjectTypeInventory)
 		_v0ObjectInInventory = true;
 
 	temp = getObjOrActorName(object);
 
 	_v0ObjectInInventory = false;
-	_v0ObjectIndex = false;
 
-	// Append the 'object-name'
+	return temp;
+}
+
+void ScummEngine_v0::drawSentenceObject(int object, int type) {
+	const byte *temp;
+	temp = getObjectName(object, type);
 	if (temp) {
 		_sentenceBuf += " ";
 		_sentenceBuf += (const char *)temp;
 	}
-
-	// Append the modifier? (With / On / To / In)
-	if (!usePrep)
-		return;
-
-	if (_verbs[_activeVerb].prep == 0xFF) {
-		_v0ObjectInInventory = objInInventory;
-		sentencePrep = verbPrep(object);
-	} else {
-		sentencePrep = _verbs[_activeVerb].prep;
-	}
-
-	if (sentencePrep > 0 && sentencePrep <= 4) {
-		// The prepositions, like the fonts, were hard code in the engine. Thus
-		// we have to do that, too, and provde localized versions for all the
-		// languages MM/Zak are available in.
-		static const char *const prepositions[][5] = {
-			{ " ", " in", " with", " on", " to" },   // English
-			{ " ", " mit", " mit", " mit", " zu" },  // German
-			{ " ", " dans", " avec", " sur", " <" }, // French
-			{ " ", " in", " con", " su", " a" },     // Italian
-			{ " ", " en", " con", " en", " a" },     // Spanish
-			};
-		int lang;
-		switch (_language) {
-		case Common::DE_DEU:
-			lang = 1;
-			break;
-		case Common::FR_FRA:
-			lang = 2;
-			break;
-		case Common::IT_ITA:
-			lang = 3;
-			break;
-		case Common::ES_ESP:
-			lang = 4;
-			break;
-		default:
-			lang = 0;	// Default to english
-		}
-
-		_sentenceBuf += prepositions[lang][sentencePrep];
-	}
 }
 
 void ScummEngine_v0::drawSentence() {
 	Common::Rect sentenceline;
-	bool		 inventoryFirst = false;
 
 	if (!(_userState & 32))
 		return;
 
-	// Current Verb, Walk/Use
+	// Current Verb
+	if (_activeVerb == 0)
+		_activeVerb = 13;
 	if (getResourceAddress(rtVerb, _activeVerb)) {
 		_sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
 	} else {
 		return;
 	}
 
-	// If using inventory first, draw it first
-	if (_activeInvExecute && _activeInventory) {
-		drawSentenceWord(_activeInventory, true, true);
-	} else {
-		// Not using inventory, use selected object
-		if (_activeObject)
-			drawSentenceWord(_activeObjectIndex, true, false);
-		else
-			inventoryFirst = true;
-	}
-
-
-	// Draw the inventory?
-	if (_activeInventory > 0 && _activeObject2 == 0) {
-		// Only if inventory isnt first (it will already be drawn by now)
-		if (!_activeInvExecute) {
-			drawSentenceWord(_activeInventory, inventoryFirst, true);
-		} else {
-			// Draw the active object, which could be inventory based, or room based
-			if (_activeObject && !_activeObjectIndex) {
-				drawSentenceWord(_activeObject, inventoryFirst, true);
-			} else // Room based
-				drawSentenceWord(_activeObjectIndex, inventoryFirst, false);
-		}
-
-	// Draw the 2nd active object
-	} else if (_activeObject2) {
-
-		// 2nd Object is in inventory
-		if (_activeObject2Inv) {
-			_v0ObjectInInventory = true;
-			drawSentenceWord(_activeObject2, inventoryFirst, true);
-		} else {
-			drawSentenceWord(_activeObject2Index, inventoryFirst, false);
+	if (_activeObject) {
+		// Draw the 1st active object
+		drawSentenceObject(_activeObject, _activeObjectType);
+
+		// Append verb preposition
+		int sentencePrep = verbPrep();
+		if (sentencePrep) {
+			drawPreposition(sentencePrep);
+
+			// Draw the 2nd active object
+			if (_activeObject2) {
+				// 2nd Object is an actor
+				if (_activeObject2Type == kObjectTypeActor) {
+					Actor *a = derefActor(_activeObject2, "");
+					_sentenceBuf += " ";
+					_sentenceBuf += (const char *)a->getActorName();
+				// 2nd Object is an inventory or room object
+				} else {
+					drawSentenceObject(_activeObject2, _activeObject2Type);
+				}
+			}
 		}
 	}
 
-	// Draw the active actor
-	if (_activeActor) {
-		Actor *a = derefActor(_activeActor, "");
-
-		_sentenceBuf += " ";
-		_sentenceBuf += (const char *)a->getActorName();
-	}
-
 	_string[2].charset = 1;
 	_string[2].ypos = _virtscr[kVerbVirtScreen].topline;
 	_string[2].xpos = 0;
@@ -890,15 +827,21 @@ void ScummEngine_v0::o_doSentence() {
 	runObjectScript(obj, entry, false, false, NULL);
 }
 
-void ScummEngine_v0::o_unknown2() {
-	byte var1 = fetchScriptByte();
-	error("STUB: o_unknown2(%d)", var1);
+bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {
+	byte obj = fetchScriptByte();
+	if (!inventoryObject || (_activeObject2Type == kObjectTypeInventory))
+		return (obj == _activeObject2);
+	return false;
 }
 
-void ScummEngine_v0::o_ifActiveObject() {
-	byte obj = fetchScriptByte();
+void ScummEngine_v0::o_ifEqualActiveObject2() {
+	bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+	jumpRelative(equal);
+}
 
-	jumpRelative(obj == _activeInventory);
+void ScummEngine_v0::o_ifNotEqualActiveObject2() {
+	bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+	jumpRelative(!equal);
 }
 
 void ScummEngine_v0::o_getClosestObjActor() {
@@ -1004,19 +947,15 @@ void ScummEngine_v0::resetSentence(bool walking) {
 	// Then reset all active objects (stops the radio crash, bug #3077966)
 	if (!walking || !(_userState & 32)) {
 		_v0ObjectFlag = 0;
-		_activeInventory = 0;
 		_activeObject = 0;
 		_activeObject2 = 0;
-		_activeObjectIndex = 0;
-		_activeObject2Index = 0;
 	}
 
 	_verbExecuting = false;
 	_verbPickup = false;
 
-	_activeActor = 0;
-	_activeInvExecute = false;
-	_activeObject2Inv = false;
+	_activeObjectType = kObjectTypeRoom;
+	_activeObject2Type = kObjectTypeRoom;
 	_activeObjectObtained = false;
 	_activeObject2Obtained = false;
 }
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index edb046d..76f6b02 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -953,6 +953,41 @@ void ScummEngine_v2::o2_doSentence() {
 	}
 }
 
+void ScummEngine_v2::drawPreposition(int index) {
+		// The prepositions, like the fonts, were hard code in the engine. Thus
+		// we have to do that, too, and provde localized versions for all the
+		// languages MM/Zak are available in.
+		const char *prepositions[][5] = {
+			{ " ", " in", " with", " on", " to" },   // English
+			{ " ", " mit", " mit", " mit", " zu" },  // German
+			{ " ", " dans", " avec", " sur", " <" }, // French
+			{ " ", " in", " con", " su", " a" },     // Italian
+			{ " ", " en", " con", " en", " a" },     // Spanish
+			};
+		int lang;
+		switch (_language) {
+		case Common::DE_DEU:
+			lang = 1;
+			break;
+		case Common::FR_FRA:
+			lang = 2;
+			break;
+		case Common::IT_ITA:
+			lang = 3;
+			break;
+		case Common::ES_ESP:
+			lang = 4;
+			break;
+		default:
+			lang = 0;	// Default to english
+		}
+
+		if (_game.platform == Common::kPlatformNES) {
+			_sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
+		} else
+			_sentenceBuf += prepositions[lang][index];
+}
+
 void ScummEngine_v2::o2_drawSentence() {
 	Common::Rect sentenceline;
 	const byte *temp;
@@ -986,38 +1021,7 @@ void ScummEngine_v2::o2_drawSentence() {
 	}
 
 	if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) {
-		// The prepositions, like the fonts, were hard code in the engine. Thus
-		// we have to do that, too, and provde localized versions for all the
-		// languages MM/Zak are available in.
-		const char *prepositions[][5] = {
-			{ " ", " in", " with", " on", " to" },   // English
-			{ " ", " mit", " mit", " mit", " zu" },  // German
-			{ " ", " dans", " avec", " sur", " <" }, // French
-			{ " ", " in", " con", " su", " a" },     // Italian
-			{ " ", " en", " con", " en", " a" },     // Spanish
-			};
-		int lang;
-		switch (_language) {
-		case Common::DE_DEU:
-			lang = 1;
-			break;
-		case Common::FR_FRA:
-			lang = 2;
-			break;
-		case Common::IT_ITA:
-			lang = 3;
-			break;
-		case Common::ES_ESP:
-			lang = 4;
-			break;
-		default:
-			lang = 0;	// Default to english
-		}
-
-		if (_game.platform == Common::kPlatformNES) {
-			_sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
-		} else
-			_sentenceBuf += prepositions[lang][VAR(VAR_SENTENCE_PREPOSITION)];
+		drawPreposition(VAR(VAR_SENTENCE_PREPOSITION));
 	}
 
 	if (VAR(VAR_SENTENCE_OBJECT2) > 0) {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index d3cc218..d3dc702 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -701,10 +701,6 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
 
 	_inventoryOffset = 0;
 
-	_activeInventory = 0;
-	_activeObject = 0;
-	_activeVerb = 0;
-
 	VAR_SENTENCE_VERB = 0xFF;
 	VAR_SENTENCE_OBJECT1 = 0xFF;
 	VAR_SENTENCE_OBJECT2 = 0xFF;
@@ -723,11 +719,11 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
 	_verbPickup = false;
 	_currentMode = 0;
 
+	_activeVerb = 0;
+	_activeObject = 0;
 	_activeObject2 = 0;
-	_activeObjectIndex = 0;
-	_activeObject2Index = 0;
-	_activeInvExecute = false;
-	_activeObject2Inv = false;
+	_activeObjectType = kObjectTypeRoom;
+	_activeObject2Type = kObjectTypeRoom;
 	_activeObjectObtained = false;
 	_activeObject2Obtained = false;
 
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index af481df..d962994 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -32,21 +32,26 @@ namespace Scumm {
  */
 class ScummEngine_v0 : public ScummEngine_v2 {
 protected:
+	enum ObjectType {
+		kObjectTypeInventory = 0,
+		kObjectTypeRoom = 1,
+		kObjectTypeActor = 2
+	};
+
+protected:
 	byte _currentMode;
 	bool _verbExecuting;			// is a verb executing
 	bool _verbPickup;				// are we picking up an object during a verb execute
 
-	int _activeActor;				// Actor Number
+	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)
 
-	bool _activeInvExecute;			// is activeInventory first to be executed
-	bool _activeObject2Inv;			// is activeobject2 in the inventory
 	bool _activeObjectObtained;		// collected _activeobject?
 	bool _activeObject2Obtained;	// collected _activeObject2?
 
-	int _activeObjectIndex;
-	int _activeObject2Index;
-
 public:
 	ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
 
@@ -68,21 +73,21 @@ protected:
 	virtual void saveOrLoad(Serializer *s);
 
 	// V0 MM Verb commands
-	int  verbPrep(int object);
-	bool verbMove(int object, int objectIndex, bool invObject);
+	int  verbPrep();
+	bool verbMove(int object, bool invObject);
 	bool verbMoveToActor(int actor);
-	bool verbObtain(int object, int objIndex);
+	bool verbObtain(int object, int objType);
 	bool verbExecutes(int object, bool inventory = false);
 	bool verbExec();
 
-	int findObjectIndex(int x, int y);
-
 	virtual void checkExecVerbs();
 	virtual void handleMouseOver(bool updateInventory);
 	void resetVerbs();
 	void setNewKidVerbs();
 
-	void drawSentenceWord(int object, bool usePrep, bool objInInventory);
+	const byte *getObjectName(int object, int type);
+
+	void drawSentenceObject(int object, int type);
 	void drawSentence();
 
 	void switchActor(int slot);
@@ -96,6 +101,10 @@ protected:
 
 	virtual bool areBoxesNeighbors(int box1nr, int box2nr);
 
+	virtual void setActiveInventory(int object);
+
+	bool ifEqualActiveObject2Common(bool ignoreType);
+
 	/* Version C64 script opcodes */
 	void o_stopCurrentScript();
 	void o_loadSound();
@@ -123,8 +132,8 @@ protected:
 	void o_getBitVar();
 	void o_setBitVar();
 	void o_doSentence();
-	void o_unknown2();
-	void o_ifActiveObject();
+	void o_ifEqualActiveObject2();
+	void o_ifNotEqualActiveObject2();
 	void o_getClosestObjActor();
 	void o_printEgo_c64();
 	void o_print_c64();
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 47c5fa2..1f41283 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -44,10 +44,6 @@ protected:
 	Common::String _sentenceBuf;
 	uint16 _inventoryOffset;
 
-	int _activeInventory;
-	int _activeObject;
-	int _activeVerb;
-
 public:
 	ScummEngine_v2(OSystem *syst, const DetectorResult &dr);
 
@@ -100,6 +96,10 @@ protected:
 
 	virtual void setBuiltinCursor(int index);
 
+	void drawPreposition(int index);
+
+	virtual void setActiveInventory(int object);
+
 	/* Version 2 script opcodes */
 	void o2_actorFromPos();
 	void o2_actorOps();
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 3398cca..1bb0c0a 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -354,6 +354,15 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
 	}
 }
 
+void ScummEngine_v2::setActiveInventory(int object) {
+	runInputScript(kInventoryClickArea, object, 0);
+}
+
+void ScummEngine_v0::setActiveInventory(int object) {
+	// TODO
+	//_activeInventory = object;
+}
+
 void ScummEngine_v2::checkV2Inventory(int x, int y) {
 	int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
 	int object = 0;
@@ -385,15 +394,8 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
 		return;
 
 	object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-
-	if (object > 0) {
-		if (_game.version == 0) {
-			_activeInventory = object;
-
-		} else {
-			runInputScript(kInventoryClickArea, object, 0);
-		}
-	}
+	if (object > 0)
+		setActiveInventory(object);
 }
 
 void ScummEngine_v2::redrawV2Inventory() {
@@ -674,15 +676,8 @@ void ScummEngine_v2::checkExecVerbs() {
 
 		if (object != -1) {
 			object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-
-			if (object > 0) {
-				if (_game.version == 0) {
-					_activeInventory = object;
-
-				} else {
-					runInputScript(kInventoryClickArea, object, 0);
-				}
-			}
+			if (object > 0)
+				setActiveInventory(object);
 			return;
 		}
 
@@ -741,8 +736,11 @@ void ScummEngine_v0::runObject(int obj, int entry) {
 
 		// 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));
+			*/
 		}
 	}
 }
@@ -764,16 +762,14 @@ bool ScummEngine_v0::verbMoveToActor(int actor) {
 	return true;
 }
 
-bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
+bool ScummEngine_v0::verbMove(int object, bool invObject) {
 	int x, y, dir;
 	Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
 
 	if (_currentMode != 3 && _currentMode != 2)
 		return false;
 
-	_v0ObjectIndex = true;
-	getObjectXYPos(objectIndex, x, y, dir);
-	_v0ObjectIndex = false;
+	getObjectXYPos(object, x, y, dir);
 
 	// Detect distance from target object
 	int dist =  getDist(a->getRealPos().x, a->getRealPos().y, x, y);
@@ -789,17 +785,13 @@ bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
 	} else {
 		// Finished walk, are we picking up the item?
 		if (_verbPickup) {
-			int oldActive = _activeObject, oldIndex = _activeObjectIndex;
+			int oldActive = _activeObject;
 			_activeObject = object;
-			_activeObjectIndex = objectIndex;
 
-			_v0ObjectIndex = true;
 			// Execute pickup
-			runObject(objectIndex, 14);
-			_v0ObjectIndex = false;
+			runObject(object, 14);
 
 			_activeObject = oldActive;
-			_activeObjectIndex = oldIndex;
 
 			// Finished picking up
 			_verbPickup = false;
@@ -809,18 +801,19 @@ bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
 	return false;
 }
 
-bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
+bool ScummEngine_v0::verbObtain(int obj, int objType) {
 	bool didPickup = false;
+	int prep;
+	int where;
 
-	int prep, where = whereIsObjectInventory(obj);
-
-	if (objIndex == 0)
+	if (!obj)
 		return false;
 
+	where = whereIsObjectInventory(obj);
+
 	// Object in inventory ?
 	if (where != WIO_INVENTORY) {
-		_v0ObjectIndex = true;
-		prep = verbPrep(objIndex);
+		prep = verbPrep();
 
 		if (prep == 1 || prep == 4) {
 			if (_activeVerb != 13 && _activeVerb != 14) {
@@ -839,11 +832,13 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
 		}
 
 		//attempt move to object
-		if (verbMove(obj, objIndex, false))
+		if (verbMove(obj, false))
 			return true;
 
 		if (didPickup && (prep == 1 || prep == 4))
 			if (_activeVerb != 13 && _activeVerb != 14) {
+				// TODO
+				/*
 				_v0ObjectInInventory = true;
 
 				if (whereIsObject(obj) == WIO_INVENTORY)
@@ -852,27 +847,32 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
 					resetSentence(false);
 
 				_v0ObjectInInventory = false;
+				*/
 			}
 	}
 
 	return false;
 }
 
-int ScummEngine_v0::verbPrep(int object) {
-	if (!_v0ObjectInInventory)
-		_v0ObjectIndex = true;
-	else
-		_v0ObjectIndex = false;
+int ScummEngine_v0::verbPrep() {
+	if (_verbs[_activeVerb].prep != 0xFF) {
+		return _verbs[_activeVerb].prep;
+	} else {
+		if (!_v0ObjectInInventory)
+			_v0ObjectIndex = true;
+		else
+			_v0ObjectIndex = false;
 
-	byte *ptr = getOBCDFromObject(object);
-	_v0ObjectIndex = false;
-	assert(ptr);
-	return (*(ptr + 11) >> 5);
+		byte *ptr = getOBCDFromObject(_activeObject);
+		_v0ObjectIndex = false;
+		assert(ptr);
+		return (*(ptr + 11) >> 5);
+	}
 }
 
 bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
 	_v0ObjectInInventory = inventory;
-	int prep = verbPrep(object);
+	int prep = verbPrep();
 
 	if (prep == 2 || prep == 0) {
 		return true;
@@ -885,44 +885,34 @@ bool ScummEngine_v0::verbExec() {
 	int prep = 0;
 	int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
 
-	if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) {
+	if (_activeObject && getObjectIndex(_activeObject) == -1) {
 		resetSentence(false);
 		return false;
 	}
 
 	// Lets try walk to the object
-	if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) {
-		prep = verbPrep(_activeObjectIndex);
+	if (_activeObject && !_activeObjectObtained && _currentMode != 0) {
+		prep = verbPrep();
 
-		if (verbObtain(_activeObject, _activeObjectIndex))
+		if (verbObtain(_activeObject, _activeObjectType))
 			return true;
 
 		_activeObjectObtained = true;
 	}
 
 	// Attempt to obtain/reach object2
-	if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
-		prep = verbPrep(_activeObject2Index);
-
+	if (_activeObject2 && !_activeObject2Obtained && _currentMode != 0) {
 		_v0ObjectInInventory = false;
-		if (verbObtain(_activeObject2, _activeObject2Index))
+		if (verbObtain(_activeObject2, _activeObject2Type))
 			return true;
 
-		if (prep != 1 && prep != 4) {
-			_activeInventory = _activeObject;
-			_activeObject = _activeObject2;
-			_activeObjectIndex = _activeObject2Index;
-			_activeObject2 = 0;
-			_activeObject2Index = 0;
-		}
-
 		_activeObject2Obtained = true;
 	}
 
 	// Give-To
-	if (_activeVerb == 3 && _activeInventory && _activeActor) {
+	if (_activeVerb == 3 && _activeObject && _activeObject2 && _activeObject2Type == kObjectTypeActor) {
 		// FIXME: Actors need to turn and face each other
-		if (verbMoveToActor(_activeActor)) {
+		if (verbMoveToActor(_activeObject2)) {
 			// Ignore verbs?
 			Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
 			if (((ActorC64 *)a)->_miscflags & 0x40) {
@@ -933,8 +923,8 @@ bool ScummEngine_v0::verbExec() {
 			return true;
 		}
 		_v0ObjectInInventory = true;
-		VAR(VAR_ACTIVE_ACTOR) = _activeActor;
-		runObject(_activeInventory , 3);
+		VAR(VAR_ACTIVE_ACTOR) = _activeObject2;
+		runObject(_activeObject , 3);
 		_v0ObjectInInventory = false;
 
 		resetSentence(false);
@@ -942,10 +932,8 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// Where we performing an action on an actor?
-	if (_activeActor) {
-		_v0ObjectIndex = true;
-		runObject(_activeActor, entry);
-		_v0ObjectIndex = false;
+	if (_activeObject2 && _activeObject2Type == kObjectTypeActor) {
+		runObject(_activeObject2, entry);
 		_verbExecuting = false;
 
 		resetSentence(false);
@@ -953,10 +941,8 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// If we've finished walking (now near target), execute the action
-	if (_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) {
-		_v0ObjectIndex = true;
-		runObject(_activeObjectIndex, entry);
-		_v0ObjectIndex = false;
+	if (_activeObject && verbPrep() == 2) {
+		runObject(_activeObject, entry);
 		_verbExecuting = false;
 
 		if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
@@ -967,10 +953,9 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// We acted on an inventory item
-	if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) {
+	if (/*_activeInventory && verbExecutes(_activeInventory, true) &&*/ _activeVerb != 3) {
 		_v0ObjectInInventory = true;
-		_activeObject = _activeInventory;
-		runObject(_activeInventory, _activeVerb);
+		runObject(_activeObject/*2*/, _activeVerb);
 
 		_verbExecuting = false;
 
@@ -985,14 +970,13 @@ bool ScummEngine_v0::verbExec() {
 
 	// Item not in inventory is executed
 	if (_activeObject) {
-		_v0ObjectIndex = true;
-		runObject(_activeObjectIndex, entry);
-		_v0ObjectIndex = false;
-	} else if (_activeInventory) {
+		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 && _activeObject2Inv && verbExecutes(_activeObject2, true)) {
+			if (_activeObject2 && _activeObject2Type == kObjectTypeInventory && verbExecutes(_activeObject2, true)) {
 				_v0ObjectInInventory = true;
 
 				_activeObject = _activeInventory;
@@ -1013,6 +997,7 @@ bool ScummEngine_v0::verbExec() {
 			_v0ObjectInInventory = true;
 			runObject(_activeInventory, _activeVerb);
 		}
+#endif
 	}
 
 	_verbExecuting = false;
@@ -1060,9 +1045,7 @@ 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);
-		int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
 		_activeObject = obj;
-		_activeObjectIndex = objIdx;
 
 		if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK))
 			_activeVerb = 13;	// Walk-To
@@ -1080,11 +1063,13 @@ 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 || _activeInventory))
+			if ((_activeVerb == 3) && _activeObject)
 				return;
 
 			// Click into V2 inventory
@@ -1094,31 +1079,16 @@ void ScummEngine_v0::checkExecVerbs() {
 			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) {
-				_v0ObjectInInventory = true;
-				int prep = verbPrep(_activeInventory);
-				_v0ObjectInInventory = true;
-				int prep2 = verbPrep(prevInventory);
-
-				// Should the new inventory object remain as the secondary selected object
-				// Or should the new inventory object become primary?
-				if (prep != prep2 || prep != 1) {
-					if (prep == 1 || prep == 3) {
-						int tmp = _activeInventory;
-						_activeInventory = prevInventory;
-						prevInventory = tmp;
-					}
-				}
-
 				// Setup object2
 				_activeObject = 0;
-				_activeInvExecute = true;
-				_activeObject2Inv = true;
+				_activeObject2Type = kObjectTypeInventory;
 				_activeObject2 = _activeInventory;
 				_activeInventory = prevInventory;
 				return;
@@ -1132,14 +1102,14 @@ void ScummEngine_v0::checkExecVerbs() {
 			if (prevInventory != _activeInventory)
 				if (!_activeObject2 || prevInventory != _activeObject2)
 					return;
+#endif
 
-			if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2))
+			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);
-			int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
 
 			if (a->_miscflags & 0x80) {
 				if (_activeVerb != 7 && over != 7) {
@@ -1207,15 +1177,15 @@ void ScummEngine_v0::checkExecVerbs() {
 
 			// Only allowing targetting actors if its the GIVE verb
 			if (_activeVerb == 3) {
-				if (_activeObject || _activeInventory) {
+				if (_activeObject) {
 					// Once selected the object cannot be changed
 					obj = 0;
-					objIdx = 0;
 
 					// Different actor selected?
 					if (act) {
-						if (_activeActor != act) {
-							_activeActor = act;
+						if (_activeObject2 != act || _activeObject2Type != kObjectTypeActor) {
+							_activeObject2 = act;
+							_activeObject2Type = kObjectTypeActor;
 							return;
 						}
 					} else {
@@ -1230,24 +1200,15 @@ void ScummEngine_v0::checkExecVerbs() {
 			}
 
 			if (obj && obj != _activeObject) {
-				if (!_activeObject)
-					if (_activeInventory)
-						_activeInvExecute = true;
-
 				// USE / UNLOCK
 				if (_activeVerb == 11 || _activeVerb == 8) {
 					if (obj != _activeObject && obj != _activeObject2) {
-						if (_activeObject || _activeInventory) {
-							//verbPrep(
-						}
-						if (!_activeObject || _activeInventory) {
+						if (!_activeObject) {
 							_activeObject = obj;
-							_activeObjectIndex = objIdx;
 							return;
 						} else {
 							if (_activeObject2 != obj) {
 								_activeObject2 = obj;
-								_activeObject2Index = objIdx;
 								return;
 							}
 						}
@@ -1256,8 +1217,6 @@ void ScummEngine_v0::checkExecVerbs() {
 					a->stopActorMoving();
 
 					_activeObject = obj;
-					_activeObjectIndex = objIdx;
-
 					if (_activeVerb != 13)
 						return;
 


Commit: f296bf8d573c0ce8d4c5a828f5e9a634bcd5e0af
    https://github.com/scummvm/scummvm/commit/f296bf8d573c0ce8d4c5a828f5e9a634bcd5e0af
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:44-08:00

Commit Message:
SCUMM: fix ScummEngine_v0::o_stopCurrentScript()

Changed paths:
    engines/scumm/script_v0.cpp
    engines/scumm/script_v2.cpp
    engines/scumm/scumm_v2.h



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 07923de..2bbde61 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -501,14 +501,7 @@ void ScummEngine_v0::drawSentence() {
 }
 
 void ScummEngine_v0::o_stopCurrentScript() {
-	int script;
-
-	script = vm.slot[_currentScript].number;
-
-	if (_currentScript != 0 && vm.slot[_currentScript].number == script)
-		stopObjectCode();
-	else
-		stopScript(script);
+	stopScriptCommon(0);
 }
 
 void ScummEngine_v0::o_loadSound() {
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 76f6b02..003bafa 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1190,11 +1190,7 @@ void ScummEngine_v2::o2_startScript() {
 	runScript(script, 0, 0, 0);
 }
 
-void ScummEngine_v2::o2_stopScript() {
-	int script;
-
-	script = getVarOrDirectByte(PARAM_1);
-
+void ScummEngine_v2::stopScriptCommon(int script) {
 	if (_game.id == GID_MANIAC && _roomResource == 26 && vm.slot[_currentScript].number == 10001) {
 	// FIXME: Nasty hack for bug #915575
 	// Don't let the exit script for room 26 stop the script (116), when
@@ -1215,6 +1211,10 @@ void ScummEngine_v2::o2_stopScript() {
 		stopScript(script);
 }
 
+void ScummEngine_v2::o2_stopScript() {
+	stopScriptCommon(getVarOrDirectByte(PARAM_1));
+}
+
 void ScummEngine_v2::o2_panCameraTo() {
 	panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0);
 }
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 1f41283..a4da4fb 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -85,6 +85,7 @@ protected:
 	void ifNotStateCommon(byte type);
 	void setStateCommon(byte type);
 	void clearStateCommon(byte type);
+	void stopScriptCommon(int script);
 
 	virtual void resetSentence(bool walking);
 	void setUserState(byte state);


Commit: 8339e36b62270e0fe41e8c3c6f448c347ce8ca34
    https://github.com/scummvm/scummvm/commit/8339e36b62270e0fe41e8c3c6f448c347ce8ca34
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:45-08:00

Commit Message:
remove unneeded verbPrep() calls

Changed paths:
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 1bb0c0a..dc4a47a 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -882,7 +882,6 @@ bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
 }
 
 bool ScummEngine_v0::verbExec() {
-	int prep = 0;
 	int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
 
 	if (_activeObject && getObjectIndex(_activeObject) == -1) {
@@ -892,8 +891,6 @@ bool ScummEngine_v0::verbExec() {
 
 	// Lets try walk to the object
 	if (_activeObject && !_activeObjectObtained && _currentMode != 0) {
-		prep = verbPrep();
-
 		if (verbObtain(_activeObject, _activeObjectType))
 			return true;
 


Commit: 1f445a7b1dbaa80d361a3c7a59212880f298320c
    https://github.com/scummvm/scummvm/commit/1f445a7b1dbaa80d361a3c7a59212880f298320c
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:45-08:00

Commit Message:
- removed complicated and unnecessary _v0ObjectIndex, _v0ObjectInInventory, _v0ObjectFlag vars
- started to merge object id and type into one object value (type<<8|id)
- verb preposition ids do not dependent on language -> remove from VerbSettings

Note:
- objects with type=0 are foreground objects. They have a state, an owner and a bg overlay image.
- objects with type=1 are bg objects. They do not have a state or owner and are already contained in the bg image. The do not have an entry in objectState/OwnerTable

Changed paths:
    engines/scumm/object.cpp
    engines/scumm/object.h
    engines/scumm/script.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/script_v2.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index a9e2a76..53dc015 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 edbff38..7e4a5b5 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 37ea3a9..d04c3c0 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 2bbde61..14df89b 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 003bafa..1ea3257 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 d3dc702..423ad79b 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 d9237b2..f004176 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 d962994..0bb4d1a 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 dc4a47a..467b587 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) {


Commit: f8bca7003a6bdbad4a4e7620ad40c2778a2625ad
    https://github.com/scummvm/scummvm/commit/f8bca7003a6bdbad4a4e7620ad40c2778a2625ad
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:46-08:00

Commit Message:
selecting inventory objects and inventory scrolling works again

Changed paths:
    engines/scumm/scumm_v0.h
    engines/scumm/scumm_v2.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 0bb4d1a..460843c 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -108,8 +108,6 @@ protected:
 
 	virtual bool areBoxesNeighbors(int box1nr, int box2nr);
 
-	virtual void setActiveInventory(int object);
-
 	bool ifEqualActiveObject2Common(bool ignoreType);
 
 	/* Version C64 script opcodes */
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index a4da4fb..b9cd8a3 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -50,7 +50,7 @@ public:
 	virtual void resetScumm();
 
 	void checkV2MouseOver(Common::Point pos);
-	void checkV2Inventory(int x, int y);
+	int checkV2Inventory(int x, int y);
 	void redrawV2Inventory();
 
 protected:
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 467b587..2919858 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -389,19 +389,14 @@ void ScummEngine_v2::setActiveInventory(int object) {
 	runInputScript(kInventoryClickArea, object, 0);
 }
 
-void ScummEngine_v0::setActiveInventory(int object) {
-	// TODO
-	//_activeInventory = object;
-}
-
-void ScummEngine_v2::checkV2Inventory(int x, int y) {
+int ScummEngine_v2::checkV2Inventory(int x, int y) {
 	int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
 	int object = 0;
 
 	y -= _virtscr[kVerbVirtScreen].topline;
 
 	if ((y < inventoryArea) || !(_mouseAndKeyboardStat & MBS_LEFT_CLICK))
-		return;
+		return 0;
 
 	if (_mouseOverBoxesV2[kInventoryUpArrow].rect.contains(x, y)) {
 		if (_inventoryOffset >= 2) {
@@ -422,11 +417,9 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
 	}
 
 	if (object >= 4)
-		return;
+		return 0;
 
-	object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-	if (object > 0)
-		setActiveInventory(object);
+	return findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
 }
 
 void ScummEngine_v2::redrawV2Inventory() {
@@ -706,7 +699,7 @@ void ScummEngine_v2::checkExecVerbs() {
 		if (object != -1) {
 			object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
 			if (object > 0)
-				setActiveInventory(object);
+				runInputScript(kInventoryClickArea, object, 0);
 			return;
 		}
 
@@ -727,7 +720,9 @@ void ScummEngine_v2::checkExecVerbs() {
 			runInputScript(kSentenceClickArea, 0, 0);
 		} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) {
 			// Click into V2 inventory
-			checkV2Inventory(_mouse.x, _mouse.y);
+			int object = checkV2Inventory(_mouse.x, _mouse.y);
+			if (object > 0)
+				runInputScript(kInventoryClickArea, object, 0);
 		} else {
 			over = findVerbAtPos(_mouse.x, _mouse.y);
 			if (over != 0) {
@@ -1070,53 +1065,71 @@ void ScummEngine_v0::checkExecVerbs() {
 			_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;
-				}
+		if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
+			// TODO:  Check keypresses
+		} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
+			if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
+				// TODO: handle click into sentence line
 			} else {
-				//_activeVerbPrep:
-				// 0: no activeObject or activeObject but no prep
-				// > 0: activeObject + prep
-				if (activeVerbPrep() == 0) {
-					if (id == _activeObjectNr && type == _activeObjectType) {
-						_verbExecuting = true;
+				int obj = 0;
+
+				if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
+					// click into inventory
+					int invOff = _inventoryOffset;
+					obj = checkV2Inventory(_mouse.x, _mouse.y);
+					if (invOff != _inventoryOffset) {
+						// inventory position changed (arrows pressed, do nothing)
+						return;
+					}
+				} else if (zone->number == kMainVirtScreen) {
+					// click into main screen
+					if (_activeVerb == kVerbGive && _activeObjectNr) {
+						obj = OBJECT_V0(getActorFromPos(_virtualMouse.x, _virtualMouse.y), kObjectTypeActor);
 					} else {
-						_activeObjectNr = id;
-						_activeObjectType = type;
+						obj = findObject(_virtualMouse.x, _virtualMouse.y);
+					}
+				}
+
+				int id = OBJECT_V0_NR(obj);
+				int type = OBJECT_V0_TYPE(obj);
+				debug("found 0x%03x", obj);
+
+				if (!id) {
+					if (_activeVerb == kVerbWalkTo) {
+						_activeObjectNr = 0;
+						_activeObject2Nr = 0;
 					}
-					//sentenceLineChanged = true;
-					if (_currentMode == 1)
-						_verbExecuting = true;
 				} else {
-					if (id == _activeObject2Nr && type == _activeObject2Type)
-						_verbExecuting = true;
-					if (!(id == _activeObjectNr && type == _activeObjectType)) {
-						_activeObject2Nr = id;
-						_activeObject2Type = type;
+					//_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;
+				sentenceLineChanged = true;
+				if (_activeVerb == kVerbWalkTo) {
+					scriptUpdateSkip = 0;
+					_verbExecuting = true;
+				}
 			}
 		}
 	}
@@ -1184,29 +1197,7 @@ void ScummEngine_v0::checkExecVerbs() {
 		}
 	}
 
-	if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
-		return;
-
-	if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
-		/* Check keypresses */
-		// TODO
-	} else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
-		if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
-			// TODO
-		} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
-			int invOff = _inventoryOffset;
-
-			// Click into V2 inventory
-			checkV2Inventory(_mouse.x, _mouse.y);
-
-			// Did the Inventory position changed (arrows pressed, do nothing)
-			if (invOff != _inventoryOffset)
-				return;
-		} else {
-			int over = findVerbAtPos(_mouse.x, _mouse.y);
-			int act  = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
-			int obj  = findObject(_virtualMouse.x, _virtualMouse.y);
-
+	...
 
 			// Clicked on nothing, walk here?
 			if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {


Commit: 71617abc29e300b94ba96d73648da5ff3aa867e7
    https://github.com/scummvm/scummvm/commit/71617abc29e300b94ba96d73648da5ff3aa867e7
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:46-08:00

Commit Message:
use constants for c64 actor miscflags

Changed paths:
    engines/scumm/actor.h
    engines/scumm/script_v0.cpp
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 1584d0a..d8e3692 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -335,10 +335,21 @@ protected:
 	virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
 };
 
+enum ActorC64MiscFlags {
+	kActorMiscFlagStrong   = 0x01, // Kid is strong (Hunk-O-Matic used)
+	kActorMiscFlag_02      = 0x02, // ???
+	kActorMiscFlag_04      = 0x04, // ???
+	kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend
+	kActorMiscFlag_10      = 0x10, // ???
+	kActorMiscFlag_20      = 0x20, // ???
+	kActorMiscFlagFreeze   = 0x40, // Stop moving
+	kActorMiscFlagHide     = 0x80, // Hide actor (e.g. dead or wearing radiation suit)
+};
+
 class ActorC64 : public Actor_v2 {
 public:
 	byte _costCommand, _costFrame;
-	byte _miscflags; // 0x1: strong, 0x8: Ed's enemy, 0x40: stop moving, 0x80: hide(dead/radiation suit)
+	byte _miscflags;
 	byte _speaking, _speakingPrev;
 
 public:
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 14df89b..0f9fbc6 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -542,16 +542,16 @@ void ScummEngine_v0::o_loadRoom() {
 }
 
 void ScummEngine_v0::o_loadRoomWithEgo() {
-	Actor *a;
+	ActorC64 *a;
 	int obj, room, x, y, dir;
 
 	obj = fetchScriptByte();
 	room = fetchScriptByte();
 
-	a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
+	a = (ActorC64 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
 
 	//0x634F
-	if (((ActorC64 *)a)->_miscflags & 0x40) {
+	if (a->_miscflags & kActorMiscFlagFreeze) {
 		// TODO: Check if this is the correct function
 		// to be calling here
 		stopObjectCode();
@@ -734,9 +734,9 @@ void ScummEngine_v0::o_setActorBitVar() {
 		a->_miscflags &= ~mask;
 
 	// This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!')
-	if (a->_miscflags & 0x40)
+	if (a->_miscflags & kActorMiscFlagFreeze)
 		a->stopActorMoving();
-	if (a->_miscflags & 0x80)
+	if (a->_miscflags & kActorMiscFlagHide)
 		a->setActorCostume(0);
 
 	debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 2919858..3d0abae 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -847,8 +847,8 @@ bool ScummEngine_v0::verbObtain(int obj) {
 		}
 
 		// Ignore verbs?
-		Actor *a = derefActor(VAR(VAR_EGO), "verbObtain");
-		if (((ActorC64 *)a)->_miscflags & 0x40) {
+		ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbObtain");
+		if (a->_miscflags & kActorMiscFlagFreeze) {
 			resetSentence(false);
 			return false;
 		}
@@ -918,7 +918,7 @@ bool ScummEngine_v0::verbExec() {
 		if (verbMoveToActor(_activeObject2Nr)) {
 			// Ignore verbs?
 			Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
-			if (((ActorC64 *)a)->_miscflags & 0x40) {
+			if (((ActorC64 *)a)->_miscflags & kActorMiscFlagFreeze) {
 				resetSentence(false);
 				return false;
 			}
@@ -1052,7 +1052,7 @@ void ScummEngine_v0::checkExecVerbs() {
 		}
 	}
 
-	if (a->_miscflags & 0x80) {
+	if (a->_miscflags & kActorMiscFlagHide) {
 		if (_activeVerb != kVerbNewKid) {
 			_activeVerb = kVerbNone;
 		}
@@ -1210,7 +1210,7 @@ void ScummEngine_v0::checkExecVerbs() {
 
 				if (zone->number == kMainVirtScreen) {
 					// Ignore verbs?
-					if (a->_miscflags & 0x40) {
+					if (a->_miscflags & kActorMiscFlagFreeze) {
 						resetSentence(false);
 						return;
 					}


Commit: ed67d548407ecb1534a606bbb23fed469636a777
    https://github.com/scummvm/scummvm/commit/ed67d548407ecb1534a606bbb23fed469636a777
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:46-08:00

Commit Message:
replace verb, prep and currentMode values with symbolic constants

Changed paths:
    engines/scumm/script_v0.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp
    engines/scumm/verbs.h



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 0f9fbc6..31363ed 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -422,8 +422,8 @@ void ScummEngine_v0::drawSentence() {
 		return;
 
 	// Current Verb
-	if (_activeVerb == 0)
-		_activeVerb = 13;
+	if (_activeVerb == kVerbNone)
+		_activeVerb = kVerbWalkTo;
 	if (getResourceAddress(rtVerb, _activeVerb)) {
 		_sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
 	} else {
@@ -602,15 +602,15 @@ void ScummEngine_v0::o_cursorCommand() {
 
 	_currentMode = fetchScriptByte();
 	switch (_currentMode) {
-	case 0:
+	case kModeCutscene:
 		state = 15;
 		break;
-	case 1:
+	case kModeKeypad:
 		state = 31;
 		break;
-	case 2:
+	case kModeNoNewKid:
 		break;
-	case 3:
+	case kModeNormal:
 		state = 247;
 		break;
 	}
@@ -908,7 +908,7 @@ void ScummEngine_v0::o_setOwnerOf() {
 }
 
 void ScummEngine_v0::resetSentence(bool walking) {
-	_activeVerb = 13;
+	_activeVerb = kVerbWalkTo;
 
 	// 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)
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 423ad79b..8b2e2ef 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -716,7 +716,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
 	_verbPickup = false;
 	_currentMode = 0;
 
-	_activeVerb = 0;
+	_activeVerb = kVerbNone;
 	_activeObjectNr = 0;
 	_activeObject2Nr = 0;
 	_activeObjectType = kObjectTypeBG;
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 460843c..2c8c1c8 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -32,6 +32,13 @@ namespace Scumm {
  */
 class ScummEngine_v0 : public ScummEngine_v2 {
 protected:
+	enum CurrentMode {
+		kModeCutscene = 0,   // cutscene active
+		kModeKeypad = 1,     // kid selection / dial pad / save-load dialog
+		kModeNoNewKid = 2,   // verb "new kid" disabled (e.g. when entering lab)
+		kModeNormal = 3,     // normal playing mode
+	};
+
 	enum ObjectType {
 		kObjectTypeFG = 0,    // foreground object
 		                      //   - with owner/state, might (but has not to) be pickupable
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 3d0abae..03acdda 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -37,25 +37,6 @@ 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;
@@ -103,13 +84,13 @@ static const VerbSettings v0VerbTable_German[] = {
 int ScummEngine_v0::verbPrepIdType(int verbid) {
 	switch (verbid) {
 	case kVerbUse: // depends on object1
-		return 0xFF;
+		return kVerbPrepObject;
 	case kVerbGive: 
-		return 4;
+		return kVerbPrepTo;
 	case kVerbUnlock: case kVerbFix:
-		return 2;
+		return kVerbPrepWith;
 	default:
-		return 0;
+		return kVerbPrepNone;
 	}
 }
 
@@ -192,7 +173,7 @@ void ScummEngine_v0::switchActor(int slot) {
 		return;
 
 	// verbs disabled? or just new kid button?
-	if (_currentMode == 0 || _currentMode == 1 || _currentMode == 2)
+	if (_currentMode == kModeCutscene || _currentMode == kModeKeypad || _currentMode == kModeNoNewKid)
 		return;
 
 	VAR(VAR_EGO) = VAR(97 + slot);
@@ -785,7 +766,7 @@ bool ScummEngine_v0::verbMove(int object, bool invObject) {
 	int x, y, dir;
 	Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
 
-	if (_currentMode != 3 && _currentMode != 2)
+	if (_currentMode != kModeNormal && _currentMode != kModeNoNewKid)
 		return false;
 
 	getObjectXYPos(object, x, y, dir);
@@ -837,8 +818,8 @@ bool ScummEngine_v0::verbObtain(int obj) {
 	if (where != WIO_INVENTORY) {
 		prep = activeVerbPrep();
 
-		if (prep == 1 || prep == 4) {
-			if (_activeVerb != 13 && _activeVerb != 14) {
+		if (prep == kVerbPrepIn || prep == kVerbPrepTo) {
+			if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
 				_verbPickup = true;
 				didPickup = true;
 			}
@@ -857,8 +838,8 @@ bool ScummEngine_v0::verbObtain(int obj) {
 		if (verbMove(obj, false))
 			return true;
 
-		if (didPickup && (prep == 1 || prep == 4))
-			if (_activeVerb != 13 && _activeVerb != 14) {
+		if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo))
+			if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
 // TODO(TOBIAS)
 #if 0
 				if (whereIsObject(obj) == WIO_INVENTORY)
@@ -889,7 +870,7 @@ int ScummEngine_v0::activeVerbPrep() {
 }
 
 bool ScummEngine_v0::verbExec() {
-	int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
+	int entry = (_currentMode != kModeCutscene && _currentMode != kModeKeypad) ? _activeVerb : kVerbWhatIs;
 
 	if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) {
 		resetSentence(false);
@@ -897,7 +878,7 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// Lets try walk to the object
-	if (_activeObjectNr && !_activeObjectObtained && _currentMode != 0) {
+	if (_activeObjectNr && !_activeObjectObtained && _currentMode != kModeCutscene) {
 		if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType)))
 			return true;
 
@@ -905,7 +886,7 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// Attempt to obtain/reach object2
-	if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != 0) {
+	if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != kModeCutscene) {
 		if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type)))
 			return true;
 
@@ -913,7 +894,7 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// Give-To
-	if (_activeVerb == 3 && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
+	if (_activeVerb == kVerbGive && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
 		// FIXME: Actors need to turn and face each other
 		if (verbMoveToActor(_activeObject2Nr)) {
 			// Ignore verbs?
@@ -942,11 +923,11 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// If we've finished walking (now near target), execute the action
-	if (_activeObjectNr && activeVerbPrep() == 2) {
+	if (_activeObjectNr && activeVerbPrep() == kVerbPrepWith) {
 		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
 		_verbExecuting = false;
 
-		if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
+		if ((_currentMode == kModeNormal || _currentMode == kModeNoNewKid) && _activeVerb == kVerbWalkTo)
 			return false;
 
 		resetSentence(false);
@@ -954,12 +935,12 @@ bool ScummEngine_v0::verbExec() {
 	}
 
 	// We acted on an inventory item
-	if (_activeVerb != 3) {
+	if (_activeVerb != kVerbGive) {
 		runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb);
 
 		_verbExecuting = false;
 
-		if (_currentMode == 3 && _activeVerb == 13) {
+		if (_currentMode == kModeNormal && _activeVerb == kVerbWalkTo) {
 			resetSentence(true);
 			return false;
 		}
@@ -974,7 +955,7 @@ bool ScummEngine_v0::verbExec() {
 
 	_verbExecuting = false;
 
-	if (_activeVerb == 13) {
+	if (_activeVerb == kVerbWalkTo) {
 		resetSentence(true);
 		return false;
 	}
@@ -1058,10 +1039,8 @@ void ScummEngine_v0::checkExecVerbs() {
 		}
 	}
 
-	// mode 1: kid selection, 3: normal
-	if (_currentMode != 0) {
-		if (_currentMode == 1) {
-			// kid selection or dial pad
+	if (_currentMode != kModeCutscene) {
+		if (_currentMode == kModeKeypad) {
 			_activeVerb = kVerbPush;
 		}
 
@@ -1097,13 +1076,15 @@ void ScummEngine_v0::checkExecVerbs() {
 				if (!id) {
 					if (_activeVerb == kVerbWalkTo) {
 						_activeObjectNr = 0;
+						_activeObjectType = 0;
 						_activeObject2Nr = 0;
+						_activeObject2Type = 0;
 					}
 				} else {
 					//_activeVerbPrep:
 					// 0: no activeObject or activeObject but no prep
 					// > 0: activeObject + prep
-					if (activeVerbPrep() == 0) {
+					if (activeVerbPrep() == kVerbPrepNone) {
 						if (id == _activeObjectNr && type == _activeObjectType) {
 							_verbExecuting = true;
 						} else {
@@ -1111,7 +1092,7 @@ void ScummEngine_v0::checkExecVerbs() {
 							_activeObjectType = type;
 						}
 						//sentenceLineChanged = true;
-						if (_currentMode == 1)
+						if (_currentMode == kModeKeypad)
 							_verbExecuting = true;
 					} else {
 						if (id == _activeObject2Nr && type == _activeObject2Type)
@@ -1119,7 +1100,7 @@ void ScummEngine_v0::checkExecVerbs() {
 						if (!(id == _activeObjectNr && type == _activeObjectType)) {
 							_activeObject2Nr = id;
 							_activeObject2Type = type;
-							if (_currentMode == 1)
+							if (_currentMode == kModeKeypad)
 								_verbExecuting = true;
 						}
 					}
@@ -1139,7 +1120,7 @@ void ScummEngine_v0::checkExecVerbs() {
 
 	if (_activeVerb == kVerbNewKid) {
 		// TODO
-		if (_currentMode == 3) {
+		if (_currentMode == kModeNormal) {
 			// get kid
 			_activeVerb = kVerbWalkTo;
 			resetSentence(false);
@@ -1155,7 +1136,7 @@ void ScummEngine_v0::checkExecVerbs() {
 	/*
 	if (_activeVerbPrep == 0) {
 		int prep = activeVerbPrep();
-		if (prep == 0)
+		if (prep == kVerbPrepNone)
 			; //exec();
 		else {
 			_activeVerbPrep = prep;
@@ -1200,7 +1181,7 @@ void ScummEngine_v0::checkExecVerbs() {
 	...
 
 			// Clicked on nothing, walk here?
-			if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {
+			if (!over && !act && _activeVerb == kVerbWalkTo && !obj && _currentMode != kMode_0) {
 				// Clear all selected
 				resetSentence(false);
 
diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h
index fb4dc96..fce260e 100644
--- a/engines/scumm/verbs.h
+++ b/engines/scumm/verbs.h
@@ -57,6 +57,34 @@ struct VerbSlot {
 	uint16 imgindex;
 };
 
+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
+};
+
+enum VerbPrepsV0 {
+	kVerbPrepNone   = 0,
+	kVerbPrepIn     = 1,
+	kVerbPrepWith   = 2,
+	kVerbPrepOn     = 3,
+	kVerbPrepTo     = 4,
+	kVerbPrepObject = 0xFF, // prep depends on object (USE)
+};
+
 } // End of namespace Scumm
 
 #endif


Commit: fffcce269921748197005372545dc9db2f89a744
    https://github.com/scummvm/scummvm/commit/fffcce269921748197005372545dc9db2f89a744
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:47-08:00

Commit Message:
cleanup

Changed paths:
    engines/scumm/script_v0.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 31363ed..9b39391 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -406,9 +406,9 @@ void ScummEngine_v0::decodeParseString() {
 	actorTalk(buffer);
 }
 
-void ScummEngine_v0::drawSentenceObject(int object, int type) {
+void ScummEngine_v0::drawSentenceObject(int object) {
 	const byte *temp;
-	temp = getObjOrActorName(OBJECT_V0(object, type));
+	temp = getObjOrActorName(object);
 	if (temp) {
 		_sentenceBuf += " ";
 		_sentenceBuf += (const char *)temp;
@@ -432,7 +432,7 @@ void ScummEngine_v0::drawSentence() {
 
 	if (_activeObjectNr) {
 		// Draw the 1st active object
-		drawSentenceObject(_activeObjectNr, _activeObjectType);
+		drawSentenceObject(OBJECT_V0(_activeObjectNr, _activeObjectType));
 
 		// Append verb preposition
 		int sentencePrep = activeVerbPrep();
@@ -448,7 +448,7 @@ void ScummEngine_v0::drawSentence() {
 					_sentenceBuf += (const char *)a->getActorName();
 				// 2nd Object is an inventory or room object
 				} else {
-					drawSentenceObject(_activeObject2Nr, _activeObject2Type);
+					drawSentenceObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type));
 				}
 			}
 		}
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 2c8c1c8..9b38b10 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -89,10 +89,9 @@ protected:
 	// V0 MM Verb commands
 	int getVerbPrepId();
 	int activeVerbPrep();
-	bool verbMove(int object, bool invObject);
+	bool verbMove(int object);
 	bool verbMoveToActor(int actor);
 	bool verbObtain(int object);
-	bool verbExecutes(int object, bool inventory = false);
 	bool verbExec();
 
 	virtual void checkExecVerbs();
@@ -101,7 +100,7 @@ protected:
 	void resetVerbs();
 	void setNewKidVerbs();
 
-	void drawSentenceObject(int object, int type);
+	void drawSentenceObject(int object);
 	void drawSentence();
 
 	void switchActor(int slot);
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 03acdda..016248c 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -762,7 +762,7 @@ bool ScummEngine_v0::verbMoveToActor(int actor) {
 	return true;
 }
 
-bool ScummEngine_v0::verbMove(int object, bool invObject) {
+bool ScummEngine_v0::verbMove(int object) {
 	int x, y, dir;
 	Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
 
@@ -835,7 +835,7 @@ bool ScummEngine_v0::verbObtain(int obj) {
 		}
 
 		//attempt move to object
-		if (verbMove(obj, false))
+		if (verbMove(obj))
 			return true;
 
 		if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo))


Commit: b265f4ad8226cc0b76ecb19b285d81c0ed820cfc
    https://github.com/scummvm/scummvm/commit/b265f4ad8226cc0b76ecb19b285d81c0ed820cfc
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:47-08:00

Commit Message:
- MM C64 uses command stack (SentenceTab, doSentence()) now
- _cmdObject... added for current SentenceTab. The _active... variables are only used to build a sentence in the inventory but never by a script.
-> many routines are not needed anymore and are removed

Changed paths:
    engines/scumm/object.cpp
    engines/scumm/script.cpp
    engines/scumm/script_v0.cpp
    engines/scumm/script_v2.cpp
    engines/scumm/script_v5.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v0.h
    engines/scumm/scumm_v2.h
    engines/scumm/scumm_v5.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 53dc015..49f1777 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -434,8 +434,15 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
 			y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
 		}
 	} else if (_game.version <= 2) {
-		x = od.walk_x >> V12_X_SHIFT;
-		y = od.walk_y >> V12_Y_SHIFT;
+		if (od.actordir) {
+			x = od.walk_x;
+			y = od.walk_y;
+		} else {
+			x = od.x_pos + od.width/2;
+			y = od.y_pos + od.height/2;
+		}
+		x = x >> V12_X_SHIFT;
+		y = y >> V12_Y_SHIFT;
 	} else {
 		x = od.walk_x;
 		y = od.walk_y;
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index d04c3c0..0864022 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -28,6 +28,7 @@
 #include "scumm/object.h"
 #include "scumm/resource.h"
 #include "scumm/util.h"
+#include "scumm/scumm_v0.h"
 #include "scumm/scumm_v2.h"
 #include "scumm/sound.h"
 #include "scumm/verbs.h"
@@ -194,9 +195,14 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
 		return verboffs + 8 + READ_LE_UINT32(ptr + 1);
 	} else if (_game.version <= 2) {
 		do {
-			if (!*verbptr)
-				return 0;
-			if (*verbptr == entry || *verbptr == 0xFF)
+			const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF);
+			if (!*verbptr) {
+				if (_game.version == 0 && entry == kVerbWalkTo)
+					return 13;
+				else
+					return 0;
+			}
+			if (*verbptr == entry || *verbptr == kFallbackEntry)
 				break;
 			verbptr += 2;
 		} while (1);
@@ -1128,6 +1134,130 @@ void ScummEngine::checkAndRunSentenceScript() {
 		runScript(sentenceScript, 0, 0, localParamList);
 }
 
+void ScummEngine_v0::walkToActorOrObject(int object) {
+	int x, y, dir;
+	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject");
+
+	_walkToObject = object;
+	_walkToObjectIdx = getObjectIndex(object);
+
+	if (OBJECT_V0_TYPE(object) == kObjectTypeActor) {
+		walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4);
+		x = a->getRealPos().x;
+		y = a->getRealPos().y;
+	} else {
+		walkActorToObject(VAR(VAR_EGO), object);
+		getObjectXYPos(object, x, y, dir);
+	}
+
+	VAR(6) = x;
+	VAR(7) = y;
+
+	if (!(a->_miscflags & kActorMiscFlagFreeze)) {
+		// FIXME: walking already started -> should be stopped if condition not true
+		//actorStartWalk();
+	}
+}
+
+void ScummEngine_v0::checkAndRunSentenceScript() {
+	const ScriptSlot *ss;
+
+	if (_walkToObjectIdx) {
+		ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript");
+		if (a->_moving)
+			return;
+		// TODO: change actor facing
+		_walkToObjectIdx = 0;
+		runSentenceScript();
+		return;
+	}
+
+	if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
+		return;
+
+	//_sentenceNum--;
+	SentenceTab &st = _sentence[_sentenceNum - 1];
+
+	if (st.preposition && st.objectB == st.objectA)
+		return;
+
+	// FIXME: should this be executed?
+	//_currentScript = 0xFF;
+
+	int obj1Nr = OBJECT_V0_NR(st.objectA);
+	int obj1Type = OBJECT_V0_TYPE(st.objectA);
+	int obj2Nr = OBJECT_V0_NR(st.objectB);
+	int obj2Type = OBJECT_V0_TYPE(st.objectB);
+	assert(obj1Nr);
+
+	// If two objects are involved, at least one must be in the actors inventory
+	if (obj2Nr &&
+		(obj1Type != kObjectTypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) &&
+	    (obj2Type != kObjectTypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO)))
+	{
+		if (getVerbEntrypoint(st.objectA, kVerbPickUp))
+			doSentence(kVerbPickUp, st.objectA, 0);
+		else if (getVerbEntrypoint(st.objectB, kVerbPickUp))
+			doSentence(kVerbPickUp, st.objectB, 0);
+		else
+			_sentenceNum--;
+		return;
+	}
+
+	_cmdVerb = st.verb;
+	_cmdObjectNr = obj1Nr;
+	_cmdObjectType = obj1Type;
+	_cmdObject2Nr = obj2Nr;
+	_cmdObject2Type = obj2Type;
+	_sentenceNum--;
+
+	// TODO: check sentenceNum
+
+	if (whereIsObject(st.objectA) != WIO_INVENTORY) {
+		if (_currentMode != kModeKeypad) {
+			walkToActorOrObject(st.objectA);
+			return;
+		}
+	} else if (st.objectB && whereIsObject(st.objectB) != WIO_INVENTORY) {
+		walkToActorOrObject(st.objectB);
+		return;
+	}
+
+	runSentenceScript();
+	if (_currentMode == kModeKeypad) {
+		_walkToObjectIdx = 0;
+	}
+}
+
+void ScummEngine_v0::runSentenceScript() {
+	int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+
+	// FIXME: should it really ever return 0xD on WalkTo, seems wrong?
+	if (getVerbEntrypoint(obj, _cmdVerb) != 0) {
+		if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) {
+			//slot = 0xFF;
+			VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+			runScript(3, 0, 0, 0);
+			return;
+		} else {
+			VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr;
+			runObjectScript(obj, _cmdVerb, false, false, NULL);
+			return;
+		}
+	} else {
+		if (_cmdVerb == kVerbGive) {
+			if (_cmdObject2Nr < 8)
+				setOwnerOf(obj, _cmdObject2Nr);
+			return;
+		} else if (_cmdVerb == kVerbWalkTo) {
+			//slot = 0xFF;
+			VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+			runScript(3, 0, 0, 0);
+			return;
+		}
+	}
+}
+
 void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) {
 	int args[24];
 	int verbScript;
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 9b39391..f4b98a4 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -177,7 +177,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0x70, o_lights);
 	OPCODE(0x71, o_getBitVar);
 	OPCODE(0x72, o_nop);
-	OPCODE(0x73, o5_getObjectOwner);
+	OPCODE(0x73, o_getObjectOwner);
 	/* 74 */
 	OPCODE(0x74, o5_getDist);
 	OPCODE(0x75, o_printEgo_c64);
@@ -337,7 +337,7 @@ void ScummEngine_v0::setupOpcodes() {
 	OPCODE(0xf0, o_lights);
 	OPCODE(0xf1, o_getBitVar);
 	OPCODE(0xf2, o_nop);
-	OPCODE(0xf3, o5_getObjectOwner);
+	OPCODE(0xf3, o_getObjectOwner);
 	/* F4 */
 	OPCODE(0xf4, o5_getDist);
 	OPCODE(0xf5, o_stopCurrentScript);
@@ -365,7 +365,7 @@ uint ScummEngine_v0::fetchScriptWord() {
 
 int ScummEngine_v0::getActiveObject() {
 	if (_opcode & PARAM_2)
-		return _activeObjectNr;
+		return _cmdObjectNr;
 
 	return fetchScriptByte();
 }
@@ -693,7 +693,7 @@ void ScummEngine_v0::o_putActorAtObject() {
 
 void ScummEngine_v0::o_pickupObject() {
 	int objNr = fetchScriptByte();
-	int obj = OBJECT_V0((objNr ? objNr : _activeObjectNr), 0);
+	int obj = OBJECT_V0((objNr ? objNr : _cmdObjectNr), 0);
 
 	/* Don't take an object twice */
 	if (whereIsObject(obj) == WIO_INVENTORY)
@@ -742,6 +742,12 @@ void ScummEngine_v0::o_setActorBitVar() {
 	debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
 }
 
+void ScummEngine_v0::o_getObjectOwner() {
+	getResultPos();
+	int obj = getVarOrDirectWord(PARAM_1);
+	setResult(getOwner(obj ? obj : _cmdObjectNr));
+}
+
 void ScummEngine_v0::o_getActorBitVar() {
 	getResultPos();
 	byte act = getVarOrDirectByte(PARAM_1);
@@ -787,17 +793,35 @@ void ScummEngine_v0::o_printEgo_c64() {
 }
 
 void ScummEngine_v0::o_doSentence() {
-	byte entry = fetchScriptByte();
-	byte obj = fetchScriptByte();
-	fetchScriptByte();
+	byte verb = fetchScriptByte();
+	int obj, obj2;
+	byte b;
+
+	b = fetchScriptByte();
+	if (b == 0xFF) {
+		obj = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type);
+	} else if (b == 0xFE) {
+		obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+	} else {
+		obj = OBJECT_V0(b, (_opcode & 0x80) ? 1 : 0);
+	}
 
-	runObjectScript(obj, entry, false, false, NULL);
+	b = fetchScriptByte();
+	if (b == 0xFF) {
+		obj2 = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type);
+	} else if (b == 0xFE) {
+		obj2 = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+	} else {
+		obj2 = OBJECT_V0(b, (_opcode & 0x40) ? 1 : 0);
+	}
+
+	doSentence(verb, obj, obj2);
 }
 
-bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) {
+bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) {
 	byte obj = fetchScriptByte();
-	if (!inventoryObject || (_activeObject2Type == kObjectTypeFG))
-		return (obj == _activeObject2Nr);
+	if (!ignoreType || (_cmdObject2Type == kObjectTypeFG))
+		return (obj == _cmdObject2Nr);
 	return false;
 }
 
@@ -894,7 +918,7 @@ void ScummEngine_v0::o_setOwnerOf() {
 	owner = getVarOrDirectByte(PARAM_2);
 
 	if (obj == 0)
-		obj = _activeObjectNr;
+		obj = _cmdObjectNr;
 
 	// FIXME: the original interpreter seems to set the owner of 
 	// an item to remove (new owner 0) to 13 (purple tentacle).
@@ -909,21 +933,11 @@ void ScummEngine_v0::o_setOwnerOf() {
 
 void ScummEngine_v0::resetSentence(bool walking) {
 	_activeVerb = kVerbWalkTo;
-
-	// 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)) {
-		_activeObjectNr = 0;
-		_activeObjectType = kObjectTypeBG;
-		_activeObject2Nr = 0;
-		_activeObject2Type = kObjectTypeBG;
-	}
-
-	_verbExecuting = false;
-	_verbPickup = false;
-
-	_activeObjectObtained = false;
-	_activeObject2Obtained = false;
+	_activeObjectNr = 0;
+	_activeObjectType = kObjectTypeBG;
+	_activeObject2Nr = 0;
+	_activeObject2Type = kObjectTypeBG;
+	_walkToObjectIdx = 0;
 }
 
 } // End of namespace Scumm
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 1ea3257..6f6138d 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1219,20 +1219,23 @@ void ScummEngine_v2::o2_panCameraTo() {
 	panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0);
 }
 
-void ScummEngine_v2::o2_walkActorToObject() {
-	int obj;
-	Actor *a;
+void ScummEngine_v2::walkActorToObject(int actor, int obj) {
+	int x, y, dir;
+	getObjectXYPos(obj, x, y, dir);
 
-	a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");
-	obj = getVarOrDirectWord(PARAM_2);
-	if (whereIsObject(obj) != WIO_NOT_FOUND) {
-		int x, y, dir;
-		getObjectXYPos(obj, x, y, dir);
-		AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
-		x = r.x;
-		y = r.y;
+	Actor *a = derefActor(actor, "walkActorToObject");
+	AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
+	x = r.x;
+	y = r.y;
+
+	a->startWalkActor(x, y, dir);
+}
 
-		a->startWalkActor(x, y, dir);
+void ScummEngine_v2::o2_walkActorToObject() {
+	int actor = getVarOrDirectByte(PARAM_1);
+	int obj = getVarOrDirectWord(PARAM_2);
+	if (whereIsObject(obj) != WIO_NOT_FOUND) {
+		walkActorToObject(actor, obj);
 	}
 }
 
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 6426b75..1d68e86 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2464,8 +2464,43 @@ void ScummEngine_v5::o5_walkActorTo() {
 	a->startWalkActor(x, y, -1);
 }
 
+void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
+	Actor *a = derefActor(actor, "walkActorToActor");
+	Actor *to = derefActor(toActor, "walkActorToActor(2)");
+
+	if (_game.version <= 2) {
+		dist *= V12_X_MULTIPLIER;
+	} else if (dist == 0xFF) {
+		dist = a->_scalex * a->_width / 0xFF;
+		dist += (to->_scalex * to->_width / 0xFF) / 2;
+	}
+	int x = to->getPos().x;
+	int y = to->getPos().y;
+	if (x < a->getPos().x)
+		x += dist;
+	else
+		x -= dist;
+
+	if (_game.version <= 2) {
+		x /= V12_X_MULTIPLIER;
+		y /= V12_Y_MULTIPLIER;
+	}
+	if (_game.version <= 3) {
+		AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
+		x = abr.x;
+		y = abr.y;
+	}
+	a->startWalkActor(x, y, -1);
+
+	// WORKAROUND: See bug #2971126 for details on why this is here.
+	if (_game.version == 0) {
+		// FIXME(TOBIAS): is this still needed?
+		// (updateScriptPtr/_currentScript might now be called automatically) 
+		o5_breakHere();
+	}
+}
+
 void ScummEngine_v5::o5_walkActorToActor() {
-	int x, y;
 	Actor *a, *a2;
 	int nr = getVarOrDirectByte(PARAM_1);
 	int nr2 = getVarOrDirectByte(PARAM_2);
@@ -2499,33 +2534,7 @@ void ScummEngine_v5::o5_walkActorToActor() {
 	if (!a2->isInCurrentRoom())
 		return;
 
-	if (_game.version <= 2) {
-		dist *= V12_X_MULTIPLIER;
-	} else if (dist == 0xFF) {
-		dist = a->_scalex * a->_width / 0xFF;
-		dist += (a2->_scalex * a2->_width / 0xFF) / 2;
-	}
-	x = a2->getPos().x;
-	y = a2->getPos().y;
-	if (x < a->getPos().x)
-		x += dist;
-	else
-		x -= dist;
-
-	if (_game.version <= 2) {
-		x /= V12_X_MULTIPLIER;
-		y /= V12_Y_MULTIPLIER;
-	}
-	if (_game.version <= 3) {
-		AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
-		x = abr.x;
-		y = abr.y;
-	}
-	a->startWalkActor(x, y, -1);
-
-	// WORKAROUND: See bug #2971126 for details on why this is here.
-	if (_game.version == 0)
-		o5_breakHere();
+	walkActorToActor(nr, nr2, dist);
 }
 
 void ScummEngine_v5::o5_walkActorToObject() {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 8b2e2ef..e6ec2b0 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -712,17 +712,19 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
 ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
 	: ScummEngine_v2(syst, dr) {
 
-	_verbExecuting = false;
-	_verbPickup = false;
 	_currentMode = 0;
 
 	_activeVerb = kVerbNone;
 	_activeObjectNr = 0;
+	_activeObjectType = 0;
 	_activeObject2Nr = 0;
-	_activeObjectType = kObjectTypeBG;
-	_activeObject2Type = kObjectTypeBG;
-	_activeObjectObtained = false;
-	_activeObject2Obtained = false;
+	_activeObject2Type = 0;
+
+	_cmdVerb = kVerbNone;
+	_cmdObjectNr = 0;
+	_cmdObjectType = 0;
+	_cmdObject2Nr = 0;
+	_cmdObject2Type = 0;
 
 	VAR_ACTIVE_ACTOR = 0xFF;
 	VAR_IS_SOUND_RUNNING = 0xFF;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index f004176..fadc390 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -642,7 +642,7 @@ protected:
 	void updateScriptPtr();
 	virtual void runInventoryScript(int i);
 	void inventoryScriptIndy3Mac();
-	void checkAndRunSentenceScript();
+	virtual void checkAndRunSentenceScript();
 	void runExitScript();
 	void runEntryScript();
 	void runAllScripts();
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 9b38b10..031a73a 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -54,8 +54,6 @@ protected:
 
 protected:
 	byte _currentMode;
-	bool _verbExecuting;			// is a verb executing
-	bool _verbPickup;				// are we picking up an object during a verb execute
 
 	int _activeVerb;
 	int _activeObjectNr;			// 1st Object Number
@@ -63,8 +61,14 @@ protected:
 	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?
+	int _cmdVerb;
+	int _cmdObjectNr;
+	int _cmdObjectType;
+	int _cmdObject2Nr;
+	int _cmdObject2Type;
+
+	int _walkToObject;
+	int _walkToObjectIdx;
 
 public:
 	ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@@ -83,17 +87,16 @@ protected:
 
 	virtual void processInput();
 
-	virtual void runObject(int obj, int entry);
 	virtual void saveOrLoad(Serializer *s);
 
 	// V0 MM Verb commands
 	int getVerbPrepId();
 	int activeVerbPrep();
-	bool verbMove(int object);
-	bool verbMoveToActor(int actor);
-	bool verbObtain(int object);
-	bool verbExec();
+	void walkToActorOrObject(int object);
+	void verbExec();
 
+	virtual void runSentenceScript();
+	virtual void checkAndRunSentenceScript();
 	virtual void checkExecVerbs();
 	virtual void handleMouseOver(bool updateInventory);
 	int verbPrepIdType(int verbid);
@@ -138,6 +141,7 @@ protected:
 	void o_unlockScript();
 	void o_decrement();
 	void o_nop();
+	void o_getObjectOwner();
 	void o_getActorBitVar();
 	void o_setActorBitVar();
 	void o_getBitVar();
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index b9cd8a3..b407fd3 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -99,7 +99,7 @@ protected:
 
 	void drawPreposition(int index);
 
-	virtual void setActiveInventory(int object);
+	void walkActorToObject(int actor, int obj);
 
 	/* Version 2 script opcodes */
 	void o2_actorFromPos();
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index b8a61c1..0eef04b 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -87,6 +87,8 @@ protected:
 
 	void drawFlashlight();
 
+	void walkActorToActor(int actor, int toActor, int dist);
+
 	/**
 	 * Fetch the next script word, then if cond is *false*, perform a relative jump.
 	 * So this corresponds to a "jne" jump instruction.
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 016248c..376e075 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -366,10 +366,6 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
 	}
 }
 
-void ScummEngine_v2::setActiveInventory(int object) {
-	runInputScript(kInventoryClickArea, object, 0);
-}
-
 int ScummEngine_v2::checkV2Inventory(int x, int y) {
 	int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
 	int object = 0;
@@ -717,142 +713,6 @@ void ScummEngine_v2::checkExecVerbs() {
 	}
 }
 
-void ScummEngine_v0::runObject(int obj, int entry) {
-	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
-		//  it merely seems to be some type of fallback)
-		if (getVerbEntrypoint(obj, 0x0F) != 0) {
-			entry = 0x0F;
-		}
-	}
-
-	if (getVerbEntrypoint(obj, entry) != 0) {
-		runObjectScript(obj, entry, false, false, NULL);
-	} else if (entry != 13 && entry != 15) {
-		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);
-		}
-	}
-}
-
-bool ScummEngine_v0::verbMoveToActor(int actor) {
-	Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor");
-	Actor *a2 = derefActor(actor, "verbMoveToActor");
-	int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
-
-	if (!a->_moving && dist > 4) {
-		a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1);
-	} else {
-		if (dist <= 4) {
-			a->stopActorMoving();
-			return false;
-		}
-	}
-
-	return true;
-}
-
-bool ScummEngine_v0::verbMove(int object) {
-	int x, y, dir;
-	Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
-
-	if (_currentMode != kModeNormal && _currentMode != kModeNoNewKid)
-		return false;
-
-	getObjectXYPos(object, x, y, dir);
-
-	// Detect distance from target object
-	int dist =  getDist(a->getRealPos().x, a->getRealPos().y, x, y);
-
-	if (a->_moving)
-		return true;
-
-	if (dist > 5) {
-		a->startWalkActor(x, y, dir);
-		VAR(6) = x;
-		VAR(7) = y;
-		return true;
-	} else {
-		// Finished walk, are we picking up the item?
-		if (_verbPickup) {
-			int oldActive = OBJECT_V0(_activeObjectNr, _activeObjectType);
-
-			_activeObjectNr = OBJECT_V0_NR(object);
-			_activeObjectType = OBJECT_V0_TYPE(object);
-
-			// Execute pickup
-			runObject(object, 14);
-
-			_activeObjectNr = OBJECT_V0_NR(oldActive);
-			_activeObjectType = OBJECT_V0_TYPE(oldActive);
-
-			// Finished picking up
-			_verbPickup = false;
-		}
-	}
-
-	return false;
-}
-
-bool ScummEngine_v0::verbObtain(int obj) {
-	bool didPickup = false;
-	int prep;
-	int where;
-
-	if (!obj)
-		return false;
-
-	where = whereIsObject(obj);
-
-	// Object in inventory ?
-	if (where != WIO_INVENTORY) {
-		prep = activeVerbPrep();
-
-		if (prep == kVerbPrepIn || prep == kVerbPrepTo) {
-			if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
-				_verbPickup = true;
-				didPickup = true;
-			}
-		} else {
-			_verbPickup = false;
-		}
-
-		// Ignore verbs?
-		ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbObtain");
-		if (a->_miscflags & kActorMiscFlagFreeze) {
-			resetSentence(false);
-			return false;
-		}
-
-		//attempt move to object
-		if (verbMove(obj))
-			return true;
-
-		if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo))
-			if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) {
-// TODO(TOBIAS)
-#if 0
-				if (whereIsObject(obj) == WIO_INVENTORY)
-					_activeInventory = obj;
-				else
-					resetSentence(false);
-#endif
-			}
-	}
-
-	return false;
-}
-
 int ScummEngine_v0::getVerbPrepId() {
 	if (_verbs[_activeVerb].prep != 0xFF) {
 		return _verbs[_activeVerb].prep;
@@ -869,150 +729,44 @@ int ScummEngine_v0::activeVerbPrep() {
 	return getVerbPrepId();
 }
 
-bool ScummEngine_v0::verbExec() {
-	int entry = (_currentMode != kModeCutscene && _currentMode != kModeKeypad) ? _activeVerb : kVerbWhatIs;
-
-	if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) {
-		resetSentence(false);
-		return false;
-	}
-
-	// Lets try walk to the object
-	if (_activeObjectNr && !_activeObjectObtained && _currentMode != kModeCutscene) {
-		if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType)))
-			return true;
-
-		_activeObjectObtained = true;
-	}
-
-	// Attempt to obtain/reach object2
-	if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != kModeCutscene) {
-		if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type)))
-			return true;
-
-		_activeObject2Obtained = true;
-	}
-
-	// Give-To
-	if (_activeVerb == kVerbGive && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
-		// FIXME: Actors need to turn and face each other
-		if (verbMoveToActor(_activeObject2Nr)) {
-			// Ignore verbs?
-			Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
-			if (((ActorC64 *)a)->_miscflags & kActorMiscFlagFreeze) {
-				resetSentence(false);
-				return false;
-			}
-
-			return true;
-		}
-		VAR(VAR_ACTIVE_ACTOR) = _activeObject2Nr;
-		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), 3);
-
-		resetSentence(false);
-		return false;
-	}
-
-	// Where we performing an action on an actor?
-	if (_activeObject2Nr && _activeObject2Type == kObjectTypeActor) {
-		runObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type), entry);
-		_verbExecuting = false;
-
-		resetSentence(false);
-		return false;
-	}
-
-	// If we've finished walking (now near target), execute the action
-	if (_activeObjectNr && activeVerbPrep() == kVerbPrepWith) {
-		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
-		_verbExecuting = false;
-
-		if ((_currentMode == kModeNormal || _currentMode == kModeNoNewKid) && _activeVerb == kVerbWalkTo)
-			return false;
-
-		resetSentence(false);
-		return false;
-	}
-
-	// We acted on an inventory item
-	if (_activeVerb != kVerbGive) {
-		runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb);
-
-		_verbExecuting = false;
-
-		if (_currentMode == kModeNormal && _activeVerb == kVerbWalkTo) {
-			resetSentence(true);
-			return false;
+void ScummEngine_v0::verbExec() {
+	if (_activeVerb == kVerbWhatIs)
+		return;
+		
+	if (_activeVerb != kVerbWalkTo || _activeObjectNr != 0) {		
+		doSentence(_activeVerb, 
+			OBJECT_V0(_activeObjectNr, _activeObjectType), 
+			OBJECT_V0(_activeObject2Nr, _activeObject2Type));
+		if (_activeVerb != kVerbWalkTo) {
+			_activeVerb = kVerbWalkTo;
+			_activeObjectNr = 0;
 		}
-
-		resetSentence(false);
-		return false;
-	}
-
-	if (_activeObjectNr) {
-		runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry);
-	}
-
-	_verbExecuting = false;
-
-	if (_activeVerb == kVerbWalkTo) {
-		resetSentence(true);
-		return false;
+		_walkToObjectIdx = 0;
+		return;
 	}
 
-	resetSentence(false);
+	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbExec");
+	int x = _virtualMouse.x / V12_X_MULTIPLIER;
+	int y = _virtualMouse.y / V12_Y_MULTIPLIER;
+	//actorSetPosInBox();
 
-	return false;
-}
+	// 0xB31
+	VAR(6) = x;
+	VAR(7) = y;
 
-#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;
+	if (a->_miscflags & kActorMiscFlagFreeze)
 		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();
-	}
+
+	a->stopActorMoving();
+	a->startWalkActor(VAR(6), VAR(7), -1);
 }
-#endif
 
 void ScummEngine_v0::checkExecVerbs() {
 	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
 	VirtScreen *zone = findVirtScreen(_mouse.y);
 
-	int scriptUpdateSkip;
 	int sentenceLineChanged = false;
+	bool execute = false;
 
 	/*
 	if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
@@ -1024,7 +778,6 @@ void ScummEngine_v0::checkExecVerbs() {
 		int over = findVerbAtPos(_mouse.x, _mouse.y);
 		if (over && _activeVerb != over) {
 			_activeVerb = over;
-			//_activeVerbPrep = 0;
 			_activeObjectNr = 0;
 			_activeObjectType = 0;
 			_activeObject2Nr = 0;
@@ -1045,7 +798,7 @@ void ScummEngine_v0::checkExecVerbs() {
 		}
 
 		if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
-			// TODO:  Check keypresses
+			// TODO: check keypresses
 		} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
 			if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
 				// TODO: handle click into sentence line
@@ -1081,130 +834,61 @@ void ScummEngine_v0::checkExecVerbs() {
 						_activeObject2Type = 0;
 					}
 				} else {
-					//_activeVerbPrep:
-					// 0: no activeObject or activeObject but no prep
-					// > 0: activeObject + prep
 					if (activeVerbPrep() == kVerbPrepNone) {
 						if (id == _activeObjectNr && type == _activeObjectType) {
-							_verbExecuting = true;
+							execute = true;
 						} else {
 							_activeObjectNr = id;
 							_activeObjectType = type;
 						}
-						//sentenceLineChanged = true;
 						if (_currentMode == kModeKeypad)
-							_verbExecuting = true;
+							execute = true;
 					} else {
 						if (id == _activeObject2Nr && type == _activeObject2Type)
-							_verbExecuting = true;
+							execute = true;
 						if (!(id == _activeObjectNr && type == _activeObjectType)) {
 							_activeObject2Nr = id;
 							_activeObject2Type = type;
 							if (_currentMode == kModeKeypad)
-								_verbExecuting = true;
+								execute = true;
 						}
 					}
 				}
 
 				sentenceLineChanged = true;
-				if (_activeVerb == kVerbWalkTo) {
-					scriptUpdateSkip = 0;
-					_verbExecuting = true;
+				if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) {
+					_walkToObjectIdx = 0;
+					execute = true;
 				}
 			}
 		}
 	}
 
-	if (sentenceLineChanged)
+	if (sentenceLineChanged) {
 		drawSentence();
+		sentenceLineChanged = false;
+	}
+
+	if (!execute || !_activeVerb)
+		return;
 
 	if (_activeVerb == kVerbNewKid) {
-		// TODO
 		if (_currentMode == kModeNormal) {
-			// get kid
+			// TODO: get clicked kid
 			_activeVerb = kVerbWalkTo;
-			resetSentence(false);
+			drawSentence();
 			//switchActor(_verbs[over].verbid - 1);
 		}
 		_activeVerb = kVerbWalkTo;
 	}
 
-	if (_activeVerb == kVerbWalkTo) {
-		//exec();
-	}
-
-	/*
-	if (_activeVerbPrep == 0) {
-		int prep = activeVerbPrep();
-		if (prep == kVerbPrepNone)
-			; //exec();
-		else {
-			_activeVerbPrep = prep;
-			; // draw()
-		}
-	} else {
-		if (_activeObject2 == 0)
-			; //drawSentence();
-		else
-			; // exec();
+	if (_activeVerb == kVerbWalkTo)
+		verbExec();
+	else if (_activeObjectNr) {
+		// execute if we have a 1st object and either have or do not need a 2nd
+		if (activeVerbPrep() == kVerbPrepNone || _activeObject2Nr)
+			verbExec();
 	}
-	*/
-
-#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);
-			byte type;
-			int obj  = findObject(_virtualMouse.x, _virtualMouse.y, &type);
-
-			if (over && over != _activeVerb) {
-				_activeVerb = over;
-				_verbExecuting = false;
-				return;
-			}
-
-			if (!obj && !act && !over) {
-				resetSentence(false);
-			} else {
-				a->stopActorMoving();
-			}
-		} else {
-
-			if (_verbExecuting && !verbExec())
-				return;
-		}
-	}
-
-	...
-
-			// Clicked on nothing, walk here?
-			if (!over && !act && _activeVerb == kVerbWalkTo && !obj && _currentMode != kMode_0) {
-				// Clear all selected
-				resetSentence(false);
-
-				// 0xB31
-				VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER;
-				VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
-
-				if (zone->number == kMainVirtScreen) {
-					// Ignore verbs?
-					if (a->_miscflags & kActorMiscFlagFreeze) {
-						resetSentence(false);
-						return;
-					}
-					a->stopActorMoving();
-					a->startWalkActor(VAR(6), VAR(7), -1);
-					_verbExecuting = true;
-				}
-				return;
-			}
-		_verbExecuting = true;
-
-	}	// mouse k/b action
-#endif
 }
 
 void ScummEngine::verbMouseOver(int verb) {


Commit: 8233af60239d965e70c38cea8f3b212d642f4a11
    https://github.com/scummvm/scummvm/commit/8233af60239d965e70c38cea8f3b212d642f4a11
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:48-08:00

Commit Message:
make START-button in kid selection screen work again

Changed paths:
    engines/scumm/object.cpp
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 49f1777..670b2cb 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -1223,7 +1223,7 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
 		return 0;
 
 	for (i = (_numLocalObjects-1); i > 0; i--) {
-		if (_objs[i].obj_nr == object) {
+		if (_objs[i].obj_nr == OBJECT_V0_NR(object)) {
 			if (_game.version == 0 && _objs[i].obj_type != OBJECT_V0_TYPE(object))
 				continue;
 			if (_objs[i].fl_object_index != 0)
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 376e075..19ad003 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -740,6 +740,7 @@ void ScummEngine_v0::verbExec() {
 		if (_activeVerb != kVerbWalkTo) {
 			_activeVerb = kVerbWalkTo;
 			_activeObjectNr = 0;
+			_activeObjectType = 0;
 		}
 		_walkToObjectIdx = 0;
 		return;
@@ -841,6 +842,7 @@ void ScummEngine_v0::checkExecVerbs() {
 							_activeObjectNr = id;
 							_activeObjectType = type;
 						}
+						// immediately execute action in keypad/selection mode
 						if (_currentMode == kModeKeypad)
 							execute = true;
 					} else {


Commit: d57b483a272258dd175dfd5fa161fcc1e00d0c80
    https://github.com/scummvm/scummvm/commit/d57b483a272258dd175dfd5fa161fcc1e00d0c80
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:48-08:00

Commit Message:
- getVerbEntrypoint() should not handle walk-to differently (revert 0x0D handling back to original behavior)
- VAR_ACTIVE_ACTOR actually is VAR_ACTIVE_OBJECT2
- runSentenceScript(): "if (_cmdVerb == kVerbWalkTo)" must be "if (_cmdVerb != kVerbWalkTo)"

Changed paths:
    engines/scumm/script.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/vars.cpp



diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 0864022..e34c81d 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -196,12 +196,8 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
 	} else if (_game.version <= 2) {
 		do {
 			const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF);
-			if (!*verbptr) {
-				if (_game.version == 0 && entry == kVerbWalkTo)
-					return 13;
-				else
-					return 0;
-			}
+			if (!*verbptr)
+				return 0;
 			if (*verbptr == entry || *verbptr == kFallbackEntry)
 				break;
 			verbptr += 2;
@@ -1160,8 +1156,6 @@ void ScummEngine_v0::walkToActorOrObject(int object) {
 }
 
 void ScummEngine_v0::checkAndRunSentenceScript() {
-	const ScriptSlot *ss;
-
 	if (_walkToObjectIdx) {
 		ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript");
 		if (a->_moving)
@@ -1175,7 +1169,6 @@ void ScummEngine_v0::checkAndRunSentenceScript() {
 	if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
 		return;
 
-	//_sentenceNum--;
 	SentenceTab &st = _sentence[_sentenceNum - 1];
 
 	if (st.preposition && st.objectB == st.objectA)
@@ -1232,30 +1225,27 @@ void ScummEngine_v0::checkAndRunSentenceScript() {
 void ScummEngine_v0::runSentenceScript() {
 	int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
 
-	// FIXME: should it really ever return 0xD on WalkTo, seems wrong?
 	if (getVerbEntrypoint(obj, _cmdVerb) != 0) {
-		if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) {
-			//slot = 0xFF;
-			VAR(VAR_ACTIVE_VERB) = _cmdVerb;
-			runScript(3, 0, 0, 0);
-			return;
-		} else {
-			VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr;
+		// do not read in the dark
+		if (!(_cmdVerb == kVerbRead && _currentLights == 0)) {
+			VAR(VAR_ACTIVE_OBJECT2) = _cmdObject2Nr;
 			runObjectScript(obj, _cmdVerb, false, false, NULL);
 			return;
 		}
 	} else {
 		if (_cmdVerb == kVerbGive) {
+			// no "give to"-script: give to other kid or ignore
 			if (_cmdObject2Nr < 8)
 				setOwnerOf(obj, _cmdObject2Nr);
 			return;
-		} else if (_cmdVerb == kVerbWalkTo) {
-			//slot = 0xFF;
-			VAR(VAR_ACTIVE_VERB) = _cmdVerb;
-			runScript(3, 0, 0, 0);
-			return;
 		}
 	}
+
+	if (_cmdVerb != kVerbWalkTo) {
+		// perform verb's fallback action
+		VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+		runScript(3, 0, 0, 0);
+	}
 }
 
 void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index e6ec2b0..2eda5ca 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -726,7 +726,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
 	_cmdObject2Nr = 0;
 	_cmdObject2Type = 0;
 
-	VAR_ACTIVE_ACTOR = 0xFF;
+	VAR_ACTIVE_OBJECT2 = 0xFF;
 	VAR_IS_SOUND_RUNNING = 0xFF;
 	VAR_ACTIVE_VERB = 0xFF;
 }
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 031a73a..3335a15 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -159,7 +159,7 @@ protected:
 	void o_beginOverride();
 	void o_setOwnerOf();
 
-	byte VAR_ACTIVE_ACTOR;
+	byte VAR_ACTIVE_OBJECT2;
 	byte VAR_IS_SOUND_RUNNING;
 	byte VAR_ACTIVE_VERB;
 };
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 26a6a2f..6365a72 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -115,7 +115,7 @@ void ScummEngine_v0::setupScummVars() {
 	VAR_CAMERA_POS_X = 2;
 	VAR_HAVE_MSG = 3;
 	VAR_ROOM = 4;
-	VAR_ACTIVE_ACTOR = 5;
+	VAR_ACTIVE_OBJECT2 = 5;
 	VAR_OVERRIDE = 6;
 	VAR_IS_SOUND_RUNNING = 8;
 	VAR_ACTIVE_VERB = 9;


Commit: f0b97b9ef8d35d288d137f58ec59e6898ccd2c72
    https://github.com/scummvm/scummvm/commit/f0b97b9ef8d35d288d137f58ec59e6898ccd2c72
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:49-08:00

Commit Message:
kid selection working again

The kid names are now displayed in the sentence line (instead of the verb area) as it is done in the original.

Changed paths:
    engines/scumm/script_v0.cpp
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index f4b98a4..cd2e896 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -406,6 +406,42 @@ void ScummEngine_v0::decodeParseString() {
 	actorTalk(buffer);
 }
 
+void ScummEngine_v0::clearSentenceLine() {
+	Common::Rect sentenceline;
+	sentenceline.top = _virtscr[kVerbVirtScreen].topline;
+	sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8;
+	sentenceline.left = 0;
+	sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
+	restoreBackground(sentenceline);
+}
+
+void ScummEngine_v0::flushSentenceLine() {
+	byte string[80];
+	const char *ptr = _sentenceBuf.c_str();
+	int i = 0, len = 0;
+
+	// Maximum length of printable characters
+	int maxChars = 40;
+	while (*ptr) {
+		if (*ptr != '@')
+			len++;
+		if (len > maxChars) {
+			break;
+		}
+
+		string[i++] = *ptr++;
+
+	}
+	string[i] = 0;
+
+	_string[2].charset = 1;
+	_string[2].ypos = _virtscr[kVerbVirtScreen].topline;
+	_string[2].xpos = 0;
+	_string[2].right = _virtscr[kVerbVirtScreen].w - 1;
+	_string[2].color = 16;
+	drawString(2, (byte *)string);
+}
+
 void ScummEngine_v0::drawSentenceObject(int object) {
 	const byte *temp;
 	temp = getObjOrActorName(object);
@@ -415,20 +451,30 @@ void ScummEngine_v0::drawSentenceObject(int object) {
 	}
 }
 
-void ScummEngine_v0::drawSentence() {
-	Common::Rect sentenceline;
 
+void ScummEngine_v0::drawSentenceLine() {
 	if (!(_userState & 32))
 		return;
 
+	clearSentenceLine();
+
+	if (_activeVerb == kVerbNewKid) {
+		_sentenceBuf = "";
+		for (int i = 0; i < 3; ++i) {
+			Actor *a = derefActor(VAR(97 + i), "drawSentence");
+			_sentenceBuf += Common::String::format("%-13s", a->getActorName());
+		}
+		flushSentenceLine();
+		return;
+	}
+
 	// Current Verb
 	if (_activeVerb == kVerbNone)
 		_activeVerb = kVerbWalkTo;
-	if (getResourceAddress(rtVerb, _activeVerb)) {
-		_sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
-	} else {
-		return;
-	}
+
+	char *verbName = (char *)getResourceAddress(rtVerb, _activeVerb);
+	assert(verbName);
+	_sentenceBuf = verbName;
 
 	if (_activeObjectNr) {
 		// Draw the 1st active object
@@ -454,37 +500,7 @@ void ScummEngine_v0::drawSentence() {
 		}
 	}
 
-	_string[2].charset = 1;
-	_string[2].ypos = _virtscr[kVerbVirtScreen].topline;
-	_string[2].xpos = 0;
-	_string[2].right = _virtscr[kVerbVirtScreen].w - 1;
-	_string[2].color = 16;
-
-	byte string[80];
-	const char *ptr = _sentenceBuf.c_str();
-	int i = 0, len = 0;
-
-	// Maximum length of printable characters
-	int maxChars = 40;
-	while (*ptr) {
-		if (*ptr != '@')
-			len++;
-		if (len > maxChars) {
-			break;
-		}
-
-		string[i++] = *ptr++;
-
-	}
-	string[i] = 0;
-
-	sentenceline.top = _virtscr[kVerbVirtScreen].topline;
-	sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8;
-	sentenceline.left = 0;
-	sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
-	restoreBackground(sentenceline);
-
-	drawString(2, (byte *)string);
+	flushSentenceLine();
 }
 
 void ScummEngine_v0::o_stopCurrentScript() {
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 3335a15..78449ea 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -101,10 +101,11 @@ protected:
 	virtual void handleMouseOver(bool updateInventory);
 	int verbPrepIdType(int verbid);
 	void resetVerbs();
-	void setNewKidVerbs();
 
+	void clearSentenceLine();
+	void flushSentenceLine();
 	void drawSentenceObject(int object);
-	void drawSentence();
+	void drawSentenceLine();
 
 	void switchActor(int slot);
 
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 19ad003..e06ee3d 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -131,37 +131,6 @@ void ScummEngine_v0::resetVerbs() {
 	}
 }
 
-void ScummEngine_v0::setNewKidVerbs() {
-	VirtScreen *virt = &_virtscr[kVerbVirtScreen];
-	VerbSlot *vs;
-	int i;
-
-	for (i = 1; i < 16; i++)
-		killVerb(i);
-
-	for (i = 1; i < 4; i++) {
-		vs = &_verbs[i];
-		vs->verbid = i;
-		vs->color = 5;
-		vs->hicolor = 7;
-		vs->dimcolor = 11;
-		vs->type = kTextVerbType;
-		vs->charset_nr = _string[0]._default.charset;
-		vs->curmode = 1;
-		vs->saveid = 0;
-		vs->key = 0;
-		vs->center = 0;
-		vs->imgindex = 0;
-		vs->prep = 0;
-		vs->curRect.left = (i * 8) * 8;
-		vs->curRect.top = virt->topline + 8;
-
-		Actor *a = derefActor(VAR(96 + i), "setNewKidVerbs");
-		loadPtrToResource(rtVerb, i, (const byte*)a->getActorName());
-	}
-	setUserState(191);
-}
-
 void ScummEngine_v0::switchActor(int slot) {
 	resetSentence(false);
 
@@ -802,7 +771,24 @@ void ScummEngine_v0::checkExecVerbs() {
 			// TODO: check keypresses
 		} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
 			if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
-				// TODO: handle click into sentence line
+				if (_activeVerb == kVerbNewKid) {
+					if (_currentMode == kModeNormal) {
+						int kid;
+						int lineX = _mouse.x >> V12_X_SHIFT;
+						if (lineX < 11)
+							kid = 0;
+						else if (lineX < 25)
+							kid = 1;
+						else
+							kid = 2;
+						// TODO: get clicked kid
+						_activeVerb = kVerbWalkTo;
+						drawSentenceLine();
+						switchActor(kid);
+					}
+					_activeVerb = kVerbWalkTo;
+					return;
+				}
 			} else {
 				int obj = 0;
 
@@ -867,23 +853,13 @@ void ScummEngine_v0::checkExecVerbs() {
 	}
 
 	if (sentenceLineChanged) {
-		drawSentence();
+		drawSentenceLine();
 		sentenceLineChanged = false;
 	}
 
 	if (!execute || !_activeVerb)
 		return;
 
-	if (_activeVerb == kVerbNewKid) {
-		if (_currentMode == kModeNormal) {
-			// TODO: get clicked kid
-			_activeVerb = kVerbWalkTo;
-			drawSentence();
-			//switchActor(_verbs[over].verbid - 1);
-		}
-		_activeVerb = kVerbWalkTo;
-	}
-
 	if (_activeVerb == kVerbWalkTo)
 		verbExec();
 	else if (_activeObjectNr) {


Commit: a2c4cf194cb6e3acfd5554cf887b49ce65bec516
    https://github.com/scummvm/scummvm/commit/a2c4cf194cb6e3acfd5554cf887b49ce65bec516
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:49-08:00

Commit Message:
click into sentence line now performs the action

Changed paths:
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index e06ee3d..cb8148d 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -781,13 +781,15 @@ void ScummEngine_v0::checkExecVerbs() {
 							kid = 1;
 						else
 							kid = 2;
-						// TODO: get clicked kid
 						_activeVerb = kVerbWalkTo;
 						drawSentenceLine();
 						switchActor(kid);
 					}
 					_activeVerb = kVerbWalkTo;
 					return;
+				} else if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) {
+					if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr))
+						execute = true;
 				}
 			} else {
 				int obj = 0;


Commit: 76675a7ad54a27038d6a6bba5dc79273504ca806
    https://github.com/scummvm/scummvm/commit/76675a7ad54a27038d6a6bba5dc79273504ca806
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:49-08:00

Commit Message:
fix a regression that was found by segra.

Changed paths:
    engines/scumm/object.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 670b2cb..2659786 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -1223,7 +1223,8 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
 		return 0;
 
 	for (i = (_numLocalObjects-1); i > 0; i--) {
-		if (_objs[i].obj_nr == OBJECT_V0_NR(object)) {
+		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 != 0)


Commit: 716dfbe46c7705debf838c63b6ef3ea4c8c39b25
    https://github.com/scummvm/scummvm/commit/716dfbe46c7705debf838c63b6ef3ea4c8c39b25
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:50-08:00

Commit Message:
reset sentence line if sentence executed

Changed paths:
    engines/scumm/script.cpp



diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index e34c81d..ded47ad 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1225,6 +1225,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() {
 void ScummEngine_v0::runSentenceScript() {
 	int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
 
+	drawSentenceLine();
+
 	if (getVerbEntrypoint(obj, _cmdVerb) != 0) {
 		// do not read in the dark
 		if (!(_cmdVerb == kVerbRead && _currentLights == 0)) {


Commit: c9dfdbac688f16d1a9e20ee15cc379eb7610203c
    https://github.com/scummvm/scummvm/commit/c9dfdbac688f16d1a9e20ee15cc379eb7610203c
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:50-08:00

Commit Message:
- execute sentence if verb was clicked twice
- reuse the first object if a new verb is selected (but no preposition is used yet)

Changed paths:
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 78449ea..c2af6d4 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -97,6 +97,7 @@ protected:
 
 	virtual void runSentenceScript();
 	virtual void checkAndRunSentenceScript();
+	bool checkSentenceComplete();
 	virtual void checkExecVerbs();
 	virtual void handleMouseOver(bool updateInventory);
 	int verbPrepIdType(int verbid);
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index cb8148d..74ff27c 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -731,6 +731,14 @@ void ScummEngine_v0::verbExec() {
 	a->startWalkActor(VAR(6), VAR(7), -1);
 }
 
+bool ScummEngine_v0::checkSentenceComplete() {
+	if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) {
+		if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr))
+			return true;
+	}
+	return false;
+}
+
 void ScummEngine_v0::checkExecVerbs() {
 	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
 	VirtScreen *zone = findVirtScreen(_mouse.y);
@@ -738,21 +746,28 @@ void ScummEngine_v0::checkExecVerbs() {
 	int sentenceLineChanged = false;
 	bool execute = false;
 
-	/*
-	if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
-		return;
-	*/
+	//if (_userPut <= 0)
+	//	return;
 
-	// Check if mouse click
 	if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
 		int over = findVerbAtPos(_mouse.x, _mouse.y);
-		if (over && _activeVerb != over) {
-			_activeVerb = over;
-			_activeObjectNr = 0;
-			_activeObjectType = 0;
-			_activeObject2Nr = 0;
-			_activeObject2Type = 0;
-			sentenceLineChanged = true;
+		// click region: verbs
+		if (over) {
+			if (_activeVerb != over) { // new verb
+				// keep first object if no preposition is used yet
+				if (activeVerbPrep()) {
+					_activeObjectNr = 0;
+					_activeObjectType = 0;
+				}
+				_activeObject2Nr = 0;
+				_activeObject2Type = 0;
+				_activeVerb = over;
+				sentenceLineChanged = true;
+			} else {
+				// execute sentence if complete
+				if (checkSentenceComplete())
+					execute = true;
+			}
 		}
 	}
 
@@ -770,6 +785,7 @@ void ScummEngine_v0::checkExecVerbs() {
 		if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
 			// TODO: check keypresses
 		} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
+			// click region: sentence line
 			if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
 				if (_activeVerb == kVerbNewKid) {
 					if (_currentMode == kModeNormal) {
@@ -787,13 +803,18 @@ void ScummEngine_v0::checkExecVerbs() {
 					}
 					_activeVerb = kVerbWalkTo;
 					return;
-				} else if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) {
-					if (_activeObjectNr && (!activeVerbPrep() || _activeObject2Nr))
+				} else {
+					// execute sentence if complete
+					if (checkSentenceComplete())
 						execute = true;
 				}
-			} else {
+			// click region: inventory or main screen
+			} else if ((zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) ||
+			           (zone->number == kMainVirtScreen))
+			{
 				int obj = 0;
 
+				// click region: inventory
 				if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
 					// click into inventory
 					int invOff = _inventoryOffset;
@@ -802,6 +823,7 @@ void ScummEngine_v0::checkExecVerbs() {
 						// inventory position changed (arrows pressed, do nothing)
 						return;
 					}
+				// click region: main screen
 				} else if (zone->number == kMainVirtScreen) {
 					// click into main screen
 					if (_activeVerb == kVerbGive && _activeObjectNr) {


Commit: 5cbf2df71c2b94dac1a7b36c162a99ec4c4e3af8
    https://github.com/scummvm/scummvm/commit/5cbf2df71c2b94dac1a7b36c162a99ec4c4e3af8
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:51-08:00

Commit Message:
pop stack if command's object1 and 2 are the same, otherwise the command will never be removed and the stack overflows

Changed paths:
    engines/scumm/script.cpp



diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index ded47ad..eb0f7bf 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1171,8 +1171,10 @@ void ScummEngine_v0::checkAndRunSentenceScript() {
 
 	SentenceTab &st = _sentence[_sentenceNum - 1];
 
-	if (st.preposition && st.objectB == st.objectA)
+	if (st.preposition && st.objectB == st.objectA) {
+		_sentenceNum--;
 		return;
+	}
 
 	// FIXME: should this be executed?
 	//_currentScript = 0xFF;


Commit: 9e93af921cde3339e58a806f2476577a3eed327d
    https://github.com/scummvm/scummvm/commit/9e93af921cde3339e58a806f2476577a3eed327d
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:51-08:00

Commit Message:
reset object2 correctly. This fixes the issue that a kid will not enter the front door after opening it with the key.

Changed paths:
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 74ff27c..e70ae49b 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -710,6 +710,8 @@ void ScummEngine_v0::verbExec() {
 			_activeVerb = kVerbWalkTo;
 			_activeObjectNr = 0;
 			_activeObjectType = 0;
+			_activeObject2Nr = 0;
+			_activeObject2Type = 0;
 		}
 		_walkToObjectIdx = 0;
 		return;


Commit: b5fca08312cdc44142b0183cb8d61235b8ec1e93
    https://github.com/scummvm/scummvm/commit/b5fca08312cdc44142b0183cb8d61235b8ec1e93
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:51-08:00

Commit Message:
make what-is verb work again

Changed paths:
    engines/scumm/verbs.cpp



diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index e70ae49b..30d0d02 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -784,7 +784,7 @@ void ScummEngine_v0::checkExecVerbs() {
 			_activeVerb = kVerbPush;
 		}
 
-		if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
+		if (_mouseAndKeyboardStat > 0 && _mouseAndKeyboardStat < MBS_MAX_KEY) {
 			// TODO: check keypresses
 		} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
 			// click region: sentence line


Commit: f0172ba159b3565f8da77dde9b6d466437fc84d9
    https://github.com/scummvm/scummvm/commit/f0172ba159b3565f8da77dde9b6d466437fc84d9
Author: Tobias Gunkel (tobias.gunkel at gmx.de)
Date: 2012-01-28T22:11:52-08:00

Commit Message:
cleanup

- o5_breakHere() seems to be still needed. For example edna does not manage to walk up the ladder if this is not enabled.
- numLocalObjects seems to be big enough so that < instead of <= can be used. The original interpreter only uses the local ids 0 .. 44 whereas scummvm has _numLocalObjects set to 200.

Changed paths:
    engines/scumm/object.cpp
    engines/scumm/script_v5.cpp



diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 2659786..86d9065 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -499,7 +499,6 @@ 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;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 1d68e86..707c3c2 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2493,11 +2493,8 @@ void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
 	a->startWalkActor(x, y, -1);
 
 	// WORKAROUND: See bug #2971126 for details on why this is here.
-	if (_game.version == 0) {
-		// FIXME(TOBIAS): is this still needed?
-		// (updateScriptPtr/_currentScript might now be called automatically) 
+	if (_game.version == 0)
 		o5_breakHere();
-	}
 }
 
 void ScummEngine_v5::o5_walkActorToActor() {


Commit: ca781b5822a19b460afd2887e67302e46b280460
    https://github.com/scummvm/scummvm/commit/ca781b5822a19b460afd2887e67302e46b280460
Author: Travis Howell (kirben at optusnet.com.au)
Date: 2012-01-28T22:16:14-08:00

Commit Message:
SCUMM: Fix minor compiler warnings.

Changed paths:
    engines/scumm/actor.h
    engines/scumm/scumm_v0.h
    engines/scumm/verbs.h



diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index d8e3692..f081da8 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -343,7 +343,7 @@ enum ActorC64MiscFlags {
 	kActorMiscFlag_10      = 0x10, // ???
 	kActorMiscFlag_20      = 0x20, // ???
 	kActorMiscFlagFreeze   = 0x40, // Stop moving
-	kActorMiscFlagHide     = 0x80, // Hide actor (e.g. dead or wearing radiation suit)
+	kActorMiscFlagHide     = 0x80  // Hide actor (e.g. dead or wearing radiation suit)
 };
 
 class ActorC64 : public Actor_v2 {
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index c2af6d4..ff4a43e 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -36,7 +36,7 @@ protected:
 		kModeCutscene = 0,   // cutscene active
 		kModeKeypad = 1,     // kid selection / dial pad / save-load dialog
 		kModeNoNewKid = 2,   // verb "new kid" disabled (e.g. when entering lab)
-		kModeNormal = 3,     // normal playing mode
+		kModeNormal = 3      // normal playing mode
 	};
 
 	enum ObjectType {
diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h
index fce260e..8085b90 100644
--- a/engines/scumm/verbs.h
+++ b/engines/scumm/verbs.h
@@ -82,7 +82,7 @@ enum VerbPrepsV0 {
 	kVerbPrepWith   = 2,
 	kVerbPrepOn     = 3,
 	kVerbPrepTo     = 4,
-	kVerbPrepObject = 0xFF, // prep depends on object (USE)
+	kVerbPrepObject = 0xFF  // prep depends on object (USE)
 };
 
 } // End of namespace Scumm






More information about the Scummvm-git-logs mailing list