[Scummvm-cvs-logs] scummvm master -> 5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc

dreammaster dreammaster at scummvm.org
Sun Jun 14 15:00:00 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:
5364b46d6a SHERLOCK: RT: Move checkObject from Object to BaseObject


Commit: 5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc
    https://github.com/scummvm/scummvm/commit/5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-14T08:56:00-04:00

Commit Message:
SHERLOCK: RT: Move checkObject from Object to BaseObject

checkObject needs to be called in checkSprite now, which is in
the Sprite class. So the method and a few others it depeends
on have been moved into BaseObject

Changed paths:
    engines/sherlock/objects.cpp
    engines/sherlock/objects.h
    engines/sherlock/scalpel/scalpel_scene.cpp



diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 29c5d73..df91995 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -70,10 +70,15 @@ static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = {
 	{ "ITDOWNRG", 8, 0, 0 }
 };
 
-SherlockEngine *Sprite::_vm;
+SherlockEngine *BaseObject::_vm;
 
 /*----------------------------------------------------------------*/
 
+void BaseObject::setVm(SherlockEngine *vm) {
+	_vm = vm;
+	_countCAnimFrames = false;
+}
+
 BaseObject::BaseObject() {
 	_type = INVALID;
 	_sequences = nullptr;
@@ -156,1023 +161,1114 @@ bool BaseObject::hasAborts() const {
 	return true;
 }
 
-/*----------------------------------------------------------------*/
-
-void Sprite::clear() {
-	_name = "";
-	_description = "";
-	_examine.clear();
-	_pickUp = "";
-	_walkSequences.clear();
-	_sequences = nullptr;
-	_images = nullptr;
-	_imageFrame = nullptr;
-	_walkCount = 0;
-	_allow = 0;
-	_frameNumber = _sequenceNumber = 0;
-	_position.x = _position.y = 0;
-	_delta.x = _delta.y = 0;
-	_oldPosition.x = _oldPosition.y = 0;
-	_oldSize.x = _oldSize.y = 0;
-	_goto.x = _goto.y = 0;
-	_type = INVALID;
-	_pickUp.clear();
-	_noShapeSize.x = _noShapeSize.y = 0;
-	_status = 0;
-	_misc = 0;
-	_altImages = nullptr;
-	_altSeq = 0;
-	Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
-}
-
-void Sprite::setImageFrame() {
-	int frameNum = MAX(_frameNumber, 0);
-	int imageNumber = _walkSequences[_sequenceNumber][frameNum];
-	
-	if (IS_SERRATED_SCALPEL)
-		imageNumber = imageNumber + _walkSequences[_sequenceNumber][0] - 2;
-	else if (imageNumber > _maxFrames)
-		imageNumber = 1;
+void BaseObject::checkObject() {
+	Scene &scene = *_vm->_scene;
+	Sound &sound = *_vm->_sound;
+	Talk &talk = *_vm->_talk;
+	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+	bool codeFound;
 
-	// Get the images to use
-	ImageFile *images = _altSeq ? _altImages : _images;
-	assert(images);
+	if (_seqTo) {
+		byte *ptr = &_sequences[_frameNumber];
+		if (*ptr == _seqTo) {
+			// The sequence is completed
+			*ptr = _seqTo + SEQ_TO_CODE + 128;	// Reset to normal
+			_seqTo = 0;
+		} else {
+			// Continue doing sequence
+			if (*ptr > _seqTo)
+				*ptr -= 1;
+			else
+				*ptr += 1;
 
-	if (_vm->getPlatform() == Common::kPlatform3DO) {
-		// only do this to the image-array with 110 entries
-		// map uses another image-array and this code
-		if (images->size() == 110) {
-			// 3DO has 110 animation frames inside walk.anim
-			// PC has 55
-			// this adjusts the framenumber accordingly
-			// sort of HACK
-			imageNumber *= 2;
+			return;
 		}
-	} else if (IS_ROSE_TATTOO) {
-		--imageNumber;
 	}
 
-	// Set the frame pointer
-	_imageFrame = &(*images)[imageNumber];
-}
-
-void Sprite::checkSprite() {
-	Events &events = *_vm->_events;
-	People &people = *_vm->_people;
-	Scene &scene = *_vm->_scene;
-	Screen &screen = *_vm->_screen;
-	Talk &talk = *_vm->_talk;
-	Point32 pt;
-	Common::Rect objBounds;
-	Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
-
-	if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
-		return;
-
-	pt = _walkCount ? _position + _delta : _position;
-	pt.x /= FIXED_INT_MULTIPLIER;
-	pt.y /= FIXED_INT_MULTIPLIER;
+	++_frameNumber;
 
-	if (IS_ROSE_TATTOO) {
-		// TODO: Needs to be called
-		//checkObject(1001);
+	do {
+		// Check for end of sequence
+		codeFound = checkEndOfSequence();
 
-		// For Rose Tattoo, we only do the further processing for Sherlock
-		if (this != &people[HOLMES])
-			return;
-	}
+		if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
+			codeFound = true;
+			int v = _sequences[_frameNumber];
 
-	for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
-		Object &obj = scene._bgShapes[idx];
-		if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
-			continue;
+			// Check for a Talk or Listen Sequence
+			if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
+				if (_gotoSeq) {
+					setObjTalkSequence(_gotoSeq);
+				} else {
+					++_frameNumber;
+				}
+			} else if (IS_ROSE_TATTOO && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE)) {
+				if (_talkSeq)
+					setObjTalkSequence(_talkSeq);
+				else
+					setObjSequence(0, false);
+			} else  if (v >= GOTO_CODE) {
+				// Goto code found
+				v -= GOTO_CODE;
+				_seqCounter2 = _seqCounter;
+				_seqStack = _frameNumber + 1;
+				setObjSequence(v, false);
+			} else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
+				codeFound = true;
+				++_frameNumber;
+				v -= SOUND_CODE + (IS_SERRATED_SCALPEL ? 1 : 0);
 
-		if (obj._type == NO_SHAPE) {
-			objBounds = Common::Rect(obj._position.x, obj._position.y,
-				obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
-		} else {
-			int xp = obj._position.x + obj._imageFrame->_offset.x;
-			int yp = obj._position.y + obj._imageFrame->_offset.y;
-			objBounds = Common::Rect(xp, yp,
-				xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
-		}
+				if (sound._soundOn && !_countCAnimFrames) {
+					if (!scene._sounds[v]._name.empty() && sound._digitized)
+						sound.playLoadedSound(v, WAIT_RETURN_IMMEDIATELY);
+				}
+			} else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) {
+				// Flip code
+				codeFound = true;
+				++_frameNumber;
+				v -= FLIP_CODE;
 
-		if (objBounds.contains(pt)) {
-			if (objBounds.contains(spritePt)) {
-				// Current point is already inside the the bounds, so impact occurred
-				// on a previous call. So simply do nothing until we're clear of the box
-				switch (obj._aType) {
-				case TALK_MOVE:
-					if (_walkCount) {
-						// Holmes is moving
-						obj._type = HIDDEN;
-						obj.setFlagsAndToggles();
-						talk.talkTo(obj._use[0]._target);
-					}
+				// Alter the flipped status
+				switch (v) {
+				case 0:
+					// Clear the flag
+					_flags &= ~OBJ_FLIPPED;
+					break;
+				case 1:
+					// Set the flag
+					_flags |= OBJ_FLIPPED;
+					break;
+				case 2:
+					// Toggle the flag
+					_flags ^= OBJ_FLIPPED;
 					break;
+				default:
+					break;
+				}
+			} else if (IS_ROSE_TATTOO && v == TELEPORT_CODE) {
+				_position.x = READ_LE_UINT16(&_sequences[_frameNumber + 1]);
+				_position.y = READ_LE_UINT16(&_sequences[_frameNumber + 3]);
 
-				case PAL_CHANGE:
-				case PAL_CHANGE2:
-					if (_walkCount) {
-						int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
-						int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
-						int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
-						if (templ == 0)
-							templ = 100;
+				_frameNumber += 5;
+			} else if (IS_ROSE_TATTOO && v == CALL_TALK_CODE) {
+				Common::String filename;
+				for (int idx = 0; idx < 8; ++idx) {
+					if (_sequences[_frameNumber + 1 + idx] != 1)
+						filename += (char)_sequences[_frameNumber + 1 + idx];
+					else
+						break;
+				}
 
-						// Ensure only valid palette change data found
-						if (palLength > 0) {
-							// Figure out how far into the shape Holmes is so that we
-							// can figure out what percentage of the original palette
-							// to set the current palette to
-							int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
-							palPercent = palPercent * templ / 100;
-							if (obj._aType == PAL_CHANGE)
-								// Invert percentage
-								palPercent = 100 - palPercent;
+				_frameNumber += 8;
+				talk.talkTo(filename);
 
-							for (int i = palStart; i < (palStart + palLength); ++i)
-								screen._sMap[i] = screen._cMap[i] * palPercent / 100;
+			} else if (IS_ROSE_TATTOO && v == HIDE_CODE) {
+				switch (_sequences[_frameNumber + 2]) {
+				case 1:
+					// Hide Object
+					if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type != HIDDEN)
+						scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
+					break;
 
-							events.pollEvents();
-							screen.setPalette(screen._sMap);
-						}
-					}
+				case 2:
+					// Activate Object
+					if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type == HIDDEN)
+						scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
 					break;
 
-				case TALK:
-				case TALK_EVERY:
-					obj._type = HIDDEN;
-					obj.setFlagsAndToggles();
-					talk.talkTo(obj._use[0]._target);
+				case 3:
+					// Toggle Object
+					scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
 					break;
 
 				default:
 					break;
 				}
+				_frameNumber += 3;
+			
 			} else {
-				// New impact just occurred
-				switch (obj._aType) {
-				case BLANK_ZONE:
-					// A blank zone masks out all other remaining zones underneath it.
-					// If this zone is hit, exit the outer loop so we do not check anymore
-					return;
-
-				case SOLID:
-				case TALK:
-					// Stop walking
-					if (obj._aType == TALK) {
-						obj.setFlagsAndToggles();
-						talk.talkTo(obj._use[0]._target);
-					} else {
-						gotoStand();
-					}
-					break;
+				v -= 128;
 
-				case TALK_EVERY:
-					if (obj._aType == TALK_EVERY) {
-						obj._type = HIDDEN;
-						obj.setFlagsAndToggles();
-						talk.talkTo(obj._use[0]._target);
-					} else {
-						gotoStand();
-					}
-					break;
+				// 68-99 is a squence code
+				if (v > SEQ_TO_CODE) {
+					byte *p = &_sequences[_frameNumber];
+					v -= SEQ_TO_CODE;	// # from 1-32
+					_seqTo = v;
+					*p = *(p - 1);
 
-				case FLAG_SET:
-					obj.setFlagsAndToggles();
-					obj._type = HIDDEN;
-					break;
+					if (*p > 128)
+						// If the high bit is set, convert to a real frame
+						*p -= (byte)(SEQ_TO_CODE - 128);
 
-				case WALK_AROUND:
-					if (objBounds.contains(people[HOLMES]._walkTo.front())) {
-						// Reached zone
-						gotoStand();
-					} else {
-						// Destination not within box, walk to best corner
-						Common::Point walkPos;
+					if (*p > _seqTo)
+						*p -= 1;
+					else
+						*p += 1;
 
-						if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
-							// Impact occurred due to vertical movement. Determine whether to
-							// travel to the left or right side
-							if (_delta.x > 0)
-								// Go to right side
-								walkPos.x = objBounds.right + CLEAR_DIST_X;
-							else if (_delta.x < 0) {
-								// Go to left side
-								walkPos.x = objBounds.left - CLEAR_DIST_X;
-							} else {
-								// Going straight up or down. So choose best side
-								if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
-									walkPos.x = objBounds.right + CLEAR_DIST_X;
-								else
-									walkPos.x = objBounds.left - CLEAR_DIST_X;
-							}
+					// Will be incremented below to return back to original value
+					--_frameNumber;
+					v = 0;
 
-							walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
-								objBounds.bottom + CLEAR_DIST_Y;
-						} else {
-							// Impact occurred due to horizontal movement
-							if (_delta.y > 0)
-								// Go to bottom of box
-								walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
-							else if (_delta.y < 0)
-								// Go to top of box
-								walkPos.y = objBounds.top - CLEAR_DIST_Y;
-							else {
-								// Going straight horizontal, so choose best side
-								if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
-									walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
-								else
-									walkPos.y = objBounds.top - CLEAR_DIST_Y;
-							}
+				} else if (IS_ROSE_TATTOO && v == 10) {
+					// Set delta for objects
+					_delta = Common::Point(READ_LE_UINT16(&_sequences[_frameNumber + 1]), 
+						READ_LE_UINT16(&_sequences[_frameNumber + 3]));
+					_noShapeSize = Common::Point(0, 0);
+					_frameNumber += 4;
 
-							walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
-								objBounds.right + CLEAR_DIST_X;
-						}
+				} else if (v == 10) {
+					// Set delta for objects
+					Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
+					if (pt.x > 128)
+						pt.x = (pt.x - 128) *  -1;
+					else
+						pt.x--;
 
-						walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
-						people._walkDest = walkPos;
-						people[HOLMES]._walkTo.push(walkPos);
-						people[HOLMES].setWalking();
-					}
-					break;
+					if (pt.y > 128)
+						pt.y = (pt.y - 128) * -1;
+					else
+						pt.y--;
 
-				case DELTA:
-					_position.x += 200;
-					break;
+					_delta = pt;
+					_frameNumber += 2;
 
-				default:
-					break;
+				} else if (v < USE_COUNT) {
+					for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+						checkNameForCodes(_use[v]._names[idx], nullptr);
+					}
+
+					if (_use[v]._useFlag)
+						_vm->setFlags(_use[v]._useFlag);
 				}
+
+				++_frameNumber;
 			}
 		}
-	}
+	} while (codeFound);
 }
 
