[Scummvm-cvs-logs] SF.net SVN: scummvm:[48269] scummvm/trunk/engines/scumm

Kirben at users.sourceforge.net Kirben at users.sourceforge.net
Tue Mar 16 09:59:48 CET 2010


Revision: 48269
          http://scummvm.svn.sourceforge.net/scummvm/?rev=48269&view=rev
Author:   Kirben
Date:     2010-03-16 08:59:48 +0000 (Tue, 16 Mar 2010)

Log Message:
-----------
Add patch #2970176 - V0: MM Verb + Anim Fix.

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/actor.cpp
    scummvm/trunk/engines/scumm/costume.cpp
    scummvm/trunk/engines/scumm/costume.h
    scummvm/trunk/engines/scumm/script_v0.cpp
    scummvm/trunk/engines/scumm/scumm.h
    scummvm/trunk/engines/scumm/verbs.cpp

Modified: scummvm/trunk/engines/scumm/actor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/actor.cpp	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/actor.cpp	2010-03-16 08:59:48 UTC (rev 48269)
@@ -215,6 +215,12 @@
 void Actor::stopActorMoving() {
 	if (_walkScript)
 		_vm->stopScript(_walkScript);
+
+	// V0 Games will walk on the spot if the actor is stopped mid-walk
+	// So we must set the stand still frame
+	if (_vm->_game.version == 0)
+		startWalkAnim(3, -1);
+
 	_moving = 0;
 }
 

Modified: scummvm/trunk/engines/scumm/costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/costume.cpp	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/costume.cpp	2010-03-16 08:59:48 UTC (rev 48269)
@@ -75,6 +75,13 @@
 	0x17, 0x00, 0x01, 0x05, 0x16
 };
 
+const byte v0ActorTalkArray[0x19] = {
+	0x00, 0x06, 0x06, 0x06, 0x06, 
+	0x06, 0x06, 0x00, 0x46, 0x06, 
+	0x06, 0x06, 0x06, 0xFF, 0xFF, 
+	0x06, 0xC0, 0x06, 0x06, 0x00, 
+	0xC0, 0xC0, 0x00, 0x06, 0x06
+};
 
 byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
 	int i, skip = 0;
@@ -1341,6 +1348,10 @@
 }
 
 void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
+
+	if ((v0ActorTalkArray[ a->_number ] & 0x80))
+		return;
+
 	if ((a->_speaking & 0x80))
 		cmd += 0x0C;
 	else
@@ -1356,6 +1367,9 @@
 
 	// Enable/Disable speaking flag
 	if (frame == a->_talkStartFrame) {
+		if ((v0ActorTalkArray[ a->_number ] & 0x40))
+			return;
+
 		A->_speaking = 1;
 		return;
 	}
@@ -1393,16 +1407,8 @@
 		int cmd = A->_costCommand;
 		A->_speakingPrev = A->_speaking;
 
-		// Update to use speak frame
-		if (A->_speaking & 0x80) {
-			actorSpeak(A, cmd);
+		actorSpeak(A, cmd);
 
-		} else {
-			// Update to use stand frame
-			if (A->_costFrame == A->_standFrame)
-				cmd = dirToDirStop(cmd);
-		}
-
 		// Update the limb frames
 		frameUpdate(A, cmd);
 	}
@@ -1410,7 +1416,11 @@
 	if (A->_moving  && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
 		if (a->_cost.soundPos == 0)
 			a->_cost.soundCounter++;
-		a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
+		
+		// Is this the correct location?
+		// 0x073C
+		if ((v0ActorTalkArray[ a->_number ] & 0x3F))
+			a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
 	}
 
 	// increase each frame pos

