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

dreammaster dreammaster at scummvm.org
Fri Jun 12 05:27:58 CEST 2015


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

Summary:
eb7fb21946 SHERLOCK: Refactor setWalking into Person classes


Commit: eb7fb219464505779ac2ca562291f92788b13c30
    https://github.com/scummvm/scummvm/commit/eb7fb219464505779ac2ca562291f92788b13c30
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-11T23:26:58-04:00

Commit Message:
SHERLOCK: Refactor setWalking into Person classes

Changed paths:
    engines/sherlock/objects.cpp
    engines/sherlock/objects.h
    engines/sherlock/people.cpp
    engines/sherlock/people.h
    engines/sherlock/scalpel/scalpel_map.cpp
    engines/sherlock/scalpel/scalpel_people.cpp
    engines/sherlock/scalpel/scalpel_people.h
    engines/sherlock/scalpel/scalpel_user_interface.cpp
    engines/sherlock/talk.cpp
    engines/sherlock/tattoo/tattoo_people.h



diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 120fb99..19561f6 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -321,7 +321,7 @@ void Sprite::checkSprite() {
 						break;
 
 					case WALK_AROUND:
-						if (objBounds.contains(people._walkTo.front())) {
+						if (objBounds.contains(people[PLAYER]._walkTo.front())) {
 							// Reached zone
 							gotoStand();
 						} else {
@@ -369,8 +369,8 @@ void Sprite::checkSprite() {
 
 							walkPos.x += people[PLAYER]._imageFrame->_frame.w / 2;
 							people._walkDest = walkPos;
-							people._walkTo.push(walkPos);
-							people.setWalking();
+							people[PLAYER]._walkTo.push(walkPos);
+							people[PLAYER].setWalking();
 						}
 						break;
 
@@ -1433,7 +1433,7 @@ int Object::pickUpObject(const char *const messages[]) {
 		} else {
 			// Play generic pickup sequence
 			// Original moved cursor position here
-			people.goAllTheWay();
+			people[PLAYER].goAllTheWay();
 			ui._menuCounter = 25;
 			ui._temp1 = 1;
 		}
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index b9911c7..a22606b 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -309,6 +309,12 @@ public:
 	 * Bring a moving character using the sprite to a standing position
 	 */
 	virtual void gotoStand() = 0;
+
+	/**
+	 * Set the variables for moving a character from one poisition to another
+	 * in a straight line
+	 */
+	virtual void setWalking() = 0;
 };
 
 enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index bb95c51..4ad0b2d 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -27,11 +27,6 @@
 
 namespace Sherlock {
 
-// Walk speeds
-#define MWALK_SPEED 2
-#define XWALK_SPEED 4
-#define YWALK_SPEED 1
-
 // Characer animation sequences
 static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = {
 	{ 29, 1, 2, 3, 4, 5, 6, 7, 0 },		// Walk Right
@@ -80,6 +75,8 @@ Person::Person() : Sprite(), _walkLoaded(false), _npcIndex(0), _npcStack(0), _np
 	_savedNpcFrame = 0;
 	_updateNPCPath = false;
 	_npcPause = false;
+	_oldWalkSequence = -1;
+	_srcZone = _destZone = 0;
 }
 
 void Person::clearNPC() {
@@ -92,6 +89,94 @@ void Person::updateNPC() {
 	// TODO
 }
 
+void Person::goAllTheWay() {
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+	Common::Point srcPt(_position.x / FIXED_INT_MULTIPLIER + frameWidth() / 2,
+		_position.y / FIXED_INT_MULTIPLIER);
+
+	// Get the zone the player is currently in
+	_srcZone = scene.whichZone(srcPt);
+	if (_srcZone == -1)
+		_srcZone = scene.closestZone(srcPt);
+
+	// Get the zone of the destination
+	_destZone = scene.whichZone(people._walkDest);
+	if (_destZone == -1) {
+		_destZone = scene.closestZone(people._walkDest);
+
+		// The destination isn't in a zone
+		if (people._walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1))
+			people._walkDest.x = SHERLOCK_SCREEN_WIDTH - 2;
+
+		// Trace a line between the centroid of the found closest zone to
+		// the destination, to find the point at which the zone will be left
+		const Common::Rect &destRect = scene._zones[_destZone];
+		const Common::Point destCenter((destRect.left + destRect.right) / 2,
+			(destRect.top + destRect.bottom) / 2);
+		const Common::Point delta = people._walkDest - destCenter;
+		Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER);
+
+		// Move along the line until the zone is left
+		do {
+			pt += delta;
+		} while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER));
+
+		// Set the new walk destination to the last point that was in the
+		// zone just before it was left
+		people._walkDest = Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER,
+			(pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER);
+	}
+
+	// Only do a walk if both zones are acceptable
+	if (_srcZone == -2 || _destZone == -2)
+		return;
+
+	// If the start and dest zones are the same, walk directly to the dest point
+	if (_srcZone == _destZone) {
+		setWalking();
+	} else {
+		// Otherwise a path needs to be formed from the path information
+		int i = scene._walkDirectory[_srcZone][_destZone];
+
+		// See if we need to use a reverse path
+		if (i == -1)
+			i = scene._walkDirectory[_destZone][_srcZone];
+
+		int count = scene._walkData[i];
+		++i;
+
+		// See how many points there are between the src and dest zones
+		if (!count || count == -1) {
+			// There are none, so just walk to the new zone
+			setWalking();
+		} else {
+			// There are points, so set up a multi-step path between points
+			// to reach the given destination
+			_walkTo.clear();
+
+			if (scene._walkDirectory[_srcZone][_destZone] != -1) {
+				i += 3 * (count - 1);
+				for (int idx = 0; idx < count; ++idx, i -= 3) {
+					_walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]),
+						scene._walkData[i + 2]));
+				}
+			} else {
+				for (int idx = 0; idx < count; ++idx, i += 3) {
+					_walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2]));
+				}
+			}
+
+			// Final position
+			_walkTo.push(people._walkDest);
+
+			// Start walking
+			people._walkDest = _walkTo.pop();
+			setWalking();
+		}
+	}
+}
+
 /*----------------------------------------------------------------*/
 
 People *People::init(SherlockEngine *vm) {
@@ -103,12 +188,10 @@ People *People::init(SherlockEngine *vm) {
 
 People::People(SherlockEngine *vm) : _vm(vm) {
 	_holmesOn = true;
-	_oldWalkSequence = -1;
 	_allowWalkAbort = false;
 	_portraitLoaded = false;
 	_portraitsOn = true;
 	_clearingThePortrait = false;
-	_srcZone = _destZone = 0;
 	_talkPics = nullptr;
 	_portraitSide = 0;
 	_speakerFlip = false;
@@ -140,7 +223,7 @@ void People::reset() {
 	// Note: Serrated Scalpel only uses a single Person slot for Sherlock.. Watson is handled by scene sprites
 	int count = IS_SERRATED_SCALPEL ? 1 : MAX_CHARACTERS;
 	for (int idx = 0; idx < count; ++idx) {
-		Sprite &p = *_data[idx];
+		Person &p = *_data[idx];
 
 		p._type = (idx == 0) ? CHARACTER : INVALID;
 		if (IS_SERRATED_SCALPEL)
@@ -173,6 +256,7 @@ void People::reset() {
 		p._adjust = Common::Point(0, 0);
 
 		// Load the default walk sequences
+		p._walkTo.clear();
 		p._oldWalkSequence = -1;
 		p._walkSequences.clear();
 		if (IS_SERRATED_SCALPEL) {
@@ -187,9 +271,6 @@ void People::reset() {
 			}
 		}
 	}
-
-	// Reset any walk path in progress when Sherlock leaves scenes
-	_walkTo.clear();
 }
 
 bool People::loadWalk() {
@@ -286,152 +367,6 @@ bool People::freeWalk() {
 	return result;
 }
 
-void People::setWalking() {
-	Map &map = *_vm->_map;
-	Scene &scene = *_vm->_scene;
-	int oldDirection, oldFrame;
-	Common::Point speed, delta;
-
-	// Flag that player has now walked in the scene
-	scene._walkedInScene = true;
-
-	// Stop any previous walking, since a new dest is being set
-	_data[PLAYER]->_walkCount = 0;
-	oldDirection = _data[PLAYER]->_sequenceNumber;
-	oldFrame = _data[PLAYER]->_frameNumber;
-
-	// Set speed to use horizontal and vertical movement
-	if (map._active) {
-		speed = Common::Point(MWALK_SPEED, MWALK_SPEED);
-	} else {
-		speed = Common::Point(XWALK_SPEED, YWALK_SPEED);
-	}
-
-	// If the player is already close to the given destination that no
-	// walking is needed, move to the next straight line segment in the
-	// overall walking route, if there is one
-	for (;;) {
-		// Since we want the player to be centered on the destination they
-		// clicked, but characters draw positions start at their left, move
-		// the destination half the character width to draw him centered
-		int temp;
-		if (_walkDest.x >= (temp = _data[PLAYER]->_imageFrame->_frame.w / 2))
-			_walkDest.x -= temp;
-
-		delta = Common::Point(
-			ABS(_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER - _walkDest.x),
-			ABS(_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER - _walkDest.y)
-		);
-
-		// If we're ready to move a sufficient distance, that's it. Otherwise,
-		// move onto the next portion of the walk path, if there is one
-		if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
-			break;
-
-		// Pop next walk segment off the walk route stack
-		_walkDest = _walkTo.pop();
-	}
-
-	// If a sufficient move is being done, then start the move
-	if (delta.x > 3 || delta.y) {
-		// See whether the major movement is horizontal or vertical
-		if (delta.x >= delta.y) {
-			// Set the initial frame sequence for the left and right, as well
-			// as setting the delta x depending on direction
-			if (_walkDest.x < (_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER)) {
-				_data[PLAYER]->_sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT);
-				_data[PLAYER]->_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
-			} else {
-				_data[PLAYER]->_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT);
-				_data[PLAYER]->_delta.x = speed.x * FIXED_INT_MULTIPLIER;
-			}
-
-			// See if the x delta is too small to be divided by the speed, since
-			// this would cause a divide by zero error
-			if (delta.x >= speed.x) {
-				// Det the delta y
-				_data[PLAYER]->_delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
-				if (_walkDest.y < (_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER))
-					_data[PLAYER]->_delta.y = -_data[PLAYER]->_delta.y;
-
-				// Set how many times we should add the delta to the player's position
-				_data[PLAYER]->_walkCount = delta.x / speed.x;
-			} else {
-				// The delta x was less than the speed (ie. we're really close to
-				// the destination). So set delta to 0 so the player won't move
-				_data[PLAYER]->_delta = Point32(0, 0);
-				_data[PLAYER]->_position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER);
-assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/
-				_data[PLAYER]->_walkCount = 1;
-			}
-
-			// See if the sequence needs to be changed for diagonal walking
-			if (_data[PLAYER]->_delta.y > 150) {
-				if (!map._active) {
-					switch (_data[PLAYER]->_sequenceNumber) {
-					case Scalpel::WALK_LEFT:
-						_data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWNLEFT;
-						break;
-					case Scalpel::WALK_RIGHT:
-						_data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWNRIGHT;
-						break;
-					}
-				}
-			} else if (_data[PLAYER]->_delta.y < -150) {
-				if (!map._active) {
-					switch (_data[PLAYER]->_sequenceNumber) {
-					case Scalpel::WALK_LEFT:
-						_data[PLAYER]->_sequenceNumber = Scalpel::WALK_UPLEFT;
-						break;
-					case Scalpel::WALK_RIGHT:
-						_data[PLAYER]->_sequenceNumber = Scalpel::WALK_UPRIGHT;
-						break;
-					}
-				}
-			}
-		} else {
-			// Major movement is vertical, so set the sequence for up and down,
-			// and set the delta Y depending on the direction
-			if (_walkDest.y < (_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER)) {
-				_data[PLAYER]->_sequenceNumber = Scalpel::WALK_UP;
-				_data[PLAYER]->_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
-			} else {
-				_data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWN;
-				_data[PLAYER]->_delta.y = speed.y * FIXED_INT_MULTIPLIER;
-			}
-
-			// If we're on the overhead map, set the sequence so we keep moving
-			// in the same direction
-			if (map._active)
-				_data[PLAYER]->_sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;
-
-			// Set the delta x
-			_data[PLAYER]->_delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y);
-			if (_walkDest.x < (_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER))
-				_data[PLAYER]->_delta.x = -_data[PLAYER]->_delta.x;
-
-			_data[PLAYER]->_walkCount = delta.y / speed.y;
-		}
-	}
-
-	// See if the new walk sequence is the same as the old. If it's a new one,
-	// we need to reset the frame number to zero so it's animation starts at
-	// it's beginning. Otherwise, if it's the same sequence, we can leave it
-	// as is, so it keeps the animation going at wherever it was up to
-	if (_data[PLAYER]->_sequenceNumber != _oldWalkSequence)
-		_data[PLAYER]->_frameNumber = 0;
-	_oldWalkSequence = _data[PLAYER]->_sequenceNumber;
-
-	if (!_data[PLAYER]->_walkCount)
-		_data[PLAYER]->gotoStand();
-
-	// If the sequence is the same as when we started, then Holmes was
-	// standing still and we're trying to re-stand him, so reset Holmes'
-	// rame to the old frame number from before it was reset to 0
-	if (_data[PLAYER]->_sequenceNumber == oldDirection)
-		_data[PLAYER]->_frameNumber = oldFrame;
-}
-
 void People::walkToCoords(const Point32 &destPos, int destDir) {
 	Events &events = *_vm->_events;
 	Scene &scene = *_vm->_scene;
@@ -442,7 +377,7 @@ void People::walkToCoords(const Point32 &destPos, int destDir) {
 
 	_walkDest = Common::Point(destPos.x / FIXED_INT_MULTIPLIER + 10, destPos.y / FIXED_INT_MULTIPLIER);
 	_allowWalkAbort = true;
-	goAllTheWay();
+	_data[PLAYER]->goAllTheWay();
 
 	// Keep calling doBgAnim until the walk is done
 	do {
@@ -466,93 +401,6 @@ assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/
 	}
 }
 
-void People::goAllTheWay() {
-	Scene &scene = *_vm->_scene;
-	Common::Point srcPt(_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER + _data[PLAYER]->frameWidth() / 2,
-		_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER);
-
-	// Get the zone the player is currently in
-	_srcZone = scene.whichZone(srcPt);
-	if (_srcZone == -1)
-		_srcZone = scene.closestZone(srcPt);
-
-	// Get the zone of the destination
-	_destZone = scene.whichZone(_walkDest);
-	if (_destZone == -1) {
-		_destZone = scene.closestZone(_walkDest);
-
-		// The destination isn't in a zone
-		if (_walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1))
-			_walkDest.x = SHERLOCK_SCREEN_WIDTH - 2;
-
-		// Trace a line between the centroid of the found closest zone to
-		// the destination, to find the point at which the zone will be left
-		const Common::Rect &destRect = scene._zones[_destZone];
-		const Common::Point destCenter((destRect.left + destRect.right) / 2,
-			(destRect.top + destRect.bottom) / 2);
-		const Common::Point delta = _walkDest - destCenter;
-		Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER);
-
-		// Move along the line until the zone is left
-		do {
-			pt += delta;
-		} while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER));
-
-		// Set the new walk destination to the last point that was in the
-		// zone just before it was left
-		_walkDest = Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER,
-			(pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER);
-	}
-
-	// Only do a walk if both zones are acceptable
-	if (_srcZone == -2 || _destZone == -2)
-		return;
-
-	// If the start and dest zones are the same, walk directly to the dest point
-	if (_srcZone == _destZone) {
-		setWalking();
-	} else {
-		// Otherwise a path needs to be formed from the path information
-		int i = scene._walkDirectory[_srcZone][_destZone];
-
-		// See if we need to use a reverse path
-		if (i == -1)
-			i = scene._walkDirectory[_destZone][_srcZone];
-
-		int count = scene._walkData[i];
-		++i;
-
-		// See how many points there are between the src and dest zones
-		if (!count || count == -1) {
-			// There are none, so just walk to the new zone
-			setWalking();
-		} else {
-			// There are points, so set up a multi-step path between points
-			// to reach the given destination
-			_walkTo.clear();
-
-			if (scene._walkDirectory[_srcZone][_destZone] != -1) {
-				i += 3 * (count - 1);
-				for (int idx = 0; idx < count; ++idx, i -= 3) {
-					_walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]),
-						scene._walkData[i + 2]));
-				}
-			} else {
-				for (int idx = 0; idx < count; ++idx, i += 3) {
-					_walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2]));
-				}
-			}
-
-			// Final position
-			_walkTo.push(_walkDest);
-
-			// Start walking
-			_walkDest = _walkTo.pop();
-			setWalking();
-		}
-	}
-}
-
 int People::findSpeaker(int speaker) {
 	Scene &scene = *_vm->_scene;
 	const char *portrait = _characters[speaker]._portrait;
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index 6d8389d..2b99091 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -59,6 +59,7 @@ struct PersonData {
 class Person : public Sprite {
 public:
 	Common::Queue<Common::Point> _walkTo;
+	int _srcZone, _destZone;
 	bool _walkLoaded;
 	Common::String _portrait;
 
@@ -83,6 +84,13 @@ public:
 	virtual ~Person() {}
 
 	/**
+	 * Called to set the character walking to the current cursor location.
+	 * It uses the zones and the inter-zone points to determine a series
+	 * of steps to walk to get to that position.
+	 */
+	void goAllTheWay();
+
+	/**
 	 * Clear the NPC related data
 	 */
 	void clearNPC();
@@ -99,8 +107,6 @@ class People {
 protected:
 	SherlockEngine *_vm;
 	Common::Array<Person *> _data;
-	int _oldWalkSequence;
-	int _srcZone, _destZone;
 
 	People(SherlockEngine *vm);
 public:
@@ -109,7 +115,6 @@ public:
 	Common::Point _walkDest;
 	Point32 _hSavedPos;
 	int _hSavedFacing;
-	Common::Queue<Common::Point> _walkTo;
 	bool _holmesOn;
 	bool _portraitLoaded;
 	bool _portraitsOn;
@@ -147,25 +152,11 @@ public:
 	bool freeWalk();
 
 	/**
-	 * Set the variables for moving a character from one poisition to another
-	 * in a straight line - goAllTheWay must have been previously called to
-	 * check for any obstacles in the path.
-	 */
-	void setWalking();
-
-	/**
 	 * Walk to the co-ordinates passed, and then face the given direction
 	 */
 	void walkToCoords(const Point32 &destPos, int destDir);
 
 	/**
-	 * Called to set the character walking to the current cursor location.
-	 * It uses the zones and the inter-zone points to determine a series
-	 * of steps to walk to get to that position.
-	 */
-	void goAllTheWay();
-
-	/**
 	 * Finds the scene background object corresponding to a specified speaker
 	 */
 	int findSpeaker(int speaker);
diff --git a/engines/sherlock/scalpel/scalpel_map.cpp b/engines/sherlock/scalpel/scalpel_map.cpp
index 3957f27..a9e566f 100644
--- a/engines/sherlock/scalpel/scalpel_map.cpp
+++ b/engines/sherlock/scalpel/scalpel_map.cpp
@@ -428,7 +428,7 @@ void ScalpelMap::walkTheStreets() {
 	const byte *path = _paths.getPath(start, dest);
 
 	// Add in destination position
-	people._walkTo.clear();
+	people[PLAYER]._walkTo.clear();
 	Common::Point destPos = people._walkDest;
 
 	// Check for any intermediate points between the two locations
@@ -436,7 +436,7 @@ void ScalpelMap::walkTheStreets() {
 		people[PLAYER]._sequenceNumber = -1;
 
 		if (_charPoint == 51 || _oldCharPoint == 51) {
-			people.setWalking();
+			people[PLAYER].setWalking();
 		} else {
 			bool reversePath = false;
 
@@ -453,25 +453,25 @@ void ScalpelMap::walkTheStreets() {
 			} while (*path != 254);
 
 			// Load up the path to use
-			people._walkTo.clear();
+			people[PLAYER]._walkTo.clear();
 
 			if (reversePath) {
 				for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx)
-					people._walkTo.push(tempPath[idx]);
+					people[PLAYER]._walkTo.push(tempPath[idx]);
 			} else {
 				for (int idx = 0; idx < (int)tempPath.size(); ++idx)
-					people._walkTo.push(tempPath[idx]);
+					people[PLAYER]._walkTo.push(tempPath[idx]);
 			}
 
-			people._walkDest = people._walkTo.pop() + Common::Point(12, 6);
-			people.setWalking();
+			people._walkDest = people[PLAYER]._walkTo.pop() + Common::Point(12, 6);
+			people[PLAYER].setWalking();
 		}
 	} else {
 		people[PLAYER]._walkCount = 0;
 	}
 
 	// Store the final destination icon position
-	people._walkTo.push(destPos);
+	people[PLAYER]._walkTo.push(destPos);
 }
 
 void ScalpelMap::saveIcon(ImageFrame *src, const Common::Point &pt) {
diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp
index 4fcdff0..e3cd1e5 100644
--- a/engines/sherlock/scalpel/scalpel_people.cpp
+++ b/engines/sherlock/scalpel/scalpel_people.cpp
@@ -28,6 +28,13 @@ namespace Sherlock {
 
 namespace Scalpel {
 
+// Walk speeds
+#define MWALK_SPEED 2
+#define XWALK_SPEED 4
+#define YWALK_SPEED 1
+
+/*----------------------------------------------------------------*/
+
 void ScalpelPerson::adjustSprite() {
 	Map &map = *_vm->_map;
 	People &people = *_vm->_people;
@@ -45,9 +52,9 @@ void ScalpelPerson::adjustSprite() {
 		if (!_walkCount) {
 			// If there any points left for the character to walk to along the
 			// route to a destination, then move to the next point
-			if (!people._walkTo.empty()) {
-				people._walkDest = people._walkTo.pop();
-				people.setWalking();
+			if (!people[PLAYER]._walkTo.empty()) {
+				people._walkDest = people[PLAYER]._walkTo.pop();
+				setWalking();
 			} else {
 				gotoStand();
 			}
@@ -129,7 +136,6 @@ void ScalpelPerson::adjustSprite() {
 	}
 }
 
-
 void ScalpelPerson::gotoStand() {
 	ScalpelMap &map = *(ScalpelMap *)_vm->_map;
 	People &people = *_vm->_people;
@@ -181,6 +187,153 @@ void ScalpelPerson::gotoStand() {
 	people._allowWalkAbort = true;
 }
 
+void ScalpelPerson::setWalking() {
+	Map &map = *_vm->_map;
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+	int oldDirection, oldFrame;
+	Common::Point speed, delta;
+
+	// Flag that player has now walked in the scene
+	scene._walkedInScene = true;
+
+	// Stop any previous walking, since a new dest is being set
+	_walkCount = 0;
+	oldDirection = _sequenceNumber;
+	oldFrame = _frameNumber;
+
+	// Set speed to use horizontal and vertical movement
+	if (map._active) {
+		speed = Common::Point(MWALK_SPEED, MWALK_SPEED);
+	} else {
+		speed = Common::Point(XWALK_SPEED, YWALK_SPEED);
+	}
+
+	// If the player is already close to the given destination that no
+	// walking is needed, move to the next straight line segment in the
+	// overall walking route, if there is one
+	for (;;) {
+		// Since we want the player to be centered on the destination they
+		// clicked, but characters draw positions start at their left, move
+		// the destination half the character width to draw him centered
+		int temp;
+		if (people._walkDest.x >= (temp = _imageFrame->_frame.w / 2))
+			people._walkDest.x -= temp;
+
+		delta = Common::Point(
+			ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x),
+			ABS(_position.y / FIXED_INT_MULTIPLIER - people._walkDest.y)
+		);
+
+		// If we're ready to move a sufficient distance, that's it. Otherwise,
+		// move onto the next portion of the walk path, if there is one
+		if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
+			break;
+
+		// Pop next walk segment off the walk route stack
+		people._walkDest = _walkTo.pop();
+	}
+
+	// If a sufficient move is being done, then start the move
+	if (delta.x > 3 || delta.y) {
+		// See whether the major movement is horizontal or vertical
+		if (delta.x >= delta.y) {
+			// Set the initial frame sequence for the left and right, as well
+			// as setting the delta x depending on direction
+			if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
+				_sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT);
+				_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
+			} else {
+				_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT);
+				_delta.x = speed.x * FIXED_INT_MULTIPLIER;
+			}
+
+			// See if the x delta is too small to be divided by the speed, since
+			// this would cause a divide by zero error
+			if (delta.x >= speed.x) {
+				// Det the delta y
+				_delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
+				if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER))
+					_delta.y = -_delta.y;
+
+				// Set how many times we should add the delta to the player's position
+				_walkCount = delta.x / speed.x;
+			} else {
+				// The delta x was less than the speed (ie. we're really close to
+				// the destination). So set delta to 0 so the player won't move
+				_delta = Point32(0, 0);
+				_position = Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, people._walkDest.y * FIXED_INT_MULTIPLIER);
+
+				_walkCount = 1;
+			}
+
+			// See if the sequence needs to be changed for diagonal walking
+			if (_delta.y > 150) {
+				if (!map._active) {
+					switch (_sequenceNumber) {
+					case Scalpel::WALK_LEFT:
+						_sequenceNumber = Scalpel::WALK_DOWNLEFT;
+						break;
+					case Scalpel::WALK_RIGHT:
+						_sequenceNumber = Scalpel::WALK_DOWNRIGHT;
+						break;
+					}
+				}
+			} else if (_delta.y < -150) {
+				if (!map._active) {
+					switch (_sequenceNumber) {
+					case Scalpel::WALK_LEFT:
+						_sequenceNumber = Scalpel::WALK_UPLEFT;
+						break;
+					case Scalpel::WALK_RIGHT:
+						_sequenceNumber = Scalpel::WALK_UPRIGHT;
+						break;
+					}
+				}
+			}
+		} else {
+			// Major movement is vertical, so set the sequence for up and down,
+			// and set the delta Y depending on the direction
+			if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
+				_sequenceNumber = Scalpel::WALK_UP;
+				_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
+			} else {
+				_sequenceNumber = Scalpel::WALK_DOWN;
+				_delta.y = speed.y * FIXED_INT_MULTIPLIER;
+			}
+
+			// If we're on the overhead map, set the sequence so we keep moving
+			// in the same direction
+			if (map._active)
+				_sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;
+
+			// Set the delta x
+			_delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y);
+			if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER))
+				_delta.x = -_delta.x;
+
+			_walkCount = delta.y / speed.y;
+		}
+	}
+
+	// See if the new walk sequence is the same as the old. If it's a new one,
+	// we need to reset the frame number to zero so it's animation starts at
+	// it's beginning. Otherwise, if it's the same sequence, we can leave it
+	// as is, so it keeps the animation going at wherever it was up to
+	if (_sequenceNumber != _oldWalkSequence)
+		_frameNumber = 0;
+	_oldWalkSequence = _sequenceNumber;
+
+	if (!_walkCount)
+		gotoStand();
+
+	// If the sequence is the same as when we started, then Holmes was
+	// standing still and we're trying to re-stand him, so reset Holmes'
+	// rame to the old frame number from before it was reset to 0
+	if (_sequenceNumber == oldDirection)
+		_frameNumber = oldFrame;
+}
+
 /*----------------------------------------------------------------*/
 
 ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) {
diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h
index cc4e6b6..cd6deac 100644
--- a/engines/sherlock/scalpel/scalpel_people.h
+++ b/engines/sherlock/scalpel/scalpel_people.h
@@ -55,6 +55,12 @@ public:
 	 * Bring a moving character to a standing position
 	 */
 	virtual void gotoStand();
+
+	/**
+	 * Set the variables for moving a character from one poisition to another
+	 * in a straight line
+	 */
+	virtual void setWalking();
 };
 
 class ScalpelPeople : public People {
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index a334632..2f89dce 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -319,7 +319,7 @@ void ScalpelUserInterface::handleInput() {
 			} else {
 				people._walkDest = pt;
 				people._allowWalkAbort = false;
-				people.goAllTheWay();
+				people[PLAYER].goAllTheWay();
 			}
 
 			if (_oldKey != -1) {
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index 60ab53c..17e7333 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -167,7 +167,7 @@ void Talk::talkTo(const Common::String &filename) {
 	// Turn on the Exit option
 	ui._endKeyActive = true;
 
-	if (people[PLAYER]._walkCount || people._walkTo.size() > 0) {
+	if (people[PLAYER]._walkCount || people[PLAYER]._walkTo.size() > 0) {
 		// Only interrupt if an action if trying to do an action, and not just
 		// if the player is walking around the scene
 		if (people._allowWalkAbort)
diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h
index 773f00b..9022c42 100644
--- a/engines/sherlock/tattoo/tattoo_people.h
+++ b/engines/sherlock/tattoo/tattoo_people.h
@@ -92,7 +92,7 @@ public:
 	 * Set the variables for moving a character from one poisition to another
 	 * in a straight line
 	 */
-	void setWalking();
+	virtual void setWalking();
 };
 
 class TattooPeople : public People {






More information about the Scummvm-git-logs mailing list