-const Common::Rect Sprite::getOldBounds() const {
-	return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
-}
+bool BaseObject::checkEndOfSequence() {
+	Screen &screen = *_vm->_screen;
+	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+	bool result = false;
 
-void Sprite::setObjTalkSequence(int seq) {
-	assert(seq != -1 && _type == CHARACTER);
+	if (_type == REMOVE || _type == INVALID)
+		return false;
 
-	if (_seqTo) {
-		// reset to previous value
-		_walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo;
-		_seqTo = 0;
+	if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
+		result = true;
+
+		if (_frameNumber >= (checkFrame - 1)) {
+			_frameNumber = START_FRAME;
+		}  else {
+			// Determine next sequence to use
+			int seq = _sequences[_frameNumber + 1];
+
+			if (seq == 99) {
+				--_frameNumber;
+				screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
+				screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
+				_type = INVALID;
+			} else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
+				setObjTalkSequence(_talkSeq);
+			} else {
+				setObjSequence(seq, false);
+			}
+		}
+
+		if (_allow && _frameNumber == 0) {
+			// canimation just ended
+			if (_type != NO_SHAPE && _type != REMOVE) {
+				_type = REMOVE;
+
+				if (!_countCAnimFrames) {
+					// Save details before shape is removed
+					_delta.x = _imageFrame->_frame.w;
+					_delta.y = _imageFrame->_frame.h;
+					_position += _imageFrame->_offset;
+
+					// Free the images
+					delete _images;
+					_images = nullptr;
+					_imageFrame = nullptr;
+				}
+			} else {
+				_type = INVALID;
+			}
+		}
 	}
 
-	_sequenceNumber = _gotoSeq;
-	_frameNumber = 0;
-	checkWalkGraphics();
+	return result;
 }
 
-void Sprite::checkWalkGraphics() {
-	People &people = *_vm->_people;
+void BaseObject::setObjSequence(int seq, bool wait) {
+	Scene &scene = *_vm->_scene;
+	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
 
-	if (_images == nullptr) {
-		freeAltGraphics();
-		return;
-	}
+	if (seq >= 128) {
+		// Loop the sequence until the count exceeded
+		seq -= 128;
 
-	Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str());
+		++_seqCounter;
+		if (_seqCounter >= seq) {
+			// Go to next sequence
+			if (_seqStack) {
+				_frameNumber = _seqStack;
+				_seqStack = 0;
+				_seqCounter = _seqCounter2;
+				_seqCounter2 = 0;
+				if (_frameNumber >= checkFrame)
+					_frameNumber = START_FRAME;
 
-	// Set the adjust depending on if we have to fine tune the x position of this particular graphic
-	_adjust.x = _adjust.y = 0;
+				return;
+			}
 
-	for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) {
-		if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName, 
-				strlen(ADJUST_WALKS[idx]._vgsName))) {
-			if (_walkSequences[_sequenceNumber]._horizFlip)
-				_adjust.x = ADJUST_WALKS[idx]._flipXAdjust;
+			_frameNumber += 2;
+			if (_frameNumber >= checkFrame)
+				_frameNumber = 0;
+
+			_seqCounter = 0;
+			if (_sequences[_frameNumber] == 0)
+				seq = _sequences[_frameNumber + 1];
 			else
-				_adjust.x = ADJUST_WALKS[idx]._xAdjust;
+				return;
+		} else {
+			// Find beginning of sequence
+			do {
+				--_frameNumber;
+			} while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
 
-			_adjust.y = ADJUST_WALKS[idx]._yAdjust;
-			break;
+			if (_frameNumber != 0)
+				_frameNumber += 2;
+
+			return;
 		}
+	} else {
+		// Reset sequence counter
+		_seqCounter = 0;
 	}
 