Modified: scummvm/trunk/engines/scumm/costume.h
===================================================================
--- scummvm/trunk/engines/scumm/costume.h	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/costume.h	2010-03-16 08:59:48 UTC (rev 48269)
@@ -28,7 +28,6 @@
 #include "scumm/base-costume.h"
 
 namespace Scumm {
-
 class ClassicCostumeLoader : public BaseCostumeLoader {
 public:
 	int _id;

Modified: scummvm/trunk/engines/scumm/script_v0.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v0.cpp	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/script_v0.cpp	2010-03-16 08:59:48 UTC (rev 48269)
@@ -635,7 +635,19 @@
 
 	a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
 
-	a->putActor(0, 0, room);
+	//0x634F
+	if ((((ActorC64*) a)->_miscflags & 0x40)) {
+
+		// TODO: Check if this is the correct function
+		// to be calling here
+		stopObjectCode();
+		return;
+	}
+
+	// The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
+	// This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
+	// This scripts runs before the actor position is set to the correct location
+	a->putActor(a->getPos().x, a->getPos().y, room);
 	_egoPositioned = false;
 
 	startScene(a->_room, a, obj);
@@ -815,6 +827,10 @@
 	else
 		a->_miscflags &= ~mask;
 
+	// This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!')
+	if (a->_miscflags & 0x40)
+		a->stopActorMoving();
+
 	debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
 }
 

Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/scumm.h	2010-03-16 08:59:48 UTC (rev 48269)
@@ -878,8 +878,9 @@
 	void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
 public:
 	int getObjectOrActorXY(int object, int &x, int &y);	// Used in actor.cpp, hence public
+	int getDist(int x, int y, int x2, int y2);	// Also used in actor.cpp
 protected:
-	int getDist(int x, int y, int x2, int y2);
+
 	int getObjActToObjActDist(int a, int b); // Not sure how to handle
 	const byte *getObjOrActorName(int obj);		 // these three..
 	void setObjectName(int obj);

Modified: scummvm/trunk/engines/scumm/verbs.cpp
===================================================================
--- scummvm/trunk/engines/scumm/verbs.cpp	2010-03-16 08:43:46 UTC (rev 48268)
+++ scummvm/trunk/engines/scumm/verbs.cpp	2010-03-16 08:59:48 UTC (rev 48269)
@@ -154,10 +154,27 @@
 }
 
 void ScummEngine_v0::switchActor(int slot) {
+	resetSentence(false);
+	
+	if (_currentRoom == 45)
+		return;
+
+	// radiation suit? don't let the player switch
+	if (VAR(VAR_EGO) == 8)
+		return;
+
+	// verbs disabled? or just new kid button?
+	if (_currentMode == 0 || _currentMode == 1 || _currentMode == 2)
+		return;
+
+	// verbs disabled for the current actor
+	ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "switchActor");
+	if (a->_miscflags & 0x40)
+		return;
+
 	VAR(VAR_EGO) = VAR(97 + slot);
+	resetVerbs();
 	actorFollowCamera(VAR(VAR_EGO));
-	resetVerbs();
-	resetSentence(false);
 	setUserState(247);
 }
 
@@ -668,6 +685,18 @@
 void ScummEngine_v0::runObject(int obj, int entry) {
 	int 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
+		//  it merely seems to be some type of fallback)
+		if (getVerbEntrypoint(obj, 0x0F) != 0) {
+
+			entry = 0x0F;
+		}
+	}
+	
+	_v0ObjectInInventory = prev;
+
 	if (getVerbEntrypoint(obj, entry) != 0) {
 		_v0ObjectInInventory = prev;
 		runObjectScript(obj, entry, false, false, NULL);
@@ -698,17 +727,17 @@
 }
 
 bool ScummEngine_v0::verbMoveToActor(int actor) {
-	Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
-	Actor *a2 =derefActor(actor, "checkExecVerbs");
+	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) {
-		int dist =  getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
-		if (dist > 8)
-			a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, 1);
-		else
+	if (!a->_moving && dist > 4) {
+		a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1);
+	} else {
+		if (dist <= 4) {
+			a->stopActorMoving();
 			return false;
-
-		return true;
+		}
 	}
 
 	return true;
@@ -716,21 +745,22 @@
 
 bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
 	int x, y, dir;
-	Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+	Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
 
 	if (_currentMode != 3 && _currentMode != 2)
 		return false;
 
-	if (a->_moving)
-		return true;
-
 	_v0ObjectIndex = true;
 	getObjectXYPos(objectIndex, x, y, dir);
 	_v0ObjectIndex = false;
+
 	// Detect distance from target object
 	int dist =  getDist(a->getRealPos().x, a->getRealPos().y, x, y);
 
-	if (dist > 8) {
+	if (a->_moving)
+		return true;
+
+	if (dist > 5) {
 		a->startWalkActor(x, y, dir);
 		VAR(6) = x;
 		VAR(7) = y;
@@ -766,6 +796,7 @@
 	if (objIndex == 0)
 		return false;
 
+	// Object in inventory ?
 	if (where != WIO_INVENTORY) {
 		_v0ObjectIndex = true;
 		prep = verbPrep(objIndex);
@@ -778,13 +809,29 @@
 		} else {
 			_verbPickup = false;
 		}
+		
+		// Ignore verbs?
+		Actor *a = derefActor(VAR(VAR_EGO), "verbObtain");
+		if ((((ActorC64*) a)->_miscflags & 0x40)) {
+			resetSentence(false);
+			return false;
+		}
 
+		//attempt move to object
 		if (verbMove(obj, objIndex, false))
 			return true;
 
 		if (didPickup && (prep == 1 || prep == 4))
-			if (_activeVerb != 13 && _activeVerb != 14)
-				_activeInventory = obj;
+			if (_activeVerb != 13 && _activeVerb != 14) {
+				_v0ObjectInInventory = true;
+
+				if (whereIsObject( obj ) == WIO_INVENTORY)
+					_activeInventory = obj;
+				else
+					resetSentence();
+
+				_v0ObjectInInventory = false;
+			}
 	}
 
 	return false;
@@ -795,6 +842,7 @@
 		_v0ObjectIndex = true;
 	else
 		_v0ObjectIndex = false;
+
 	byte *ptr = getOBCDFromObject(object);
 	_v0ObjectIndex = false;
 	assert(ptr);
@@ -831,6 +879,7 @@
 		_activeObjectObtained = true;
 	}
 
