[Scummvm-cvs-logs] scummvm master -> 803c06beb919b35d29bb65ec2e7e48caca69c730

dreammaster dreammaster at scummvm.org
Sat Jun 13 05:24:16 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:
803c06beb9 SHERLOCK: RT: Implement startCAnim


Commit: 803c06beb919b35d29bb65ec2e7e48caca69c730
    https://github.com/scummvm/scummvm/commit/803c06beb919b35d29bb65ec2e7e48caca69c730
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-12T23:23:16-04:00

Commit Message:
SHERLOCK: RT: Implement startCAnim

Changed paths:
    engines/sherlock/objects.cpp
    engines/sherlock/objects.h
    engines/sherlock/people.cpp
    engines/sherlock/people.h
    engines/sherlock/scalpel/scalpel.cpp
    engines/sherlock/scalpel/scalpel_map.cpp
    engines/sherlock/scalpel/scalpel_people.cpp
    engines/sherlock/scalpel/scalpel_scene.cpp
    engines/sherlock/scalpel/scalpel_talk.cpp
    engines/sherlock/scalpel/scalpel_user_interface.cpp
    engines/sherlock/scene.cpp
    engines/sherlock/talk.cpp
    engines/sherlock/tattoo/tattoo.cpp
    engines/sherlock/tattoo/tattoo.h
    engines/sherlock/tattoo/tattoo_people.cpp
    engines/sherlock/tattoo/tattoo_scene.cpp
    engines/sherlock/tattoo/tattoo_talk.cpp



diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index ee04644..954dcc7 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -328,7 +328,7 @@ void Sprite::checkSprite() {
 						break;
 
 					case WALK_AROUND:
-						if (objBounds.contains(people[PLAYER]._walkTo.front())) {
+						if (objBounds.contains(people[HOLMES]._walkTo.front())) {
 							// Reached zone
 							gotoStand();
 						} else {
@@ -374,10 +374,10 @@ void Sprite::checkSprite() {
 									objBounds.right + CLEAR_DIST_X;
 							}
 
-							walkPos.x += people[PLAYER]._imageFrame->_frame.w / 2;
+							walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
 							people._walkDest = walkPos;
-							people[PLAYER]._walkTo.push(walkPos);
-							people[PLAYER].setWalking();
+							people[HOLMES]._walkTo.push(walkPos);
+							people[HOLMES].setWalking();
 						}
 						break;
 
@@ -1313,7 +1313,7 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess
 				scene._goToScene = 100;
 			}
 
-			people[PLAYER]._position = Point32(0, 0);
+			people[HOLMES]._position = Point32(0, 0);
 			break;
 		}
 	} else if (name.hasPrefix("!")) {
@@ -1451,7 +1451,7 @@ int Object::pickUpObject(const char *const messages[]) {
 		} else {
 			// Play generic pickup sequence
 			// Original moved cursor position here
-			people[PLAYER].goAllTheWay();
+			people[HOLMES].goAllTheWay();
 			ui._menuCounter = 25;
 			ui._temp1 = 1;
 		}
@@ -1596,17 +1596,37 @@ void CAnim::load3DO(Common::SeekableReadStream &s) {
 /*----------------------------------------------------------------*/
 
 CAnimStream::CAnimStream() {
-	_stream = nullptr;
-	_frameSize = 0;
 	_images = nullptr;
 	_imageFrame = nullptr;
+	_frameNumber = 0;
 	_flags = 0;
 	_scaleVal = 0;
 	_zPlacement = 0;
 }
 
+CAnimStream::~CAnimStream() {
+	delete _images;
+}
+
+void CAnimStream::load(Common::SeekableReadStream *stream) {
+	delete _images;
+	_images = new ImageFile(*stream, false);
+	_imageFrame = &(*_images)[0];
+	_frameNumber = 0;
+}
+
+void CAnimStream::close() {
+	delete _images;
+	_images = nullptr;
+	_imageFrame = nullptr;
+	_frameNumber = 0;
+}
+
 void CAnimStream::getNextFrame() {
-	// TODO
+	if (++_frameNumber < (int)_images->size())
+		_imageFrame = &(*_images)[_frameNumber];
+	else
+		_imageFrame = nullptr;
 }
 
 /*----------------------------------------------------------------*/
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index 6035bb4..935b4b3 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -464,10 +464,8 @@ struct CAnim {
 };
 
 class CAnimStream {
-	Common::SeekableReadStream *_stream;	// Stream to read frames from
-	int _frameSize;					// Temporary used to store the frame size
-
-	void *_images;					// TOOD: FIgure out hwo to hook up ImageFile with streaming support
+	ImageFile *_images;					
+	int _frameNumber;
 public:
 	ImageFrame *_imageFrame;
 
@@ -480,8 +478,27 @@ public:
 	int _zPlacement;				// Used by doBgAnim for determining Z order
 public:
 	CAnimStream();
+	~CAnimStream();
+
+	/**
+	 * Load the animation's images
+	 */
+	void load(Common::SeekableReadStream *stream);
+
+	/**
+	 * Close any currently active animation
+	 */
+	void close();
 
+	/**
+	 * Get the next frame of the animation
+	 */
 	void getNextFrame();
+
+	/**
+	 * Returns whether the animation is active
+	 */
+	bool active() const { return _imageFrame != nullptr; }
 };
 
 struct SceneImage {
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index 00d77d9..9f1d22b 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -232,7 +232,7 @@ People::~People() {
 }
 
 void People::reset() {
-	_data[PLAYER]->_description = "Sherlock Holmes!";
+	_data[HOLMES]->_description = "Sherlock Holmes!";
 
 	// 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;
@@ -356,9 +356,9 @@ void People::synchronize(Serializer &s) {
 	s.syncAsByte(_holmesOn);
 
 	if (IS_SERRATED_SCALPEL) {
-		s.syncAsSint16LE(_data[PLAYER]->_position.x);
-		s.syncAsSint16LE(_data[PLAYER]->_position.y);
-		s.syncAsSint16LE(_data[PLAYER]->_sequenceNumber);
+		s.syncAsSint16LE(_data[HOLMES]->_position.x);
+		s.syncAsSint16LE(_data[HOLMES]->_position.y);
+		s.syncAsSint16LE(_data[HOLMES]->_sequenceNumber);
 	} else {
 		for (uint idx = 0; idx < _data.size(); ++idx) {
 			Person &p = *_data[idx];
@@ -375,8 +375,8 @@ void People::synchronize(Serializer &s) {
 	s.syncAsSint16LE(_holmesQuotient);
 
 	if (s.isLoading()) {
-		_hSavedPos = _data[PLAYER]->_position;
-		_hSavedFacing = _data[PLAYER]->_sequenceNumber;
+		_hSavedPos = _data[HOLMES]->_position;
+		_hSavedFacing = _data[HOLMES]->_sequenceNumber;
 	}
 }
 
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index 3d035b6..19e050e 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -31,7 +31,8 @@
 namespace Sherlock {
 
 enum PeopleId {
-	PLAYER			= 0,
+	HOLMES			= 0,
+	WATSON			= 1,
 	MAX_NPC_PATH	= 200
 };
 
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
index 4fe3b03..33f8c6b 100644
--- a/engines/sherlock/scalpel/scalpel.cpp
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -961,7 +961,7 @@ void ScalpelEngine::startScene() {
 }
 
 void ScalpelEngine::eraseMirror12() {
-	Common::Point pt((*_people)[PLAYER]._position.x / FIXED_INT_MULTIPLIER, (*_people)[PLAYER]._position.y / FIXED_INT_MULTIPLIER);
+	Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
 
 	// If player is in range of the mirror, then restore background from the secondary back buffer
 	if (Common::Rect(70, 100, 200, 200).contains(pt)) {
@@ -972,13 +972,13 @@ void ScalpelEngine::eraseMirror12() {
 
 void ScalpelEngine::doMirror12() {
 	People &people = *_people;
-	Person &player = people[PLAYER];
+	Person &player = people[HOLMES];
 
-	Common::Point pt((*_people)[PLAYER]._position.x / FIXED_INT_MULTIPLIER, (*_people)[PLAYER]._position.y / FIXED_INT_MULTIPLIER);
+	Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
 	int frameNum = player._walkSequences[player._sequenceNumber][player._frameNumber] +
 		player._walkSequences[player._sequenceNumber][0] - 2;
 
-	switch ((*_people)[PLAYER]._sequenceNumber) {
+	switch ((*_people)[HOLMES]._sequenceNumber) {
 	case WALK_DOWN:
 		frameNum -= 7;
 		break;
@@ -1021,12 +1021,12 @@ void ScalpelEngine::doMirror12() {
 
 	if (Common::Rect(80, 100, 145, 138).contains(pt)) {
 		// Get the frame of Sherlock to draw
-		ImageFrame &imageFrame = (*people[PLAYER]._images)[frameNum];
+		ImageFrame &imageFrame = (*people[HOLMES]._images)[frameNum];
 
 		// Draw the mirror image of Holmes
-		bool flipped = people[PLAYER]._sequenceNumber == WALK_LEFT || people[PLAYER]._sequenceNumber == STOP_LEFT
-			|| people[PLAYER]._sequenceNumber == WALK_UPRIGHT || people[PLAYER]._sequenceNumber == STOP_UPRIGHT
-			|| people[PLAYER]._sequenceNumber == WALK_DOWNLEFT || people[PLAYER]._sequenceNumber == STOP_DOWNLEFT;
+		bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT
+			|| people[HOLMES]._sequenceNumber == WALK_UPRIGHT || people[HOLMES]._sequenceNumber == STOP_UPRIGHT
+			|| people[HOLMES]._sequenceNumber == WALK_DOWNLEFT || people[HOLMES]._sequenceNumber == STOP_DOWNLEFT;
 		_screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped);
 
 		// Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror
@@ -1046,7 +1046,7 @@ void ScalpelEngine::doMirror12() {
 }
 
 void ScalpelEngine::flushMirror12() {
-	Common::Point pt((*_people)[PLAYER]._position.x / FIXED_INT_MULTIPLIER, (*_people)[PLAYER]._position.y / FIXED_INT_MULTIPLIER);
+	Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
 
 	// If player is in range of the mirror, then draw the entire mirror area to the screen
 	if (Common::Rect(70, 100, 200, 200).contains(pt))
diff --git a/engines/sherlock/scalpel/scalpel_map.cpp b/engines/sherlock/scalpel/scalpel_map.cpp
index a9e566f..63cb4a3 100644
--- a/engines/sherlock/scalpel/scalpel_map.cpp
+++ b/engines/sherlock/scalpel/scalpel_map.cpp
@@ -155,7 +155,7 @@ int ScalpelMap::show() {
 	_drawMap = true;
 	_charPoint = -1;
 	_point = -1;
-	people[PLAYER]._position = _lDrawnPos = _overPos;
+	people[HOLMES]._position = _lDrawnPos = _overPos;
 
 	// Show place icons
 	showPlaces();
@@ -233,7 +233,7 @@ int ScalpelMap::show() {
 		}
 
 		if ((events._released || events._rightReleased) && _point != -1) {
-			if (people[PLAYER]._walkCount == 0) {
+			if (people[HOLMES]._walkCount == 0) {
 				people._walkDest = _points[_point] + Common::Point(4, 9);
 				_charPoint = _point;
 
@@ -247,7 +247,7 @@ int ScalpelMap::show() {
 		}
 
 		// Check if a scene has beeen selected and we've finished "moving" to it
-		if (people[PLAYER]._walkCount == 0) {
+		if (people[HOLMES]._walkCount == 0) {
 			if (_charPoint >= 1 && _charPoint < (int)_points.size())
 				exitFlag = true;
 		}
@@ -266,7 +266,7 @@ int ScalpelMap::show() {
 	}
 
 	freeSprites();
-	_overPos = people[PLAYER]._position;
+	_overPos = people[HOLMES]._position;
 
 	// Reset font
 	screen.setFont(oldFont);
@@ -288,7 +288,7 @@ void ScalpelMap::setupSprites() {
 	_shapes = new ImageFile("mapicon.vgs");
 	_iconShapes = new ImageFile("overicon.vgs");
 	_iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height, _vm->getPlatform());
-	Person &p = people[PLAYER];
+	Person &p = people[HOLMES];
 	p._description = " ";
 	p._type = CHARACTER;
 	p._position = Common::Point(12400, 5000);
@@ -353,11 +353,11 @@ void ScalpelMap::showPlaceName(int idx, bool highlighted) {
 	int width = screen.stringWidth(name);
 
 	if (!_cursorIndex) {
-		saveIcon(people[PLAYER]._imageFrame, _lDrawnPos);
+		saveIcon(people[HOLMES]._imageFrame, _lDrawnPos);
 
-		bool flipped = people[PLAYER]._sequenceNumber == MAP_DOWNLEFT || people[PLAYER]._sequenceNumber == MAP_LEFT
-			|| people[PLAYER]._sequenceNumber == MAP_UPLEFT;
-		screen._backBuffer1.transBlitFrom(*people[PLAYER]._imageFrame, _lDrawnPos, flipped);
+		bool flipped = people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT
+			|| people[HOLMES]._sequenceNumber == MAP_UPLEFT;
+		screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, _lDrawnPos, flipped);
 	}
 
 	if (highlighted) {
@@ -390,26 +390,26 @@ void ScalpelMap::updateMap(bool flushScreen) {
 	else
 		_savedPos.x = -1;
 
-	people[PLAYER].adjustSprite();
+	people[HOLMES].adjustSprite();
 
-	_lDrawnPos.x = hPos.x = people[PLAYER]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x;
-	_lDrawnPos.y = hPos.y = people[PLAYER]._position.y / FIXED_INT_MULTIPLIER - people[PLAYER].frameHeight() - _bigPos.y;
+	_lDrawnPos.x = hPos.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x;
+	_lDrawnPos.y = hPos.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight() - _bigPos.y;
 
 	// Draw the person icon
-	saveIcon(people[PLAYER]._imageFrame, hPos);
-	if (people[PLAYER]._sequenceNumber == MAP_DOWNLEFT || people[PLAYER]._sequenceNumber == MAP_LEFT
-			|| people[PLAYER]._sequenceNumber == MAP_UPLEFT)
-		screen._backBuffer1.transBlitFrom(*people[PLAYER]._imageFrame, hPos, true);
+	saveIcon(people[HOLMES]._imageFrame, hPos);
+	if (people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT
+			|| people[HOLMES]._sequenceNumber == MAP_UPLEFT)
+		screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, true);
 	else
-		screen._backBuffer1.transBlitFrom(*people[PLAYER]._imageFrame, hPos, false);
+		screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, false);
 
 	if (flushScreen) {
 		screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
 	} else if (!_drawMap) {
 		if (hPos.x > 0 && hPos.y >= 0 && hPos.x < SHERLOCK_SCREEN_WIDTH && hPos.y < SHERLOCK_SCREEN_HEIGHT)
-			screen.flushImage(people[PLAYER]._imageFrame, Common::Point(people[PLAYER]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x,
-			people[PLAYER]._position.y / FIXED_INT_MULTIPLIER - people[PLAYER].frameHeight() - _bigPos.y),
-			&people[PLAYER]._oldPosition.x, &people[PLAYER]._oldPosition.y, &people[PLAYER]._oldSize.x, &people[PLAYER]._oldSize.y);
+			screen.flushImage(people[HOLMES]._imageFrame, Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x,
+			people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight() - _bigPos.y),
+			&people[HOLMES]._oldPosition.x, &people[HOLMES]._oldPosition.y, &people[HOLMES]._oldSize.x, &people[HOLMES]._oldSize.y);
 
 		if (osPos.x != -1)
 			screen.slamArea(osPos.x, osPos.y, osSize.x, osSize.y);
@@ -428,15 +428,15 @@ void ScalpelMap::walkTheStreets() {
 	const byte *path = _paths.getPath(start, dest);
 
 	// Add in destination position
-	people[PLAYER]._walkTo.clear();
+	people[HOLMES]._walkTo.clear();
 	Common::Point destPos = people._walkDest;
 
 	// Check for any intermediate points between the two locations
 	if (path[0] || _charPoint > 50 || _oldCharPoint > 50) {
-		people[PLAYER]._sequenceNumber = -1;
+		people[HOLMES]._sequenceNumber = -1;
 
 		if (_charPoint == 51 || _oldCharPoint == 51) {
-			people[PLAYER].setWalking();
+			people[HOLMES].setWalking();
 		} else {
 			bool reversePath = false;
 
@@ -453,25 +453,25 @@ void ScalpelMap::walkTheStreets() {
 			} while (*path != 254);
 
 			// Load up the path to use
-			people[PLAYER]._walkTo.clear();
+			people[HOLMES]._walkTo.clear();
 
 			if (reversePath) {
 				for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx)
-					people[PLAYER]._walkTo.push(tempPath[idx]);
+					people[HOLMES]._walkTo.push(tempPath[idx]);
 			} else {
 				for (int idx = 0; idx < (int)tempPath.size(); ++idx)
-					people[PLAYER]._walkTo.push(tempPath[idx]);
+					people[HOLMES]._walkTo.push(tempPath[idx]);
 			}
 
-			people._walkDest = people[PLAYER]._walkTo.pop() + Common::Point(12, 6);
-			people[PLAYER].setWalking();
+			people._walkDest = people[HOLMES]._walkTo.pop() + Common::Point(12, 6);
+			people[HOLMES].setWalking();
 		}
 	} else {
-		people[PLAYER]._walkCount = 0;
+		people[HOLMES]._walkCount = 0;
 	}
 
 	// Store the final destination icon position
-	people[PLAYER]._walkTo.push(destPos);
+	people[HOLMES]._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 b2aa4dc..31be9b4 100644
--- a/engines/sherlock/scalpel/scalpel_people.cpp
+++ b/engines/sherlock/scalpel/scalpel_people.cpp
@@ -52,8 +52,8 @@ 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[PLAYER]._walkTo.empty()) {
-				people._walkDest = people[PLAYER]._walkTo.pop();
+			if (!people[HOLMES]._walkTo.empty()) {
+				people._walkDest = people[HOLMES]._walkTo.pop();
 				setWalking();
 			} else {
 				gotoStand();
@@ -179,8 +179,8 @@ void ScalpelPerson::gotoStand() {
 
 	if (map._active) {
 		_sequenceNumber = 0;
-		people[PLAYER]._position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER;
-		people[PLAYER]._position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER;
+		people[HOLMES]._position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER;
+		people[HOLMES]._position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER;
 	}
 
 	_oldWalkSequence = -1;
@@ -401,14 +401,14 @@ void ScalpelPeople::setTalking(int speaker) {
 
 void ScalpelPeople::synchronize(Serializer &s) {
 	s.syncAsByte(_holmesOn);
-	s.syncAsSint32LE(_data[PLAYER]->_position.x);
-	s.syncAsSint32LE(_data[PLAYER]->_position.y);
-	s.syncAsSint16LE(_data[PLAYER]->_sequenceNumber);
+	s.syncAsSint32LE(_data[HOLMES]->_position.x);
+	s.syncAsSint32LE(_data[HOLMES]->_position.y);
+	s.syncAsSint16LE(_data[HOLMES]->_sequenceNumber);
 	s.syncAsSint16LE(_holmesQuotient);
 
 	if (s.isLoading()) {
-		_hSavedPos = _data[PLAYER]->_position;
-		_hSavedFacing = _data[PLAYER]->_sequenceNumber;
+		_hSavedPos = _data[HOLMES]->_position;
+		_hSavedFacing = _data[HOLMES]->_sequenceNumber;
 	}
 }
 
@@ -442,22 +442,20 @@ void ScalpelPeople::setTalkSequence(int speaker, int sequenceNum) {
 	}
 }
 
-
 bool ScalpelPeople::loadWalk() {
-	Resources &res = *_vm->_res;
 	bool result = false;
 
-	if (_data[PLAYER]->_walkLoaded) {
+	if (_data[HOLMES]->_walkLoaded) {
 		return false;
 	} else {
 		if (_vm->getPlatform() != Common::kPlatform3DO) {
-			_data[PLAYER]->_images = new ImageFile("walk.vgs");
+			_data[HOLMES]->_images = new ImageFile("walk.vgs");
 		} else {
 			// Load walk.anim on 3DO, which is a cel animation file
-			_data[PLAYER]->_images = new ImageFile3DO("walk.anim", kImageFile3DOType_CelAnimation);
+			_data[HOLMES]->_images = new ImageFile3DO("walk.anim", kImageFile3DOType_CelAnimation);
 		}
-		_data[PLAYER]->setImageFrame();
-		_data[PLAYER]->_walkLoaded = true;
+		_data[HOLMES]->setImageFrame();
+		_data[HOLMES]->_walkLoaded = true;
 
 		result = true;
 	}
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index f053747..87fe208 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -138,7 +138,7 @@ void ScalpelScene::drawAllShapes() {
 
 void ScalpelScene::checkBgShapes() {
 	People &people = *_vm->_people;
-	Person &holmes = people[PLAYER];
+	Person &holmes = people[HOLMES];
 	Common::Point pt(holmes._position.x / FIXED_INT_MULTIPLIER, holmes._position.y / FIXED_INT_MULTIPLIER);
 
 	// Call the base scene method to handle bg shapes
@@ -229,14 +229,14 @@ void ScalpelScene::doBgAnim() {
 			vm.eraseMirror12();
 
 		// Restore the back buffer from the back buffer 2 in the changed area
-		Common::Rect bounds(people[PLAYER]._oldPosition.x, people[PLAYER]._oldPosition.y,
-			people[PLAYER]._oldPosition.x + people[PLAYER]._oldSize.x,
-			people[PLAYER]._oldPosition.y + people[PLAYER]._oldSize.y);
+		Common::Rect bounds(people[HOLMES]._oldPosition.x, people[HOLMES]._oldPosition.y,
+			people[HOLMES]._oldPosition.x + people[HOLMES]._oldSize.x,
+			people[HOLMES]._oldPosition.y + people[HOLMES]._oldSize.y);
 		Common::Point pt(bounds.left, bounds.top);
 
-		if (people[PLAYER]._type == CHARACTER)
+		if (people[HOLMES]._type == CHARACTER)
 			screen.restoreBackground(bounds);
-		else if (people[PLAYER]._type == REMOVE)
+		else if (people[HOLMES]._type == REMOVE)
 			screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds);
 
 		for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
@@ -291,8 +291,8 @@ void ScalpelScene::doBgAnim() {
 			_canimShapes[idx].adjustObject();
 	}
 
-	if (people[PLAYER]._type == CHARACTER && people._holmesOn)
-		people[PLAYER].adjustSprite();
+	if (people[HOLMES]._type == CHARACTER && people._holmesOn)
+		people[HOLMES].adjustSprite();
 
 	// Flag the bg shapes which need to be redrawn
 	checkBgShapes();
@@ -331,16 +331,16 @@ void ScalpelScene::doBgAnim() {
 	}
 
 	// Draw the person if not animating
-	if (people[PLAYER]._type == CHARACTER && people[PLAYER]._walkLoaded) {
+	if (people[HOLMES]._type == CHARACTER && people[HOLMES]._walkLoaded) {
 		// If Holmes is too far to the right, move him back so he's on-screen
-		int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[PLAYER]._imageFrame->_frame.w;
-		int tempX = MIN(people[PLAYER]._position.x / FIXED_INT_MULTIPLIER, xRight);
+		int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[HOLMES]._imageFrame->_frame.w;
+		int tempX = MIN(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER, xRight);
 
-		bool flipped = people[PLAYER]._sequenceNumber == WALK_LEFT || people[PLAYER]._sequenceNumber == STOP_LEFT ||
-			people[PLAYER]._sequenceNumber == WALK_UPLEFT || people[PLAYER]._sequenceNumber == STOP_UPLEFT ||
-			people[PLAYER]._sequenceNumber == WALK_DOWNRIGHT || people[PLAYER]._sequenceNumber == STOP_DOWNRIGHT;
-		screen._backBuffer->transBlitFrom(*people[PLAYER]._imageFrame,
-			Common::Point(tempX, people[PLAYER]._position.y / FIXED_INT_MULTIPLIER - people[PLAYER]._imageFrame->_frame.h), flipped);
+		bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT ||
+			people[HOLMES]._sequenceNumber == WALK_UPLEFT || people[HOLMES]._sequenceNumber == STOP_UPLEFT ||
+			people[HOLMES]._sequenceNumber == WALK_DOWNRIGHT || people[HOLMES]._sequenceNumber == STOP_DOWNRIGHT;
+		screen._backBuffer->transBlitFrom(*people[HOLMES]._imageFrame,
+			Common::Point(tempX, people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->_frame.h), flipped);
 	}
 
 	// Draw all static and active shapes are NORMAL and are in front of the person
@@ -390,20 +390,20 @@ void ScalpelScene::doBgAnim() {
 		_animating = 0;
 		screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
 	} else {
-		if (people[PLAYER]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
-			if (people[PLAYER]._type == REMOVE) {
+		if (people[HOLMES]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
+			if (people[HOLMES]._type == REMOVE) {
 				screen.slamRect(Common::Rect(
-					people[PLAYER]._oldPosition.x, people[PLAYER]._oldPosition.y,
-					people[PLAYER]._oldPosition.x + people[PLAYER]._oldSize.x,
-					people[PLAYER]._oldPosition.y + people[PLAYER]._oldSize.y
+					people[HOLMES]._oldPosition.x, people[HOLMES]._oldPosition.y,
+					people[HOLMES]._oldPosition.x + people[HOLMES]._oldSize.x,
+					people[HOLMES]._oldPosition.y + people[HOLMES]._oldSize.y
 				));
-				people[PLAYER]._type = INVALID;
+				people[HOLMES]._type = INVALID;
 			} else {
-				screen.flushImage(people[PLAYER]._imageFrame,
-					Common::Point(people[PLAYER]._position.x / FIXED_INT_MULTIPLIER,
-						people[PLAYER]._position.y / FIXED_INT_MULTIPLIER - people[PLAYER].frameHeight()),
-					&people[PLAYER]._oldPosition.x, &people[PLAYER]._oldPosition.y,
-					&people[PLAYER]._oldSize.x, &people[PLAYER]._oldSize.y);
+				screen.flushImage(people[HOLMES]._imageFrame,
+					Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER,
+						people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight()),
+					&people[HOLMES]._oldPosition.x, &people[HOLMES]._oldPosition.y,
+					&people[HOLMES]._oldSize.x, &people[HOLMES]._oldSize.y);
 			}
 		}
 
@@ -525,8 +525,8 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 
 	if (walkPos.x != -1) {
 		// Holmes must walk to the walk point before the cAnimation is started
-		if (people[PLAYER]._position != walkPos)
-			people[PLAYER].walkToCoords(walkPos, walkDir);
+		if (people[HOLMES]._position != walkPos)
+			people[HOLMES].walkToCoords(walkPos, walkDir);
 	}
 
 	if (talk._talkToAbort)
@@ -563,7 +563,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 
 	if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) {
 		if (tpPos.x != -1)
-			people[PLAYER]._type = REMOVE;
+			people[HOLMES]._type = REMOVE;
 
 		Common::String fname = cAnim._name + ".vgs";
 		if (!res.isInCache(fname)) {
@@ -653,14 +653,14 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 			cObj._frameNumber += dir;
 		}
 
-		people[PLAYER]._type = CHARACTER;
+		people[HOLMES]._type = CHARACTER;
 	}
 
 	// Teleport to ending coordinates if necessary
 	if (tpPos.x != -1) {
-		people[PLAYER]._position = tpPos;	// Place the player
-		people[PLAYER]._sequenceNumber = tpDir;
-		people[PLAYER].gotoStand();
+		people[HOLMES]._position = tpPos;	// Place the player
+		people[HOLMES]._sequenceNumber = tpDir;
+		people[HOLMES].gotoStand();
 	}
 
 	if (playRate < 0)
@@ -686,10 +686,10 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 
 	if (tpPos.x != -1 && !talk._talkToAbort) {
 		// Teleport to ending coordinates
-		people[PLAYER]._position = tpPos;
-		people[PLAYER]._sequenceNumber = tpDir;
+		people[HOLMES]._position = tpPos;
+		people[HOLMES]._sequenceNumber = tpDir;
 
-		people[PLAYER].gotoStand();
+		people[HOLMES].gotoStand();
 	}
 
 	events.setCursor(oldCursor);
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index 5d2ece6..ea5a0fb 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -456,7 +456,7 @@ OpcodeReturn ScalpelTalk::cmdWalkToCoords(const byte *&str) {
 	People &people = *_vm->_people;
 	++str;
 
-	people[PLAYER].walkToCoords(Point32(((str[0] - 1) * 256 + str[1] - 1) * FIXED_INT_MULTIPLIER,
+	people[HOLMES].walkToCoords(Point32(((str[0] - 1) * 256 + str[1] - 1) * FIXED_INT_MULTIPLIER,
 		str[2] * FIXED_INT_MULTIPLIER), str[3] - 1);
 	if (_talkToAbort)
 		return RET_EXIT;
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index cb2bf65..8dd15e5 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -326,7 +326,7 @@ void ScalpelUserInterface::handleInput() {
 			} else {
 				people._walkDest = pt;
 				people._allowWalkAbort = false;
-				people[PLAYER].goAllTheWay();
+				people[HOLMES].goAllTheWay();
 			}
 
 			if (_oldKey != -1) {
@@ -511,7 +511,7 @@ void ScalpelUserInterface::examine() {
 			scene.startCAnim(_cNum, canimSpeed);
 		} else if (obj._lookPosition.y != 0) {
 			// Need to walk to the object to be examined
-			people[PLAYER].walkToCoords(obj._lookPosition, obj._lookFacing);
+			people[HOLMES].walkToCoords(obj._lookPosition, obj._lookFacing);
 		}
 
 		if (!talk._talkToAbort) {
@@ -2236,13 +2236,13 @@ void ScalpelUserInterface::checkAction(ActionType &action, const char *const mes
 					printed = true;
 					if (pt.x != -1)
 						// Holmes needs to walk to object before the action is done
-						people[PLAYER].walkToCoords(pt, dir);
+						people[HOLMES].walkToCoords(pt, dir);
 
 					if (!talk._talkToAbort) {
 						// Ensure Holmes is on the exact intended location
-						people[PLAYER]._position = pt;
-						people[PLAYER]._sequenceNumber = dir;
-						people[PLAYER].gotoStand();
+						people[HOLMES]._position = pt;
+						people[HOLMES]._sequenceNumber = dir;
+						people[HOLMES].gotoStand();
 
 						talk.talkTo(action._names[nameIdx].c_str() + 2);
 						if (ch == 'T')
@@ -2255,7 +2255,7 @@ void ScalpelUserInterface::checkAction(ActionType &action, const char *const mes
 		if (doCAnim && !talk._talkToAbort) {
 			if (pt.x != -1)
 				// Holmes needs to walk to object before the action is done
-				people[PLAYER].walkToCoords(pt, dir);
+				people[HOLMES].walkToCoords(pt, dir);
 		}
 
 		for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 2e80f07..da7f088 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -240,8 +240,8 @@ void Scene::selectScene() {
 		_tempFadeStyle = 0;
 	}
 
-	people._walkDest = Common::Point(people[PLAYER]._position.x / FIXED_INT_MULTIPLIER,
-		people[PLAYER]._position.y / FIXED_INT_MULTIPLIER);
+	people._walkDest = Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER,
+		people[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
 
 	_restoreFlag = true;
 	events.clearEvents();
@@ -964,8 +964,8 @@ void Scene::transitionToScene() {
 				hSavedPos = Point32(160 * FIXED_INT_MULTIPLIER, 100 * FIXED_INT_MULTIPLIER);
 				hSavedFacing = 4;
 			} else {
-				hSavedPos = people[PLAYER]._position;
-				hSavedFacing = people[PLAYER]._sequenceNumber;
+				hSavedPos = people[HOLMES]._position;
+				hSavedFacing = people[HOLMES]._sequenceNumber;
 			}
 		} else {
 			// setup entrance info
@@ -988,8 +988,8 @@ void Scene::transitionToScene() {
 
 	if (hSavedFacing < 101) {
 		// Standard info, so set it
-		people[PLAYER]._position = hSavedPos;
-		people[PLAYER]._sequenceNumber = hSavedFacing;
+		people[HOLMES]._position = hSavedPos;
+		people[HOLMES]._sequenceNumber = hSavedFacing;
 	} else {
 		// It's canimation information
 		cAnimNum = hSavedFacing - 101;
@@ -1001,7 +1001,7 @@ void Scene::transitionToScene() {
 
 	if (cAnimNum != -1) {
 		// Prevent Holmes from being drawn
-		people[PLAYER]._position = Common::Point(0, 0);
+		people[HOLMES]._position = Common::Point(0, 0);
 	}
 
 	for (uint objIdx = 0; objIdx < _bgShapes.size(); ++objIdx) {
@@ -1020,8 +1020,8 @@ void Scene::transitionToScene() {
 			}
 
 			if (Common::Rect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y).contains(
-					Common::Point(people[PLAYER]._position.x / FIXED_INT_MULTIPLIER, 
-					people[PLAYER]._position.y / FIXED_INT_MULTIPLIER))) {
+					Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER, 
+					people[HOLMES]._position.y / FIXED_INT_MULTIPLIER))) {
 				// Current point is already inside box - impact occurred on
 				// a previous call. So simply do nothing except talk until the
 				// player is clear of the box
@@ -1073,7 +1073,7 @@ void Scene::transitionToScene() {
 		PositionFacing pt = c._goto[0];
 
 		c._goto[0].x = c._goto[0].y = -1;
-		people[PLAYER]._position = Common::Point(0, 0);
+		people[HOLMES]._position = Common::Point(0, 0);
 
 		startCAnim(cAnimNum, 1);
 		c._goto[0] = pt;
@@ -1205,7 +1205,7 @@ void Scene::synchronize(Serializer &s) {
 
 void Scene::checkBgShapes() {
 	People &people = *_vm->_people;
-	Person &holmes = people[PLAYER];
+	Person &holmes = people[HOLMES];
 	Common::Point pt(holmes._position.x / FIXED_INT_MULTIPLIER, holmes._position.y / FIXED_INT_MULTIPLIER);
 
 	// Iterate through the shapes
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index 0e9feed..bb8a059 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -169,13 +169,13 @@ void Talk::talkTo(const Common::String &filename) {
 	// Turn on the Exit option
 	ui._endKeyActive = true;
 
-	if (people[PLAYER]._walkCount || people[PLAYER]._walkTo.size() > 0) {
+	if (people[HOLMES]._walkCount || people[HOLMES]._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)
 			abortFlag = true;
 
-		people[PLAYER].gotoStand();
+		people[HOLMES].gotoStand();
 	}
 
 	if (_talkToAbort)
@@ -501,7 +501,7 @@ void Talk::talk(int objNum) {
 		events.setCursor(WAIT);
 		if (obj._lookPosition.y != 0)
 			// Need to walk to character first
-			people[PLAYER].walkToCoords(obj._lookPosition, obj._lookFacing);
+			people[HOLMES].walkToCoords(obj._lookPosition, obj._lookFacing);
 		events.setCursor(ARROW);
 
 		if (!_talkToAbort)
@@ -516,7 +516,7 @@ void Talk::talk(int objNum) {
 		events.setCursor(WAIT);
 		if (obj._lookPosition.y != 0)
 			// Walk over to person to talk to
-			people[PLAYER].walkToCoords(obj._lookPosition, obj._lookFacing);
+			people[HOLMES].walkToCoords(obj._lookPosition, obj._lookFacing);
 		events.setCursor(ARROW);
 
 		if (!_talkToAbort) {
@@ -1318,14 +1318,14 @@ OpcodeReturn Talk::cmdEnableEndKey(const byte *&str) {
 
 OpcodeReturn Talk::cmdHolmesOff(const byte *&str) {
 	People &people = *_vm->_people;
-	people[PLAYER]._type = REMOVE;
+	people[HOLMES]._type = REMOVE;
 
 	return RET_SUCCESS;
 }
 
 OpcodeReturn Talk::cmdHolmesOn(const byte *&str) {
 	People &people = *_vm->_people;
-	people[PLAYER]._type = CHARACTER;
+	people[HOLMES]._type = CHARACTER;
 
 	return RET_SUCCESS;
 }
@@ -1452,7 +1452,7 @@ OpcodeReturn Talk::cmdWalkToCAnimation(const byte *&str) {
 
 	++str;
 	CAnim &animation = scene._cAnim[str[0] - 1];
-	people[PLAYER].walkToCoords(animation._goto[0], animation._goto[0]._facing);
+	people[HOLMES].walkToCoords(animation._goto[0], animation._goto[0]._facing);
 	
 	return _talkToAbort ? RET_EXIT : RET_SUCCESS;
 }
diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp
index 0961601..60803c7 100644
--- a/engines/sherlock/tattoo/tattoo.cpp
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -33,6 +33,7 @@ namespace Tattoo {
 TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
 		SherlockEngine(syst, gameDesc) {
 	_creditsActive = false;
+	_runningProlog = false;
 }
 
 void TattooEngine::showOpening() {
@@ -48,6 +49,7 @@ void TattooEngine::initialize() {
 	// Initialise the global flags
 	_flags.resize(3200);
 	_flags[1] = _flags[4] = _flags[76] = true;
+	_runningProlog = true;
 
 	// Add some more files to the cache
 	_res->addToCache("walk.lib");
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
index 28fa77f..6cafc3f 100644
--- a/engines/sherlock/tattoo/tattoo.h
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -49,6 +49,7 @@ protected:
 	virtual void startScene();
 public:
 	bool _creditsActive;
+	bool _runningProlog;
 public:
 	TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
 	virtual ~TattooEngine() {}
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index f70b079..7560ca1 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -108,7 +108,7 @@ void TattooPerson::adjustSprite() {
 	// See if the player has come to a stop after clicking on an Arrow zone to leave the scene.
 	// If so, this will set up the exit information for the scene transition
 	if (!_walkCount && scene._exitZone != -1 && scene._walkedInScene && scene._goToScene != -1 &&
-			!_description.compareToIgnoreCase(people[PLAYER]._description)) { 
+			!_description.compareToIgnoreCase(people[HOLMES]._description)) { 
 		people._hSavedPos = scene._exits[scene._exitZone]._newPosition;
 		people._hSavedFacing = scene._exits[scene._exitZone]._newFacing;
 
@@ -187,20 +187,20 @@ void TattooPerson::gotoStand() {
 	if (npc != -1 && people[npc]._npcFacing != -1) {
 		if (people[npc]._npcFacing == FACING_PLAYER) {
 			// See where Holmes is with respect to the NPC (x coords)
-			if (people[PLAYER]._position.x < people[npc]._position.x)
+			if (people[HOLMES]._position.x < people[npc]._position.x)
 				people[npc]._npcFacing = STOP_LEFT;
 			else
 				people[npc]._npcFacing = STOP_RIGHT;
 
 			// See where Holmes is with respect to the NPC (y coords)
-			if (people[PLAYER]._position.y < people[npc]._position.y - (10 * FIXED_INT_MULTIPLIER)) {
+			if (people[HOLMES]._position.y < people[npc]._position.y - (10 * FIXED_INT_MULTIPLIER)) {
 				// Holmes is above the NPC so reset the facing to the diagonal ups
 				if (people[npc]._npcFacing == STOP_RIGHT)
 					people[npc]._npcFacing = STOP_UPRIGHT;
 				else
 					people[npc]._npcFacing = STOP_UPLEFT;
 			} else {
-				if (people[PLAYER]._position.y > people[npc]._position.y + (10 * FIXED_INT_MULTIPLIER)) {
+				if (people[HOLMES]._position.y > people[npc]._position.y + (10 * FIXED_INT_MULTIPLIER)) {
 					// Holmes is below the NPC so reset the facing to the diagonal downs
 					if (people[npc]._npcFacing == STOP_RIGHT)
 						people[npc]._npcFacing = STOP_DOWNRIGHT;
@@ -446,7 +446,7 @@ int TattooPeople::findSpeaker(int speaker) {
 	if (result == -1) {
 		bool flag = _vm->readFlags(76);
 
-		if (_data[PLAYER]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag)))
+		if (_data[HOLMES]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag)))
 			return -1;
 
 		for (uint idx = 1; idx < _data.size(); ++idx) {
@@ -481,8 +481,8 @@ void TattooPeople::synchronize(Serializer &s) {
 	s.syncAsSint16LE(_holmesQuotient);
 
 	if (s.isLoading()) {
-		_hSavedPos = _data[PLAYER]->_position;
-		_hSavedFacing = _data[PLAYER]->_sequenceNumber;
+		_hSavedPos = _data[HOLMES]->_position;
+		_hSavedFacing = _data[HOLMES]->_sequenceNumber;
 	}
 }
 
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
index ce20f17..a64c86b 100644
--- a/engines/sherlock/tattoo/tattoo_scene.cpp
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -803,10 +803,134 @@ void TattooScene::setupBGArea(const byte cMap[PALETTE_SIZE]) {
 	}
 }
 
+#define ADJUST_COORD(COORD) if (COORD != -1) COORD *= FIXED_INT_MULTIPLIER
+
 int TattooScene::startCAnim(int cAnimNum, int playRate) {
-	error("TODO: startCAnim");
+	TattooEngine &vm = *(TattooEngine *)_vm;
+	Events &events = *_vm->_events;
+	TattooPeople &people = *(TattooPeople *)_vm->_people;
+	Resources &res = *_vm->_res;
+	Talk &talk = *_vm->_talk;
+	UserInterface &ui = *_vm->_ui;
+
+	// Exit immediately if the anim number is out of range, or the anim doesn't have a position specified
+	if (cAnimNum < 0 || cAnimNum >= (int)_cAnim.size() || _cAnim[cAnimNum]._position.x == -1)
+		// Return out of range error
+		return -1;
+
+	// Get the co-ordinates that the Player & NPC #1 must walk to and end on
+	CAnim &cAnim = _cAnim[cAnimNum];
+	PositionFacing goto1 = cAnim._goto[0];
+	PositionFacing goto2 = cAnim._goto[1];
+	PositionFacing teleport1 = cAnim._teleport[0];
+	PositionFacing teleport2 = cAnim._teleport[1];
+
+	// If the co-ordinates are valid (not -1), adjust them by the fixed int multiplier
+	ADJUST_COORD(goto1.x);
+	ADJUST_COORD(goto1.y);
+	ADJUST_COORD(goto2.x);
+	ADJUST_COORD(goto2.y);
+	ADJUST_COORD(teleport1.x);
+	ADJUST_COORD(teleport1.y);
+	ADJUST_COORD(teleport2.x);
+	ADJUST_COORD(teleport2.y);
+
+	// See if the Player must walk to a position before the animation starts
+	SpriteType savedPlayerType = people[HOLMES]._type;
+	if (goto1.x != -1 && people[HOLMES]._type == CHARACTER) {
+		if (people[HOLMES]._position != goto1)
+			people[HOLMES].walkToCoords(goto1, goto1._facing);
+	}
+
+	if (talk._talkToAbort)
+		return 1;
+
+	// See if NPC #1 must walk to a position before the animation starts
+	SpriteType savedNPCType = people[WATSON]._type;
+	if (goto2.x != -1 && people[WATSON]._type == CHARACTER) {
+		if (people[WATSON]._position != goto2)
+			people[WATSON].walkToCoords(goto2, goto2._facing);
+	}
+
+	if (talk._talkToAbort)
+		return 1;
+
+	// Turn the player (and NPC #1 if neccessary) off before running the canimation
+	if (teleport1.x != -1 && savedPlayerType == CHARACTER)
+		people[HOLMES]._type = REMOVE;
+
+	if (teleport2.x != -1 && savedNPCType == CHARACTER)
+		people[WATSON]._type = REMOVE;
+
+	if (ui._windowOpen)
+		ui.banishWindow();
+	
+	//_activeCAnim._filesize = cAnim._size;
+
+	// Open up the room resource file and get the data for the animation
+	Common::SeekableReadStream *stream = res.load(_rrmName);
+	stream->seek(44 + cAnimNum * 4);
+	stream->seek(stream->readUint32LE());
+	Common::SeekableReadStream *animStream = stream->readStream(cAnim._size);
+	delete stream;
+
+	// Set up the active animation
+	_activeCAnim._position = cAnim._position;
+	_activeCAnim._oldBounds = Common::Rect(0, 0, 0, 0);
+	_activeCAnim._flags = cAnim._flags;
+	_activeCAnim._scaleVal = cAnim._scaleVal;
+	_activeCAnim._zPlacement = 0;
+
+	_activeCAnim.load(animStream);
+
+	while (_activeCAnim.active() && !_vm->shouldQuit()) {
+		doBgAnim();
+
+		events.pollEvents();
+		if (events.kbHit()) {
+			Common::KeyState keyState = events.getKey();
+
+			if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) {
+				_vm->setFlags(-76);
+				_vm->setFlags(396);
+				_goToScene = 1;
+				talk._talkToAbort = true;
+				_activeCAnim.close();
+			}
+		}
+	}
+
+	// Turn the people back on
+	people[HOLMES]._type = savedPlayerType;
+	if (teleport2.x != -1)
+		people[WATSON]._type = savedNPCType;
+
+	// Teleport the Player to the ending coordinates if necessary
+	if (teleport1.x != -1 && savedPlayerType == CHARACTER) {
+		people[HOLMES]._position = teleport1;
+		people[HOLMES]._sequenceNumber = teleport1._facing;
+		people[HOLMES].gotoStand();
+	}
+
+	// Teleport Watson to the ending coordinates if necessary
+	if (teleport2.x != -1 && savedNPCType == CHARACTER) {
+		people[WATSON]._position = teleport2;
+		people[WATSON]._sequenceNumber = teleport2._facing;
+		people[WATSON].gotoStand();
+	}
+
+	// Flag the Canimation to be cleared
+	_activeCAnim._zPlacement = REMOVE;
+	_activeCAnim._removeBounds = _activeCAnim._oldBounds;
+
+	// Free up the animation
+	_activeCAnim.close();
+
+	return 1;
 }
 
+#undef ADJUST_COORD
+
 void TattooScene::setNPCPath(int npc) {
 	TattooPeople &people = *(TattooPeople *)_vm->_people;
 	Talk &talk = *_vm->_talk;
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index 28c0132..3768d12 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -243,7 +243,7 @@ OpcodeReturn TattooTalk::cmdWalkHolmesToCoords(const byte *&str) {
 		x = -1 * (x - 16384);
 	// TODO: The RT walkToCoords call has an extra parameter, person, which is 0 (Holmes) here
 	warning("TODO: cmdWalkHolmesToCoords - call RT walkToCoords variant");
-	people[PLAYER].walkToCoords(Point32(x * FIXED_INT_MULTIPLIER,
+	people[HOLMES].walkToCoords(Point32(x * FIXED_INT_MULTIPLIER,
 		((str[2] - 1) * 256 + str[3] - 1) * FIXED_INT_MULTIPLIER), DIRECTION_CONVERSION[str[4] - 1]);
 	if (_talkToAbort)
 		return RET_EXIT;






More information about the Scummvm-git-logs mailing list