-	// See if we're already using Alternate Graphics
-	if (_altSeq) {
-		// See if the VGS file called for is different than the alternate graphics already loaded
-		if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) {
-			// Different AltGraphics, Free the old ones
-			freeAltGraphics();
+	int idx = 0;
+	int seqCc = 0;
+
+	while (seqCc < seq && idx < checkFrame) {
+		++idx;
+		if (_sequences[idx] == 0) {
+			++seqCc;
+			idx += 2;
 		}
 	}
 
-	// If there is no Alternate Sequence set, see if we need to load a new one
-	if (!_altSeq) {
-		int npcNum = -1;
-		// Find which NPC this is so we can check the name of the graphics loaded
-		for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
-			if (this == &people[idx]) {
-				npcNum = idx;
-				break;
-			}
-		}
+	if (idx >= checkFrame)
+		idx = 0;
+	_frameNumber = idx;
 
-		if (npcNum != -1) {
-			// See if the VGS file called for is different than the main graphics which are already loaded
-			if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) {
-				// See if this is one of the more used Walk Graphics stored in WALK.LIB
-				for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) {
-					if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) {
-						people._useWalkLib = true;
-						break;
-					}
-				}
-
-				_altImages = new ImageFile(filename);
-				people._useWalkLib = false;
-
-				_altSeq = _sequenceNumber + 1;
-			}
-		}
-	}
+	if (wait) {
+		seqCc = idx;
+		while (_sequences[idx] != 0)
+			++idx;
 
-	// If this is a different seqeunce from the current sequence, reset the appropriate variables
-	if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {		
-		_seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
-		_sequences = &_walkSequences[_sequenceNumber]._sequences[0];
-		_seqSize = _walkSequences[_sequenceNumber]._sequences.size();
+		idx = idx - seqCc + 2;
+		for (; idx > 0; --idx)
+			scene.doBgAnim();
 	}
-
-	setImageFrame();
 }
 
-void Sprite::freeAltGraphics() {
-	if (_altImages != nullptr) {
-		delete _altImages;
-		_altImages = nullptr;
-	}
-
-	_altSeq = 0;
-}
+int BaseObject::checkNameForCodes(const Common::String &name, const char *const messages[]) {
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+	Screen &screen = *_vm->_screen;
+	Talk &talk = *_vm->_talk;
+	UserInterface &ui = *_vm->_ui;
+	bool printed = false;
 
-/*----------------------------------------------------------------*/
+	scene.toggleObject(name);
 
-void WalkSequence::load(Common::SeekableReadStream &s) {
-	char buffer[9];
-	s.read(buffer, 9);
-	_vgsName = Common::String(buffer);
-	_horizFlip = s.readByte() != 0;
+	if (name.hasPrefix("*")) {
+		// A code was found
+		printed = true;
+		char ch = (name == "*") ? 0 : toupper(name[1]);
 
-	_sequences.resize(s.readUint16LE());
-	s.skip(4);		// Skip over pointer field of structure
+		switch (ch) {
+		case 'C':
+			talk.talkTo(name.c_str() + 2);
+			break;
 
-	s.read(&_sequences[0], _sequences.size());
-}
+		case 'T':
+		case 'B':
+		case 'F':
+		case 'W':
+			// Nothing: action was already done before canimation
+			break;
 
-/*----------------------------------------------------------------*/
+		case 'G':
+		case 'A': {
+			// G: Have object go somewhere
+			// A: Add onto existing co-ordinates
+			Common::String sx(name.c_str() + 2, name.c_str() + 5);
+			Common::String sy(name.c_str() + 6, name.c_str() + 9);
 
-WalkSequences &WalkSequences::operator=(const WalkSequences &src) {
-	resize(src.size());
-	for (uint idx = 0; idx < size(); ++idx) {
-		const WalkSequence &wSrc = src[idx];
-		WalkSequence &wDest = (*this)[idx];
-		wDest._horizFlip = wSrc._horizFlip;
+			if (ch == 'G')
+				_position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+			else
+				_position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+			break;
+		}
 
-		wDest._sequences.resize(wSrc._sequences.size());
-		Common::copy(&wSrc._sequences[0], &wSrc._sequences[0] + wSrc._sequences.size(), &wDest._sequences[0]);
-	}
+		default:
+			if (ch >= '0' && ch <= '9') {
+				scene._goToScene = atoi(name.c_str() + 1);
 
-	return *this;
-}
+				if (IS_SERRATED_SCALPEL && scene._goToScene < 97) {
+					Scalpel::ScalpelMap &map = *(Scalpel::ScalpelMap *)_vm->_map;
+					if (map[scene._goToScene].x) {
+						map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
+						map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
+					}
+				}
 
-/*----------------------------------------------------------------*/
+				const char *p;
+				if ((p = strchr(name.c_str(), ',')) != nullptr) {
+					++p;
 
-ActionType::ActionType() {
-	_cAnimNum = _cAnimSpeed = 0;
-}
+					Common::String s(p, p + 3);
+					people._hSavedPos.x = atoi(s.c_str());
 
-void ActionType::load(Common::SeekableReadStream &s) {
-	char buffer[12];
+					s = Common::String(p + 3, p + 6);
+					people._hSavedPos.y = atoi(s.c_str());
 
-	_cAnimNum = s.readByte();
-	_cAnimSpeed = s.readByte();
-	if (_cAnimSpeed & 0x80)
-		_cAnimSpeed = -(_cAnimSpeed & 0x7f);
+					s = Common::String(p + 6, p + 9);
+					people._hSavedFacing = atoi(s.c_str());
+					if (people._hSavedFacing == 0)
+						people._hSavedFacing = 10;
+				} else if ((p = strchr(name.c_str(), '/')) != nullptr) {
+					people._hSavedPos = Common::Point(1, 0);
+					people._hSavedFacing = 100 + atoi(p + 1);
+				}
+			} else {
+				scene._goToScene = 100;
+			}
 
-	for (int idx = 0; idx < NAMES_COUNT; ++idx) {
-		s.read(buffer, 12);
-		_names[idx] = Common::String(buffer);
+			people[HOLMES]._position = Point32(0, 0);
+			break;
+		}
+	} else if (name.hasPrefix("!")) {
+		// Message attached to canimation
+		int messageNum = atoi(name.c_str() + 1);
+		ui._infoFlag = true;
+		ui.clearInfo();
+		screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]);
+		ui._menuCounter = 25;
+	} else if (name.hasPrefix("@")) {
+		// Message attached to canimation
+		ui._infoFlag = true;
+		ui.clearInfo();
+		screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1);
+		printed = true;
+		ui._menuCounter = 25;
 	}
+
+	return printed;
 }
 
 /*----------------------------------------------------------------*/
 