+	// Attempt to obtain/reach object2
 	if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
 		prep = verbPrep(_activeObject2Index);
 
@@ -852,10 +901,16 @@
 	// Give-To
 	if (_activeVerb == 3 && _activeInventory && _activeActor) {
 		// FIXME: Actors need to turn and face each other
-		// And walk to each other
-		if (verbMoveToActor(_activeActor))
+		if (verbMoveToActor(_activeActor)) {
+			// Ignore verbs?
+			Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
+			if ((((ActorC64*) a)->_miscflags & 0x40)) {
+				resetSentence(false);
+				return false;
+			}
+
 			return true;
-
+		}
 		_v0ObjectInInventory = true;
 		VAR(5) = _activeActor;
 		runObject(_activeInventory , 3);
@@ -865,6 +920,7 @@
 		return false;
 	}
 
+	// Where we performing an action on an actor?
 	if (_activeActor) {
 		_v0ObjectIndex = true;
 		runObject(_activeActor, entry);
@@ -905,13 +961,16 @@
 		return false;
 	}
 
+	// Item not in inventory is executed
 	if (_activeObject) {
 		_v0ObjectIndex = true;
 		runObject(_activeObjectIndex, entry);
 		_v0ObjectIndex = false;
 	} else if (_activeInventory) {
+		// Not sure this is the correct way to do this, 
+		// however its working for most situations - segra
 		if (verbExecutes(_activeInventory, true) == false) {
-			if (_activeObject2 && verbExecutes(_activeObject2, true)) {
+			if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) {
 				_v0ObjectInInventory = true;
 
 				_activeObject = _activeInventory;
@@ -920,11 +979,17 @@
 				runObject(_activeObject, _activeVerb);
 			} else {
 				_v0ObjectInInventory = true;
-				runObject(_activeInventory, _activeVerb);
+					
+				if (_activeObject2) {
+					_activeObject = _activeObject2;
+
+					runObject(_activeObject, _activeVerb);
+				} else
+					runObject(_activeInventory, _activeVerb);
 			}
 		} else {
+			_v0ObjectInInventory = true;
 			runObject(_activeInventory, _activeVerb);
-			_v0ObjectInInventory = true;
 		}
 	}
 
@@ -941,7 +1006,7 @@
 }
 
 void ScummEngine_v0::checkExecVerbs() {
-	Actor *a;
+	Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
 	VirtScreen *zone = findVirtScreen(_mouse.y);
 
 	// Is a verb currently executing
@@ -961,10 +1026,10 @@
 			if (!obj && !act && !over) {
 				resetSentence(false);
 			} else {
-				a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
 				a->stopActorMoving();
 			}
 		} else {
+
 			if (_verbExecuting && !verbExec())
 				return;
 		}
@@ -994,14 +1059,37 @@
 			// TODO
 		} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
 			int prevInventory = _activeInventory;
+			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;
+
+			// 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;
@@ -1019,7 +1107,7 @@
 				if (!_activeObject2 || prevInventory != _activeObject2)
 					return;
 
-			if (_activeVerb == 11 && !((!(_activeObject || _activeInventory)) || !_activeObject2))
+			if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2))
 				return;
 		} else {
 			int over = findVerbAtPos(_mouse.x, _mouse.y);
@@ -1027,6 +1115,8 @@
 			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;
@@ -1037,10 +1127,12 @@
 				// Disable New-Kid (in the secret lab)
 				if (_currentMode == 2 || _currentMode == 0)
 					return;
-
-				if (_activeVerb != 7) {
-					_activeVerb = over;
-					over = 0;
+				
+				if (!(((ActorC64*) a)->_miscflags & 0x80)) {
+					if (_activeVerb != 7) {
+						_activeVerb = over;
+						over = 0;
+					}
 				}
 
 				if (over) {
@@ -1064,9 +1156,14 @@
 				VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
 
 				if (zone->number == kMainVirtScreen) {
-					a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+					// Ignore verbs?
+					if ((((ActorC64*) a)->_miscflags & 0x40)) {
+						resetSentence(false);
+						return;
+					}
 					a->stopActorMoving();
-					a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
+					a->startWalkActor(VAR(6), VAR(7), -1);
+					_verbExecuting = true;
 				}
 				return;
 			}
@@ -1120,6 +1217,8 @@
 						}
 					}
 				} else {
+					a->stopActorMoving();
+
 					_activeObject = obj;
 					_activeObjectIndex = objIdx;
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list