-UseType::UseType(): ActionType() {
-	_useFlag = 0;
+void Sprite::clear() {
+	_name = "";
+	_description = "";
+	_examine.clear();
+	_pickUp = "";
+	_walkSequences.clear();
+	_sequences = nullptr;
+	_images = nullptr;
+	_imageFrame = nullptr;
+	_walkCount = 0;
+	_allow = 0;
+	_frameNumber = _sequenceNumber = 0;
+	_position.x = _position.y = 0;
+	_delta.x = _delta.y = 0;
+	_oldPosition.x = _oldPosition.y = 0;
+	_oldSize.x = _oldSize.y = 0;
+	_goto.x = _goto.y = 0;
+	_type = INVALID;
+	_pickUp.clear();
+	_noShapeSize.x = _noShapeSize.y = 0;
+	_status = 0;
+	_misc = 0;
+	_altImages = nullptr;
+	_altSeq = 0;
+	Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
 }
 
-void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
-	char buffer[12];
+void Sprite::setImageFrame() {
+	int frameNum = MAX(_frameNumber, 0);
+	int imageNumber = _walkSequences[_sequenceNumber][frameNum];
+	
+	if (IS_SERRATED_SCALPEL)
+		imageNumber = imageNumber + _walkSequences[_sequenceNumber][0] - 2;
+	else if (imageNumber > _maxFrames)
+		imageNumber = 1;
 
-	if (isRoseTattoo) {
-		s.read(buffer, 12);
-		_verb = Common::String(buffer);
-	}
+	// Get the images to use
+	ImageFile *images = _altSeq ? _altImages : _images;
+	assert(images);
 
-	ActionType::load(s);
+	if (_vm->getPlatform() == Common::kPlatform3DO) {
+		// only do this to the image-array with 110 entries
+		// map uses another image-array and this code
+		if (images->size() == 110) {
+			// 3DO has 110 animation frames inside walk.anim
+			// PC has 55
+			// this adjusts the framenumber accordingly
+			// sort of HACK
+			imageNumber *= 2;
+		}
+	} else if (IS_ROSE_TATTOO) {
+		--imageNumber;
+	}
 
-	_useFlag = s.readSint16LE();
+	// Set the frame pointer
+	_imageFrame = &(*images)[imageNumber];
+}
 
-	if (!isRoseTattoo)
-		s.skip(6);
+void Sprite::checkSprite() {
+	Events &events = *_vm->_events;
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+	Screen &screen = *_vm->_screen;
+	Talk &talk = *_vm->_talk;
+	Point32 pt;
+	Common::Rect objBounds;
+	Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
 
-	s.read(buffer, 12);
-	_target = Common::String(buffer);
-}
+	if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
+		return;
 
-void UseType::load3DO(Common::SeekableReadStream &s) {
-	char buffer[12];
+	pt = _walkCount ? _position + _delta : _position;
+	pt.x /= FIXED_INT_MULTIPLIER;
+	pt.y /= FIXED_INT_MULTIPLIER;
 
-	_cAnimNum = s.readByte();
-	_cAnimSpeed = s.readByte();
-	if (_cAnimSpeed & 0x80)
-		_cAnimSpeed = -(_cAnimSpeed & 0x7f);
+	if (IS_ROSE_TATTOO) {
+		// TODO: Needs to be called
+		//checkObject(1001);
 
-	for (int idx = 0; idx < NAMES_COUNT; ++idx) {
-		s.read(buffer, 12);
-		_names[idx] = Common::String(buffer);
+		// For Rose Tattoo, we only do the further processing for Sherlock
+		if (this != &people[HOLMES])
+			return;
 	}
 
-	_useFlag = s.readSint16BE();
-
-	s.skip(6);
+	for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
+		Object &obj = scene._bgShapes[idx];
+		if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
+			continue;
 
-	s.read(buffer, 12);
-	_target = Common::String(buffer);
-}
+		if (obj._type == NO_SHAPE) {
+			objBounds = Common::Rect(obj._position.x, obj._position.y,
+				obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
+		} else {
+			int xp = obj._position.x + obj._imageFrame->_offset.x;
+			int yp = obj._position.y + obj._imageFrame->_offset.y;
+			objBounds = Common::Rect(xp, yp,
+				xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
+		}
 
-/*----------------------------------------------------------------*/
+		if (objBounds.contains(pt)) {
+			if (objBounds.contains(spritePt)) {
+				// Current point is already inside the the bounds, so impact occurred
+				// on a previous call. So simply do nothing until we're clear of the box
+				switch (obj._aType) {
+				case TALK_MOVE:
+					if (_walkCount) {
+						// Holmes is moving
+						obj._type = HIDDEN;
+						obj.setFlagsAndToggles();
+						talk.talkTo(obj._use[0]._target);
+					}
+					break;
 
-SherlockEngine *Object::_vm;
-bool Object::_countCAnimFrames;
+				case PAL_CHANGE:
+				case PAL_CHANGE2:
+					if (_walkCount) {
+						int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
+						int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
+						int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
+						if (templ == 0)
+							templ = 100;
 
-void Object::setVm(SherlockEngine *vm) {
-	_vm = vm;
-	_countCAnimFrames = false;
-}
+						// Ensure only valid palette change data found
+						if (palLength > 0) {
+							// Figure out how far into the shape Holmes is so that we
+							// can figure out what percentage of the original palette
+							// to set the current palette to
+							int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
+							palPercent = palPercent * templ / 100;
+							if (obj._aType == PAL_CHANGE)
+								// Invert percentage
+								palPercent = 100 - palPercent;
 
-Object::Object(): BaseObject() {
-	_sequenceNumber = 0;
-	_sequenceOffset = 0;
-	_pickup = 0;
-	_defaultCommand = 0;
-	_pickupFlag = 0;
-}
+							for (int i = palStart; i < (palStart + palLength); ++i)
+								screen._sMap[i] = screen._cMap[i] * palPercent / 100;
 
-void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
-	char buffer[41];
-	s.read(buffer, 12);
-	_name = Common::String(buffer);
-	s.read(buffer, 41);
-	_description = Common::String(buffer);
+							events.pollEvents();
+							screen.setPalette(screen._sMap);
+						}
+					}
+					break;
 
-	_examine.clear();
-	_sequences = nullptr;
-	_images = nullptr;
-	_imageFrame = nullptr;
+				case TALK:
+				case TALK_EVERY:
+					obj._type = HIDDEN;
+					obj.setFlagsAndToggles();
+					talk.talkTo(obj._use[0]._target);
+					break;
 
-	s.skip(4);
-	_sequenceOffset = s.readUint16LE();
-	s.seek(10, SEEK_CUR);
+				default:
+					break;
+				}
+			} else {
+				// New impact just occurred
+				switch (obj._aType) {
+				case BLANK_ZONE:
+					// A blank zone masks out all other remaining zones underneath it.
+					// If this zone is hit, exit the outer loop so we do not check anymore
+					return;
 
-	_walkCount = s.readByte();
-	_allow = s.readByte();
-	_frameNumber = s.readSint16LE();
-	_sequenceNumber = s.readSint16LE();
-	_position.x = s.readSint16LE();
-	_position.y = s.readSint16LE();
-	_delta.x = s.readSint16LE();
-	_delta.y = s.readSint16LE();
-	_type = (SpriteType)s.readUint16LE();
-	_oldPosition.x = s.readSint16LE();
-	_oldPosition.y = s.readSint16LE();
-	_oldSize.x = s.readUint16LE();
-	_oldSize.y = s.readUint16LE();
-	
-	_goto.x = s.readSint16LE();
-	_goto.y = s.readSint16LE();
-	if (!isRoseTattoo) {
-		_goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
-		_goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
-	}
+				case SOLID:
+				case TALK:
+					// Stop walking
+					if (obj._aType == TALK) {
+						obj.setFlagsAndToggles();
+						talk.talkTo(obj._use[0]._target);
+					} else {
+						gotoStand();
+					}
+					break;
 
-	_pickup = isRoseTattoo ? 0 : s.readByte();
-	_defaultCommand = isRoseTattoo ? 0 : s.readByte();
-	_lookFlag = s.readSint16LE();
-	_pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
-	_requiredFlag = s.readSint16LE();
-	_noShapeSize.x = s.readUint16LE();
-	_noShapeSize.y = s.readUint16LE();
-	_status = s.readUint16LE();
-	_misc = s.readByte();
-	_maxFrames = s.readUint16LE();
-	_flags = s.readByte();
+				case TALK_EVERY:
+					if (obj._aType == TALK_EVERY) {
+						obj._type = HIDDEN;
+						obj.setFlagsAndToggles();
+						talk.talkTo(obj._use[0]._target);
+					} else {
+						gotoStand();
+					}
+					break;
 
-	if (!isRoseTattoo)
-		_aOpen.load(s);
+				case FLAG_SET:
+					obj.setFlagsAndToggles();
+					obj._type = HIDDEN;
+					break;
 
-	_aType = (AType)s.readByte();
-	_lookFrames = s.readByte();
-	_seqCounter = s.readByte();
-	_lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER / 100;
-	_lookPosition.y = (isRoseTattoo ? s.readSint16LE() : s.readByte()) * FIXED_INT_MULTIPLIER;
-	_lookFacing = s.readByte();
-	_lookcAnim = s.readByte();
+				case WALK_AROUND:
+					if (objBounds.contains(people[HOLMES]._walkTo.front())) {
+						// Reached zone
+						gotoStand();
+					} else {
+						// Destination not within box, walk to best corner
+						Common::Point walkPos;
 
-	if (!isRoseTattoo)
-		_aClose.load(s);
+						if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
+							// Impact occurred due to vertical movement. Determine whether to
+							// travel to the left or right side
+							if (_delta.x > 0)
+								// Go to right side
+								walkPos.x = objBounds.right + CLEAR_DIST_X;
+							else if (_delta.x < 0) {
+								// Go to left side
+								walkPos.x = objBounds.left - CLEAR_DIST_X;
+							} else {
+								// Going straight up or down. So choose best side
+								if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
+									walkPos.x = objBounds.right + CLEAR_DIST_X;
+								else
+									walkPos.x = objBounds.left - CLEAR_DIST_X;
+							}
 
-	_seqStack = s.readByte();
-	_seqTo = s.readByte();
-	_descOffset = s.readUint16LE();
-	_seqCounter2 = s.readByte();
-	_seqSize = s.readUint16LE();
+							walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
+								objBounds.bottom + CLEAR_DIST_Y;
+						} else {
+							// Impact occurred due to horizontal movement
+							if (_delta.y > 0)
+								// Go to bottom of box
+								walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+							else if (_delta.y < 0)
+								// Go to top of box
+								walkPos.y = objBounds.top - CLEAR_DIST_Y;
+							else {
+								// Going straight horizontal, so choose best side
+								if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
+									walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+								else
+									walkPos.y = objBounds.top - CLEAR_DIST_Y;
+							}
 
-	if (isRoseTattoo) {
-		for (int idx = 0; idx < 6; ++idx)
-			_use[idx].load(s, true);
+							walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
+								objBounds.right + CLEAR_DIST_X;
+						}
 
-		_quickDraw = s.readByte();
-		_scaleVal = s.readUint16LE();
-		_requiredFlags1 = s.readSint16LE();
-		_gotoSeq = s.readByte();
-		_talkSeq = s.readByte();
-		_restoreSlot = s.readByte();
-	} else {
-		s.skip(1);
-		_aMove.load(s);
-		s.skip(8);
+						walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
+						people._walkDest = walkPos;
+						people[HOLMES]._walkTo.push(walkPos);
+						people[HOLMES].setWalking();
+					}
+					break;
 
-		for (int idx = 0; idx < 4; ++idx)
-			_use[idx].load(s, false);
+				case DELTA:
+					_position.x += 200;
+					break;
+
+				default:
+					break;
+				}
+			}
+		}
 	}
-	//warning("object %s, useAnim %d", _name.c_str(), _use[0]._cAnimNum);
 }
 
-void Object::load3DO(Common::SeekableReadStream &s) {
-	int32 streamStartPos = s.pos();
-	char buffer[41];
+const Common::Rect Sprite::getOldBounds() const {
+	return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
+}
 
-	_examine.clear();
-	_sequences = nullptr;
-	_images = nullptr;
-	_imageFrame = nullptr;
+void Sprite::setObjTalkSequence(int seq) {
+	assert(seq != -1 && _type == CHARACTER);
 
-	// on 3DO all of this data is reordered!!!
-	// it seems that possibly the 3DO compiler reordered the global struct
-	// 3DO size for 1 object is 588 bytes
-	s.skip(4);
-	_sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
-	s.seek(10, SEEK_CUR);
+	if (_seqTo) {
+		// reset to previous value
+		_walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo;
+		_seqTo = 0;
+	}
+
+	_sequenceNumber = _gotoSeq;
+	_frameNumber = 0;
+	checkWalkGraphics();
+}
+
+void Sprite::checkWalkGraphics() {
+	People &people = *_vm->_people;
+
+	if (_images == nullptr) {
+		freeAltGraphics();
+		return;
+	}
+
+	Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str());
+
+	// Set the adjust depending on if we have to fine tune the x position of this particular graphic
+	_adjust.x = _adjust.y = 0;
+
+	for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) {
+		if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName, 
+				strlen(ADJUST_WALKS[idx]._vgsName))) {
+			if (_walkSequences[_sequenceNumber]._horizFlip)
+				_adjust.x = ADJUST_WALKS[idx]._flipXAdjust;
+			else
+				_adjust.x = ADJUST_WALKS[idx]._xAdjust;
+
+			_adjust.y = ADJUST_WALKS[idx]._yAdjust;
+			break;
+		}
+	}
+
+	// See if we're already using Alternate Graphics
+	if (_altSeq) {
+		// See if the VGS file called for is different than the alternate graphics already loaded
+		if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) {
+			// Different AltGraphics, Free the old ones
+			freeAltGraphics();
+		}
+	}
+
+	// If there is no Alternate Sequence set, see if we need to load a new one
+	if (!_altSeq) {
+		int npcNum = -1;
+		// Find which NPC this is so we can check the name of the graphics loaded
+		for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+			if (this == &people[idx]) {
+				npcNum = idx;
+				break;
+			}
+		}
 
-	// Offset 16
-	_frameNumber = s.readSint16BE();
-	_sequenceNumber = s.readSint16BE();
-	_position.x = s.readSint16BE();
-	_position.y = s.readSint16BE();
-	_delta.x = s.readSint16BE();
-	_delta.y = s.readSint16BE();
-	_type = (SpriteType)s.readUint16BE();
-	_oldPosition.x = s.readSint16BE();
-	_oldPosition.y = s.readSint16BE();
-	_oldSize.x = s.readUint16BE();
-	_oldSize.y = s.readUint16BE();
-	
-	_goto.x = s.readSint16BE();
-	_goto.y = s.readSint16BE();
-	_goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
-	_goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+		if (npcNum != -1) {
+			// See if the VGS file called for is different than the main graphics which are already loaded
+			if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) {
+				// See if this is one of the more used Walk Graphics stored in WALK.LIB
+				for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) {
+					if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) {
+						people._useWalkLib = true;
+						break;
+					}
+				}
 
-	// Offset 42
-	warning("pos %d", s.pos());
+				_altImages = new ImageFile(filename);
+				people._useWalkLib = false;
 
-	// Unverified
-	_lookFlag = s.readSint16BE();
-	_pickupFlag = s.readSint16BE();
-	_requiredFlag = s.readSint16BE();
-	_noShapeSize.x = s.readUint16BE();
-	_noShapeSize.y = s.readUint16BE();
-	_status = s.readUint16BE();
-	// Unverified END
+				_altSeq = _sequenceNumber + 1;
+			}
+		}
+	}
 
-	_maxFrames = s.readUint16BE();
-	// offset 56
-	_lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
-	// offset 58
-	_descOffset = s.readUint16BE();
-	_seqSize = s.readUint16BE();
+	// If this is a different seqeunce from the current sequence, reset the appropriate variables
+	if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {		
+		_seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
+		_sequences = &_walkSequences[_sequenceNumber]._sequences[0];
+		_seqSize = _walkSequences[_sequenceNumber]._sequences.size();
+	}
 
-	s.skip(2); // boundary filler
+	setImageFrame();
+}
 
-	// 288 bytes
-	for (int idx = 0; idx < 4; ++idx) {
-		_use[idx].load3DO(s);
-		s.skip(2); // Filler
+void Sprite::freeAltGraphics() {
+	if (_altImages != nullptr) {
+		delete _altImages;
+		_altImages = nullptr;
 	}
 
-	// 158 bytes
-	_aOpen.load(s); // 2 + 12*4 bytes = 50 bytes
-	s.skip(2); // Boundary filler
-	_aClose.load(s);
-	s.skip(2); // Filler
-	_aMove.load(s);
-	s.skip(2); // Filler
+	_altSeq = 0;
+}
 
-	// offset 508
-	// 3DO: name is at the end
-	s.read(buffer, 12);
-	_name = Common::String(buffer);
-	s.read(buffer, 41);
-	_description = Common::String(buffer);
+/*----------------------------------------------------------------*/
 
-	// Unverified
-	_walkCount = s.readByte();
-	_allow = s.readByte();
-	_pickup = s.readByte();
-	_defaultCommand = s.readByte();
-	// Unverified END
+void WalkSequence::load(Common::SeekableReadStream &s) {
+	char buffer[9];
+	s.read(buffer, 9);
+	_vgsName = Common::String(buffer);
+	_horizFlip = s.readByte() != 0;
 
-	// Probably those here?!?!
-	_misc = s.readByte();
-	_flags = s.readByte();
+	_sequences.resize(s.readUint16LE());
+	s.skip(4);		// Skip over pointer field of structure
 
-	// Unverified
-	_aType = (AType)s.readByte();
-	_lookFrames = s.readByte();
-	_seqCounter = s.readByte();
-	// Unverified END
+	s.read(&_sequences[0], _sequences.size());
+}
 
-	_lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
-	_lookFacing = s.readByte();
+/*----------------------------------------------------------------*/
 
-	// Unverified
-	_lookcAnim = s.readByte();
-	_seqStack = s.readByte();
-	_seqTo = s.readByte();
-	_seqCounter2 = s.readByte();
-	// Unverified END
+WalkSequences &WalkSequences::operator=(const WalkSequences &src) {
+	resize(src.size());
+	for (uint idx = 0; idx < size(); ++idx) {
+		const WalkSequence &wSrc = src[idx];
+		WalkSequence &wDest = (*this)[idx];
+		wDest._horizFlip = wSrc._horizFlip;
 
-	s.skip(12); // Unknown
+		wDest._sequences.resize(wSrc._sequences.size());
+		Common::copy(&wSrc._sequences[0], &wSrc._sequences[0] + wSrc._sequences.size(), &wDest._sequences[0]);
+	}
 
-	//warning("object %s, offset %d", _name.c_str(), streamPos);
-	//warning("object %s, lookPosX %d, lookPosY %d", _name.c_str(), _lookPosition.x, _lookPosition.y);
-	//warning("object %s, defCmd %d", _name.c_str(), _defaultCommand);
-	int32 dataSize = s.pos() - streamStartPos;
-	assert(dataSize == 588);
+	return *this;
 }
 
-void Object::toggleHidden() {
-	if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
-		if (_seqTo != 0)
-			_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
-		_seqTo = 0;
+/*----------------------------------------------------------------*/
 
-		if (_images == nullptr || _images->size() == 0)
-			// No shape to erase, so flag as hidden
-			_type = HIDDEN;
-		else
-			// Otherwise, flag it to be hidden after it gets erased
-			_type = HIDE_SHAPE;
-	} else if (_type != INVALID) {
-		if (_seqTo != 0)
-			_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
-		_seqTo = 0;
+ActionType::ActionType() {
+	_cAnimNum = _cAnimSpeed = 0;
+}
 
-		_seqCounter = _seqCounter2 = 0;
-		_seqStack = 0;
-		_frameNumber = -1;
+void ActionType::load(Common::SeekableReadStream &s) {
+	char buffer[12];
 
-		if (_images == nullptr || _images->size() == 0) {
-			_type = NO_SHAPE;
-		} else {
-			_type = ACTIVE_BG_SHAPE;
-			int idx = _sequences[0];
-			if (idx >= _maxFrames)
-				// Turn on: set up first frame
-				idx = 0;
+	_cAnimNum = s.readByte();
+	_cAnimSpeed = s.readByte();
+	if (_cAnimSpeed & 0x80)
+		_cAnimSpeed = -(_cAnimSpeed & 0x7f);
 
-			_imageFrame = &(*_images)[idx];
-		}
+	for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+		s.read(buffer, 12);
+		_names[idx] = Common::String(buffer);
 	}
 }
 
-void Object::checkObject() {
-	Scene &scene = *_vm->_scene;
-	Sound &sound = *_vm->_sound;
-	Talk &talk = *_vm->_talk;
-	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
-	bool codeFound;
+/*----------------------------------------------------------------*/
 
-	if (_seqTo) {
-		byte *ptr = &_sequences[_frameNumber];
-		if (*ptr == _seqTo) {
-			// The sequence is completed
-			*ptr = _seqTo + SEQ_TO_CODE + 128;	// Reset to normal
-			_seqTo = 0;
-		} else {
-			// Continue doing sequence
-			if (*ptr > _seqTo)
-				*ptr -= 1;
-			else
-				*ptr += 1;
+UseType::UseType(): ActionType() {
+	_useFlag = 0;
+}
 
-			return;
-		}
+void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+	char buffer[12];
+
+	if (isRoseTattoo) {
+		s.read(buffer, 12);
+		_verb = Common::String(buffer);
 	}
 
-	++_frameNumber;
+	ActionType::load(s);
 
-	do {
-		// Check for end of sequence
-		codeFound = checkEndOfSequence();
+	_useFlag = s.readSint16LE();
 
-		if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
-			codeFound = true;
-			int v = _sequences[_frameNumber];
+	if (!isRoseTattoo)
+		s.skip(6);
 
-			// Check for a Talk or Listen Sequence
-			if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
-				if (_gotoSeq) {
-					setObjTalkSequence(_gotoSeq);
-				} else {
-					++_frameNumber;
-				}
-			} else if (IS_ROSE_TATTOO && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE)) {
-				if (_talkSeq)
-					setObjTalkSequence(_talkSeq);
-				else
-					setObjSequence(0, false);
-			} else  if (v >= GOTO_CODE) {
-				// Goto code found
-				v -= GOTO_CODE;
-				_seqCounter2 = _seqCounter;
-				_seqStack = _frameNumber + 1;
-				setObjSequence(v, false);
-			} else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
-				codeFound = true;
-				++_frameNumber;
-				v -= SOUND_CODE + (IS_SERRATED_SCALPEL ? 1 : 0);
+	s.read(buffer, 12);
+	_target = Common::String(buffer);
+}
 
-				if (sound._soundOn && !_countCAnimFrames) {
-					if (!scene._sounds[v]._name.empty() && sound._digitized)
-						sound.playLoadedSound(v, WAIT_RETURN_IMMEDIATELY);
-				}
-			} else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) {
-				// Flip code
-				codeFound = true;
-				++_frameNumber;
-				v -= FLIP_CODE;
+void UseType::load3DO(Common::SeekableReadStream &s) {
+	char buffer[12];
+
+	_cAnimNum = s.readByte();
+	_cAnimSpeed = s.readByte();
+	if (_cAnimSpeed & 0x80)
+		_cAnimSpeed = -(_cAnimSpeed & 0x7f);
+
+	for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+		s.read(buffer, 12);
+		_names[idx] = Common::String(buffer);
+	}
 
-				// Alter the flipped status
-				switch (v) {
-				case 0:
-					// Clear the flag
-					_flags &= ~OBJ_FLIPPED;
-					break;
-				case 1:
-					// Set the flag
-					_flags |= OBJ_FLIPPED;
-					break;
-				case 2:
-					// Toggle the flag
-					_flags ^= OBJ_FLIPPED;
-					break;
-				default:
-					break;
-				}
-			} else if (IS_ROSE_TATTOO && v == TELEPORT_CODE) {
-				_position.x = READ_LE_UINT16(&_sequences[_frameNumber + 1]);
-				_position.y = READ_LE_UINT16(&_sequences[_frameNumber + 3]);
+	_useFlag = s.readSint16BE();
 
-				_frameNumber += 5;
-			} else if (IS_ROSE_TATTOO && v == CALL_TALK_CODE) {
-				Common::String filename;
-				for (int idx = 0; idx < 8; ++idx) {
-					if (_sequences[_frameNumber + 1 + idx] != 1)
-						filename += (char)_sequences[_frameNumber + 1 + idx];
-					else
-						break;
-				}
+	s.skip(6);
 
-				_frameNumber += 8;
-				talk.talkTo(filename);
+	s.read(buffer, 12);
+	_target = Common::String(buffer);
+}
 
-			} else if (IS_ROSE_TATTOO && v == HIDE_CODE) {
-				switch (_sequences[_frameNumber + 2]) {
-				case 1:
-					// Hide Object
-					if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type != HIDDEN)
-						scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
-					break;
+/*----------------------------------------------------------------*/
 
-				case 2:
-					// Activate Object
-					if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type == HIDDEN)
-						scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
-					break;
+bool Object::_countCAnimFrames;
 
-				case 3:
-					// Toggle Object
-					scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
-					break;
+Object::Object(): BaseObject() {
+	_sequenceNumber = 0;
+	_sequenceOffset = 0;
+	_pickup = 0;
+	_defaultCommand = 0;
+	_pickupFlag = 0;
+}
 
-				default:
-					break;
-				}
-				_frameNumber += 3;
-			
-			} else {
-				v -= 128;
+void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+	char buffer[41];
+	s.read(buffer, 12);
+	_name = Common::String(buffer);
+	s.read(buffer, 41);
+	_description = Common::String(buffer);
 
-				// 68-99 is a squence code
-				if (v > SEQ_TO_CODE) {
-					byte *p = &_sequences[_frameNumber];
-					v -= SEQ_TO_CODE;	// # from 1-32
-					_seqTo = v;
-					*p = *(p - 1);
+	_examine.clear();
+	_sequences = nullptr;
+	_images = nullptr;
+	_imageFrame = nullptr;
 
-					if (*p > 128)
-						// If the high bit is set, convert to a real frame
-						*p -= (byte)(SEQ_TO_CODE - 128);
+	s.skip(4);
+	_sequenceOffset = s.readUint16LE();
+	s.seek(10, SEEK_CUR);
 
-					if (*p > _seqTo)
-						*p -= 1;
-					else
-						*p += 1;
+	_walkCount = s.readByte();
+	_allow = s.readByte();
+	_frameNumber = s.readSint16LE();
+	_sequenceNumber = s.readSint16LE();
+	_position.x = s.readSint16LE();
+	_position.y = s.readSint16LE();
+	_delta.x = s.readSint16LE();
+	_delta.y = s.readSint16LE();
+	_type = (SpriteType)s.readUint16LE();
+	_oldPosition.x = s.readSint16LE();
+	_oldPosition.y = s.readSint16LE();
+	_oldSize.x = s.readUint16LE();
+	_oldSize.y = s.readUint16LE();
+	
+	_goto.x = s.readSint16LE();
+	_goto.y = s.readSint16LE();
+	if (!isRoseTattoo) {
+		_goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+		_goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+	}
 
-					// Will be incremented below to return back to original value
-					--_frameNumber;
-					v = 0;
+	_pickup = isRoseTattoo ? 0 : s.readByte();
+	_defaultCommand = isRoseTattoo ? 0 : s.readByte();
+	_lookFlag = s.readSint16LE();
+	_pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
+	_requiredFlag = s.readSint16LE();
+	_noShapeSize.x = s.readUint16LE();
+	_noShapeSize.y = s.readUint16LE();
+	_status = s.readUint16LE();
+	_misc = s.readByte();
+	_maxFrames = s.readUint16LE();
+	_flags = s.readByte();
 
-				} else if (IS_ROSE_TATTOO && v == 10) {
-					// Set delta for objects
-					_delta = Common::Point(READ_LE_UINT16(&_sequences[_frameNumber + 1]), 
-						READ_LE_UINT16(&_sequences[_frameNumber + 3]));
-					_noShapeSize = Common::Point(0, 0);
-					_frameNumber += 4;
+	if (!isRoseTattoo)
+		_aOpen.load(s);
 
-				} else if (v == 10) {
-					// Set delta for objects
-					Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
-					if (pt.x > 128)
-						pt.x = (pt.x - 128) *  -1;
-					else
-						pt.x--;
+	_aType = (AType)s.readByte();
+	_lookFrames = s.readByte();
+	_seqCounter = s.readByte();
+	_lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER / 100;
+	_lookPosition.y = (isRoseTattoo ? s.readSint16LE() : s.readByte()) * FIXED_INT_MULTIPLIER;
+	_lookFacing = s.readByte();
+	_lookcAnim = s.readByte();
 
-					if (pt.y > 128)
-						pt.y = (pt.y - 128) * -1;
-					else
-						pt.y--;
+	if (!isRoseTattoo)
+		_aClose.load(s);
 
-					_delta = pt;
-					_frameNumber += 2;
+	_seqStack = s.readByte();
+	_seqTo = s.readByte();
+	_descOffset = s.readUint16LE();
+	_seqCounter2 = s.readByte();
+	_seqSize = s.readUint16LE();
 
-				} else if (v < USE_COUNT) {
-					for (int idx = 0; idx < NAMES_COUNT; ++idx) {
-						checkNameForCodes(_use[v]._names[idx], nullptr);
-					}
+	if (isRoseTattoo) {
+		for (int idx = 0; idx < 6; ++idx)
+			_use[idx].load(s, true);
 
-					if (_use[v]._useFlag)
-						_vm->setFlags(_use[v]._useFlag);
-				}
+		_quickDraw = s.readByte();
+		_scaleVal = s.readUint16LE();
+		_requiredFlags1 = s.readSint16LE();
+		_gotoSeq = s.readByte();
+		_talkSeq = s.readByte();
+		_restoreSlot = s.readByte();
+	} else {
+		s.skip(1);
+		_aMove.load(s);
+		s.skip(8);
 
-				++_frameNumber;
-			}
-		}
-	} while (codeFound);
+		for (int idx = 0; idx < 4; ++idx)
+			_use[idx].load(s, false);
+	}
+	//warning("object %s, useAnim %d", _name.c_str(), _use[0]._cAnimNum);
 }
 
-bool Object::checkEndOfSequence() {
-	Screen &screen = *_vm->_screen;
-	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
-	bool result = false;
+void Object::load3DO(Common::SeekableReadStream &s) {
+	int32 streamStartPos = s.pos();
+	char buffer[41];
 
-	if (_type == REMOVE || _type == INVALID)
-		return false;
+	_examine.clear();
+	_sequences = nullptr;
+	_images = nullptr;
+	_imageFrame = nullptr;
 
-	if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
-		result = true;
+	// on 3DO all of this data is reordered!!!
+	// it seems that possibly the 3DO compiler reordered the global struct
+	// 3DO size for 1 object is 588 bytes
+	s.skip(4);
+	_sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
+	s.seek(10, SEEK_CUR);
 
-		if (_frameNumber >= (checkFrame - 1)) {
-			_frameNumber = START_FRAME;
-		}  else {
-			// Determine next sequence to use
-			int seq = _sequences[_frameNumber + 1];
+	// Offset 16
+	_frameNumber = s.readSint16BE();
+	_sequenceNumber = s.readSint16BE();
+	_position.x = s.readSint16BE();
+	_position.y = s.readSint16BE();
+	_delta.x = s.readSint16BE();
+	_delta.y = s.readSint16BE();
+	_type = (SpriteType)s.readUint16BE();
+	_oldPosition.x = s.readSint16BE();
+	_oldPosition.y = s.readSint16BE();
+	_oldSize.x = s.readUint16BE();
+	_oldSize.y = s.readUint16BE();
+	
+	_goto.x = s.readSint16BE();
+	_goto.y = s.readSint16BE();
+	_goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+	_goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
 
-			if (seq == 99) {
-				--_frameNumber;
-				screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
-				screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
-				_type = INVALID;
-			} else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
-				setObjTalkSequence(_talkSeq);
-			} else {
-				setObjSequence(seq, false);
-			}
-		}
+	// Offset 42
+	warning("pos %d", s.pos());
+
+	// Unverified
+	_lookFlag = s.readSint16BE();
+	_pickupFlag = s.readSint16BE();
+	_requiredFlag = s.readSint16BE();
+	_noShapeSize.x = s.readUint16BE();
+	_noShapeSize.y = s.readUint16BE();
+	_status = s.readUint16BE();
+	// Unverified END
 
-		if (_allow && _frameNumber == 0) {
-			// canimation just ended
-			if (_type != NO_SHAPE && _type != REMOVE) {
-				_type = REMOVE;
+	_maxFrames = s.readUint16BE();
+	// offset 56
+	_lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
+	// offset 58
+	_descOffset = s.readUint16BE();
+	_seqSize = s.readUint16BE();
 
-				if (!_countCAnimFrames) {
-					// Save details before shape is removed
-					_delta.x = _imageFrame->_frame.w;
-					_delta.y = _imageFrame->_frame.h;
-					_position += _imageFrame->_offset;
+	s.skip(2); // boundary filler
 
-					// Free the images
-					delete _images;
-					_images = nullptr;
-					_imageFrame = nullptr;
-				}
-			} else {
-				_type = INVALID;
-			}
-		}
+	// 288 bytes
+	for (int idx = 0; idx < 4; ++idx) {
+		_use[idx].load3DO(s);
+		s.skip(2); // Filler
 	}
 
-	return result;
-}
+	// 158 bytes
+	_aOpen.load(s); // 2 + 12*4 bytes = 50 bytes
+	s.skip(2); // Boundary filler
+	_aClose.load(s);
+	s.skip(2); // Filler
+	_aMove.load(s);
+	s.skip(2); // Filler
 
-void Object::setObjSequence(int seq, bool wait) {
-	Scene &scene = *_vm->_scene;
-	int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+	// offset 508
+	// 3DO: name is at the end
+	s.read(buffer, 12);
+	_name = Common::String(buffer);
+	s.read(buffer, 41);
+	_description = Common::String(buffer);
 
-	if (seq >= 128) {
-		// Loop the sequence until the count exceeded
-		seq -= 128;
+	// Unverified
+	_walkCount = s.readByte();
+	_allow = s.readByte();
+	_pickup = s.readByte();
+	_defaultCommand = s.readByte();
+	// Unverified END
 
-		++_seqCounter;
-		if (_seqCounter >= seq) {
-			// Go to next sequence
-			if (_seqStack) {
-				_frameNumber = _seqStack;
-				_seqStack = 0;
-				_seqCounter = _seqCounter2;
-				_seqCounter2 = 0;
-				if (_frameNumber >= checkFrame)
-					_frameNumber = START_FRAME;
+	// Probably those here?!?!
+	_misc = s.readByte();
+	_flags = s.readByte();
 
-				return;
-			}
+	// Unverified
+	_aType = (AType)s.readByte();
+	_lookFrames = s.readByte();
+	_seqCounter = s.readByte();
+	// Unverified END
 
-			_frameNumber += 2;
-			if (_frameNumber >= checkFrame)
-				_frameNumber = 0;
+	_lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
+	_lookFacing = s.readByte();
 
-			_seqCounter = 0;
-			if (_sequences[_frameNumber] == 0)
-				seq = _sequences[_frameNumber + 1];
-			else
-				return;
-		} else {
-			// Find beginning of sequence
-			do {
-				--_frameNumber;
-			} while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
+	// Unverified
+	_lookcAnim = s.readByte();
+	_seqStack = s.readByte();
+	_seqTo = s.readByte();
+	_seqCounter2 = s.readByte();
+	// Unverified END
 
-			if (_frameNumber != 0)
-				_frameNumber += 2;
+	s.skip(12); // Unknown
 
-			return;
-		}
-	} else {
-		// Reset sequence counter
-		_seqCounter = 0;
-	}
+	//warning("object %s, offset %d", _name.c_str(), streamPos);
+	//warning("object %s, lookPosX %d, lookPosY %d", _name.c_str(), _lookPosition.x, _lookPosition.y);
+	//warning("object %s, defCmd %d", _name.c_str(), _defaultCommand);
+	int32 dataSize = s.pos() - streamStartPos;
+	assert(dataSize == 588);
+}
 
-	int idx = 0;
-	int seqCc = 0;
+void Object::toggleHidden() {
+	if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
+		if (_seqTo != 0)
+			_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+		_seqTo = 0;
 
-	while (seqCc < seq && idx < checkFrame) {
-		++idx;
-		if (_sequences[idx] == 0) {
-			++seqCc;
-			idx += 2;
-		}
-	}
+		if (_images == nullptr || _images->size() == 0)
+			// No shape to erase, so flag as hidden
+			_type = HIDDEN;
+		else
+			// Otherwise, flag it to be hidden after it gets erased
+			_type = HIDE_SHAPE;
+	} else if (_type != INVALID) {
+		if (_seqTo != 0)
+			_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+		_seqTo = 0;
 
-	if (idx >= checkFrame)
-		idx = 0;
-	_frameNumber = idx;
+		_seqCounter = _seqCounter2 = 0;
+		_seqStack = 0;
+		_frameNumber = -1;
 
-	if (wait) {
-		seqCc = idx;
-		while (_sequences[idx] != 0)
-			++idx;
+		if (_images == nullptr || _images->size() == 0) {
+			_type = NO_SHAPE;
+		} else {
+			_type = ACTIVE_BG_SHAPE;
+			int idx = _sequences[0];
+			if (idx >= _maxFrames)
+				// Turn on: set up first frame
+				idx = 0;
 
-		idx = idx - seqCc + 2;
-		for (; idx > 0; --idx)
-			scene.doBgAnim();
+			_imageFrame = &(*_images)[idx];
+		}
 	}
 }
 
@@ -1244,103 +1340,6 @@ void Object::setObjTalkSequence(int seq) {
 	}
 }
 
-int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) {
-	People &people = *_vm->_people;
-	Scene &scene = *_vm->_scene;
-	Screen &screen = *_vm->_screen;
-	Talk &talk = *_vm->_talk;
-	UserInterface &ui = *_vm->_ui;
-	bool printed = false;
-
-	scene.toggleObject(name);
-
-	if (name.hasPrefix("*")) {
-		// A code was found
-		printed = true;
-		char ch = (name == "*") ? 0 : toupper(name[1]);
-
-		switch (ch) {
-		case 'C':
-			talk.talkTo(name.c_str() + 2);
-			break;
-
-		case 'T':
-		case 'B':
-		case 'F':
-		case 'W':
-			// Nothing: action was already done before canimation
-			break;
-
-		case 'G':
-		case 'A': {
-			// G: Have object go somewhere
-			// A: Add onto existing co-ordinates
-			Common::String sx(name.c_str() + 2, name.c_str() + 5);
-			Common::String sy(name.c_str() + 6, name.c_str() + 9);
-
-			if (ch == 'G')
-				_position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
-			else
-				_position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
-			break;
-		}
-
-		default:
-			if (ch >= '0' && ch <= '9') {
-				scene._goToScene = atoi(name.c_str() + 1);
-
-				if (IS_SERRATED_SCALPEL && scene._goToScene < 97) {
-					Scalpel::ScalpelMap &map = *(Scalpel::ScalpelMap *)_vm->_map;
-					if (map[scene._goToScene].x) {
-						map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
-						map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
-					}
-				}
-
-				const char *p;
-				if ((p = strchr(name.c_str(), ',')) != nullptr) {
-					++p;
-
-					Common::String s(p, p + 3);
-					people._hSavedPos.x = atoi(s.c_str());
-
-					s = Common::String(p + 3, p + 6);
-					people._hSavedPos.y = atoi(s.c_str());
-
-					s = Common::String(p + 6, p + 9);
-					people._hSavedFacing = atoi(s.c_str());
-					if (people._hSavedFacing == 0)
-						people._hSavedFacing = 10;
-				} else if ((p = strchr(name.c_str(), '/')) != nullptr) {
-					people._hSavedPos = Common::Point(1, 0);
-					people._hSavedFacing = 100 + atoi(p + 1);
-				}
-			} else {
-				scene._goToScene = 100;
-			}
-
-			people[HOLMES]._position = Point32(0, 0);
-			break;
-		}
-	} else if (name.hasPrefix("!")) {
-		// Message attached to canimation
-		int messageNum = atoi(name.c_str() + 1);
-		ui._infoFlag = true;
-		ui.clearInfo();
-		screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]);
-		ui._menuCounter = 25;
-	} else if (name.hasPrefix("@")) {
-		// Message attached to canimation
-		ui._infoFlag = true;
-		ui.clearInfo();
-		screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1);
-		printed = true;
-		ui._menuCounter = 25;
-	}
-
-	return printed;
-}
-
 void Object::setFlagsAndToggles() {
 	Scene &scene = *_vm->_scene;
 	Talk &talk = *_vm->_talk;
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index e73a8c3..3512930 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -167,6 +167,23 @@ struct UseType: public ActionType {
 };
 
 class BaseObject {
+protected:
+	static SherlockEngine *_vm;
+protected:
+	/**
+	* This will check to see if the object has reached the end of a sequence.
+	* If it has, it switch to whichever next sequence should be started.
+	* @returns		true if the end of a sequence was reached
+	*/
+	bool checkEndOfSequence();
+
+	/**
+	 * Scans through the sequences array and finds the designated sequence.
+	 * It then sets the frame number of the start of that sequence
+	 */
+	void setObjSequence(int seq, bool wait);
+public:
+	static bool _countCAnimFrames;
 public:
 	SpriteType _type;				// Type of object/sprite
 	Common::String _description;	// Description lines
@@ -210,6 +227,7 @@ public:
 public:
 	BaseObject();
 	virtual ~BaseObject() {}
+	static void setVm(SherlockEngine *vm);
 
 	/**
 	 * Returns true if the the object has an Allow Talk Code in the sequence that it's
@@ -218,12 +236,32 @@ public:
 	 * If it's above 128, then it's one of the Listen sequences.
 	 */
 	bool hasAborts() const;
+
+	/**
+	 * Check the state of the object
+	 */
+	void checkObject();
+
+	/**
+	 * Checks for codes
+	 * @param name		The name to check for codes
+	 * @param messages	Provides a lookup list of messages that can be printed
+	 * @returns		0 if no codes are found, 1 if codes were found
+	 */
+	int checkNameForCodes(const Common::String &name, const char *const messages[]);
+
+	/**
+	 * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+	 * so that it points to the beginning of the sequence number's talk sequence in the object's
+	 * sequence buffer
+	 * @param seq	Which sequence to use (if there's more than 1)
+	 * @remarks		1: First talk seq, 2: second talk seq, etc.
+	 */
+	virtual void setObjTalkSequence(int seq) = 0;
 };
 
 class Sprite: public BaseObject {
 protected:
-	static SherlockEngine *_vm;
-
 	/**
 	 * Free the alternate graphics used by NPCs
 	 */
@@ -275,7 +313,7 @@ public:
 	 * @param seq	Which sequence to use (if there's more than 1)
 	 * @remarks		1: First talk seq, 2: second talk seq, etc.
 	 */
-	void setObjTalkSequence(int seq);
+	virtual void setObjTalkSequence(int seq);
 
 	/**
 	* Return frame width
@@ -319,25 +357,6 @@ enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURN
 #define USE_COUNT 4
 
 class Object: public BaseObject {
-private:
-	static SherlockEngine *_vm;
-
-	/**
-	 * This will check to see if the object has reached the end of a sequence.
-	 * If it has, it switch to whichever next sequence should be started.
-	 * @returns		true if the end of a sequence was reached
-	 */
-	bool checkEndOfSequence();
-
-	/**
-	 * Scans through the sequences array and finds the designated sequence.
-	 * It then sets the frame number of the start of that sequence
-	 */
-	void setObjSequence(int seq, bool wait);
-public:
-	static bool _countCAnimFrames;
-
-	static void setVm(SherlockEngine *vm);
 public:
 	Common::String _name;			// Name
 	Common::String _examine;		// Examine in-depth description
@@ -367,19 +386,6 @@ public:
 	void toggleHidden();
 
 	/**
-	 * Check the state of the object
-	 */
-	void checkObject();
-
-	/**
-	 * Checks for codes
-	 * @param name		The name to check for codes
-	 * @param messages	Provides a lookup list of messages that can be printed
-	 * @returns		0 if no codes are found, 1 if codes were found
-	 */
-	int checkNameForCodes(const Common::String &name, const char *const messages[]);
-
-	/**
 	 * Handle setting any flags associated with the object
 	 */
 	void setFlagsAndToggles();
@@ -428,7 +434,7 @@ public:
 	 * @param seq	Which sequence to use (if there's more than 1)
 	 * @remarks		1: First talk seq, 2: second talk seq, etc.
 	 */
-	void setObjTalkSequence(int seq);
+	virtual void setObjTalkSequence(int seq);
 };
 
 
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index 7239392..af70903 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -598,7 +598,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 				++frames;
 		} else {
 			// Forward direction
-			Object::_countCAnimFrames = true;
+			BaseObject::_countCAnimFrames = true;
 
 			while (cObj._type == ACTIVE_BG_SHAPE) {
 				cObj.checkObject();
@@ -611,7 +611,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 			if (frames > 1)
 				--frames;
 
-			Object::_countCAnimFrames = false;
+			BaseObject::_countCAnimFrames = false;
 
 			cObj._type = cAnim._type;
 			cObj._frameNumber = -1;






More information about the Scummvm-git-logs mailing list