[Scummvm-cvs-logs] scummvm master -> 3511f30a2621af4773df5271cdffb6275b9e829e

dreammaster dreammaster at scummvm.org
Sun Jun 7 03:32:58 CEST 2015


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

Summary:
3511f30a26 SHERLOCK: Created common base class for Sprite and Object


Commit: 3511f30a2621af4773df5271cdffb6275b9e829e
    https://github.com/scummvm/scummvm/commit/3511f30a2621af4773df5271cdffb6275b9e829e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-06T21:31:48-04:00

Commit Message:
SHERLOCK: Created common base class for Sprite and Object

Changed paths:
    engines/sherlock/objects.cpp
    engines/sherlock/objects.h
    engines/sherlock/people.cpp
    engines/sherlock/people.h
    engines/sherlock/scalpel/scalpel_talk.cpp
    engines/sherlock/scalpel/scalpel_talk.h
    engines/sherlock/talk.cpp
    engines/sherlock/talk.h
    engines/sherlock/tattoo/tattoo_talk.cpp
    engines/sherlock/tattoo/tattoo_talk.h



diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 52c13d8..2131626 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -74,13 +74,99 @@ static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = {
 
 SherlockEngine *Sprite::_vm;
 
+/*----------------------------------------------------------------*/
+
+BaseObject::BaseObject() {
+	_type = INVALID;
+	_sequences = nullptr;
+	_images = nullptr;
+	_imageFrame = nullptr;
+	_walkCount = 0;
+	_allow = 0;
+	_frameNumber = 0;
+	_lookFlag = 0;
+	_requiredFlag = 0;
+	_status = 0;
+	_misc = 0;
+	_maxFrames = 0;
+	_flags = 0;
+	_aType = OBJECT;
+	_lookFrames = 0;
+	_seqCounter = 0;
+	_lookFacing = 0;
+	_lookcAnim = 0;
+	_seqStack = 0;
+	_seqTo = 0;
+	_descOffset = 0;
+	_seqCounter2 = 0;
+	_seqSize = 0;
+	_quickDraw = 0;
+	_scaleVal = 0;
+	_requiredFlags1 = 0;
+	_gotoSeq = 0;
+	_talkSeq = 0;
+	_restoreSlot = 0;
+}
+
+bool BaseObject::hasAborts() const {
+	int seqNum = _talkSeq;
+
+	// See if the object is in it's regular sequence
+	bool startChecking = !seqNum || _type == CHARACTER;
+
+	uint idx = 0;
+	do
+	{
+		// Get the Frame value
+		int v = _sequences[idx++];
+
+		// See if we found an Allow Talk Interrupt Code
+		if (startChecking && v == ALLOW_TALK_CODE)
+			return true;
+
+		// If we've started checking and we've encountered another Talk or Listen Sequence Code,
+		// then we're done checking this sequence because this is where it would repeat
+		if (startChecking && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE))
+			return false;
+
+		// See if we've found the beginning of a Talk Sequence
+		if ((v == TALK_SEQ_CODE && seqNum < 128) || (v == TALK_LISTEN_CODE && seqNum >= 128)) {
+			// If checking was already on and we came across one of these codes, then there couldn't
+			// have been an Allow Talk Interrupt code in the sequence we were checking, so we're done.
+			if (startChecking)
+				return false;
+
+			seqNum--;
+			// See if we're at the correct Talk Sequence Number
+			if (!(seqNum & 127))
+			{
+				// Correct Sequence, Start Checking Now
+				startChecking = true;
+			}
+		} else {
+			// Move ahead any extra because of special control codes
+			switch (v) {
+			case 0:				idx++; break;
+			case MOVE_CODE:
+			case TELEPORT_CODE:	idx += 4; break;
+			case CALL_TALK_CODE:idx += 8; break;
+			case HIDE_CODE:		idx += 2; break;
+			}
+		}
+	} while (idx < _seqSize);
+
+	return true;
+}
+
+/*----------------------------------------------------------------*/
+
 void Sprite::clear() {
 	_name = "";
 	_description = "";
 	_examine.clear();
 	_pickUp = "";
 	_walkSequences.clear();
-	_seq = nullptr;
+	_sequences = nullptr;
 	_images = nullptr;
 	_imageFrame = nullptr;
 	_walkCount = 0;
@@ -482,9 +568,9 @@ void Sprite::checkWalkGraphics() {
 	}
 
 	// If this is a different seqeunce from the current sequence, reset the appropriate variables
-	if (_seq != &_walkSequences[_sequenceNumber]._sequences[0]) {		
+	if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {		
 		_seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
-		_seq = &_walkSequences[_sequenceNumber]._sequences[0];
+		_sequences = &_walkSequences[_sequenceNumber]._sequences[0];
 		_seqSize = _walkSequences[_sequenceNumber]._sequences.size();
 	}
 
@@ -588,44 +674,12 @@ void Object::setVm(SherlockEngine *vm) {
 	_countCAnimFrames = false;
 }
 
-Object::Object() {
-	_sequenceOffset = 0;
-	_sequences = nullptr;
-	_images = nullptr;
-	_imageFrame = nullptr;
-	_walkCount = 0;
-	_allow = 0;
-	_frameNumber = 0;
+Object::Object(): BaseObject() {
 	_sequenceNumber = 0;
-	_type = INVALID;
+	_sequenceOffset = 0;
 	_pickup = 0;
 	_defaultCommand = 0;
-	_lookFlag = 0;
 	_pickupFlag = 0;
-	_requiredFlag = 0;
-	_status = 0;
-	_misc = 0;
-	_maxFrames = 0;
-	_flags = 0;
-	_aOpen._cAnimNum = 0;
-	_aOpen._cAnimSpeed = 0;
-	_aType = OBJECT;
-	_lookFrames = 0;
-	_seqCounter = 0;
-	_lookFacing = 0;
-	_lookcAnim = 0;
-	_seqStack = 0;
-	_seqTo = 0;
-	_descOffset = 0;
-	_seqCounter2 = 0;
-	_seqSize = 0;
-
-	_quickDraw = 0;
-	_scaleVal = 0;
-	_requiredFlag1 = 0;
-	_gotoSeq = 0;
-	_talkSeq = 0;
-	_restoreSlot = -1;
 }
 
 void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
@@ -703,7 +757,7 @@ void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
 
 		_quickDraw = s.readByte();
 		_scaleVal = s.readUint16LE();
-		_requiredFlag1 = s.readSint16LE();
+		_requiredFlags1 = s.readSint16LE();
 		_gotoSeq = s.readByte();
 		_talkSeq = s.readByte();
 		_restoreSlot = s.readByte();
@@ -1392,7 +1446,7 @@ int Object::pickUpObject(const char *const messages[]) {
 }
 
 const Common::Rect Object::getNewBounds() const {
-	Common::Point pt = _position;
+	Point32 pt = _position;
 	if (_imageFrame)
 		pt += _imageFrame->_offset;
 
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index c35b777..a21a37e 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -161,8 +161,61 @@ struct UseType {
 	void load(Common::SeekableReadStream &s, bool isRoseTattoo);
 };
 
+class BaseObject {
+public:
+	SpriteType _type;				// Type of object/sprite
+	Common::String _description;	// Description lines
+	byte *_sequences;				// Holds animation sequences
+	ImageFile *_images;				// Sprite images
+	ImageFrame *_imageFrame;		// Pointer to shape in the images
+	int _walkCount;					// Walk counter
+	int _allow;						// Allowed UI commands
+	int _frameNumber;				// Frame number in rame sequence to draw
+	Point32 _position;				// Current position
+	Point32 _delta;					// Momvement amount
+	Common::Point _oldPosition;		// Old position
+	Common::Point _oldSize;			// Image's old size
+	Point32 _goto;					// Walk destination
 
-class Sprite {
+	int _lookFlag;					// Which flag LOOK   will set (if any)
+	int _requiredFlag;				// Object will be hidden if not set
+	Common::Point _noShapeSize;		// Size of a NO_SHAPE
+	int _status;					// Status (open/closed, moved/not)
+	int8 _misc;						// Misc field -- use varies with type
+	int _maxFrames;					// Number of frames
+	int _flags;						// Tells if object can be walked behind
+	AType _aType;					// Tells if this is an object, person, talk, etc.
+	int _lookFrames;				// How many frames to play of the look anim before pausing
+	int _seqCounter;				// How many times this sequence has been executed
+	Point32 _lookPosition;			// Where to walk when examining object
+	int _lookFacing;				// Direction to face when examining object
+	int _lookcAnim;
+	int _seqStack;					// Allows gosubs to return to calling frame
+	int _seqTo;						// Allows 1-5, 8-3 type sequences encoded in 2 bytes
+	uint _descOffset;					// Tells where description starts in DescText
+	int _seqCounter2;				// Counter of calling frame sequence
+	uint _seqSize;					// Tells where description starts
+	UseType _use[6];				// Serrated Scalpel uses 4, Rose Tattoo 6
+	int _quickDraw;					// Flag telling whether to use quick draw routine or not
+	int _scaleVal;					// Tells how to scale the sprite
+	int _requiredFlags1;			// This flag must also be set, or the sprite is hidden
+	int _gotoSeq;					// Used by Talk to tell which sequence to goto when able
+	int _talkSeq;					// Tells which talk sequence currently in use (Talk or Listen)
+	int _restoreSlot;				// Used when talk returns to the previous sequence
+public:
+	BaseObject();
+	virtual ~BaseObject() {}
+
+	/**
+	 * Returns true if the the object has an Allow Talk Code in the sequence that it's
+	 * currently running, specified by the _talkSeq field of the object. If it's 0,
+	 * then it's a regular sequence. If it's not 0 but below 128, then it's a Talk Sequence.
+	 * If it's above 128, then it's one of the Listen sequences.
+	 */
+	bool hasAborts() const;
+};
+
+class Sprite: public BaseObject {
 private:
 	static SherlockEngine *_vm;
 
@@ -172,24 +225,11 @@ private:
 	void freeAltGraphics();
 public:
 	Common::String _name;
-	Common::String _description;
 	Common::String _examine;			// Examine in-depth description
 	Common::String _pickUp;				// Message for if you can't pick up object
 
 	WalkSequences _walkSequences;		// Holds animation sequences
-	byte *_seq;
-	ImageFile *_images;					// Sprite images
-	ImageFrame *_imageFrame;			// Pointer to shape in the images
-	int _walkCount;						// Character walk counter
-	int _allow;							// Allowed menu commands - ObjectAllow
-	int _frameNumber;					// Frame number in rame sequence to draw
 	int _sequenceNumber;				// Sequence being used
-	Point32 _position;					// Current position
-	Point32 _delta;						// Momvement delta
-	Common::Point _oldPosition;			// Old position
-	Common::Point _oldSize;				// Image's old size
-	Common::Point _goto;				// Walk destination
-	SpriteType _type;					// Type of object
 	Common::Point _noShapeSize;			// Size of a NO_SHAPE
 	int _status;						// Status: open/closed, moved/not moved
 	int8 _misc;							// Miscellaneous use
@@ -197,26 +237,6 @@ public:
 
 	// Rose Tattoo fields
 	int _startSeq;						// Frame sequence starts at
-	int _flags;							// Flags for the sprite
-	int _aType;							// Tells if this is an object, person, talk, etc.
-	int _lookFrames;					// How many frames to play of a canim before pausing
-	int _seqCounter;					// How many times the sequence has been run
-	Common::Point _lookPosition;		// Where to look when examining object
-	int _lookFacing;					// Direction to face when examining object
-	int _lookCAnim;
-	int _seqStack;						// Allow gosubs to return to calling frame
-	int _seqTo;							// Allows 1-5, 8-3 type sequences encoded in 2 bytes
-	uint _descOffset;					// Tells where description starts in description text for scene
-	int _seqCounter2;					// Counter of calling frame sequence
-	uint _seqSize;						// Size of sequence
-	UseType _use[6];
-	int _quickDraw;						// Flag telling whether to use quick draw routine or not
-	int _scaleVal;						// Tells how to scale the sprite
-	int _requiredFlags1;				// This flag must also be set, or the sprite is hidden
-	int _gotoSeq;						// Used by Talk to tell which sequence to goto when able
-	int _talkSeq;						// Tells which talk sequence currently in use (Talk or Listen)
-	int _restoreSlot;					// Used when talk returns to the previous sequence
-
 	ImageFrame *_stopFrames[8];			// Stop/rest frame for each direction
 	ImageFile *_altImages;				// Images used for alternate NPC sequences
 	int _altSeq;						// Which of the sequences the alt graphics apply to (0: main, 1=NPC seq)
@@ -224,7 +244,8 @@ public:
 	Common::Point _adjust;				// Fine tuning adjustment to position when drawn
 	int _oldWalkSequence;
 public:
-	Sprite() { clear(); }
+	Sprite(): BaseObject() { clear(); }
+	virtual ~Sprite() {}
 
 	static void setVm(SherlockEngine *vm) { _vm = vm; }
 
@@ -282,7 +303,7 @@ public:
 enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };
 #define USE_COUNT 4
 
-class Object {
+class Object: public BaseObject {
 private:
 	static SherlockEngine *_vm;
 
@@ -298,59 +319,17 @@ private:
 	 * It then sets the frame number of the start of that sequence
 	 */
 	void setObjSequence(int seq, bool wait);
-
-	/**
-	 * 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.
-	 */
-	void setObjTalkSequence(int seq);
 public:
 	static bool _countCAnimFrames;
 
 	static void setVm(SherlockEngine *vm);
 public:
 	Common::String _name;			// Name
-	Common::String _description;	// Description lines
 	Common::String _examine;		// Examine in-depth description
+	int _sequenceNumber;
 	int _sequenceOffset;
-	uint8 *_sequences;				// Holds animation sequences
-	ImageFile *_images;				// Sprite images
-	ImageFrame *_imageFrame;		// Pointer to shape in the images
-	int _walkCount;					// Character walk counter
-	int _allow;						// Allowed menu commands - ObjectAllow
-	int _frameNumber;				// Frame number in rame sequence to draw
-	int _sequenceNumber;			// Sequence being used
-	SpriteType _type;				// Object type
-	Common::Point _position;		// Current position
-	Common::Point _delta;			// Momvement amount
-	Common::Point _oldPosition;		// Old position
-	Common::Point _oldSize;			// Image's old size
-	Point32 _goto;					// Walk destination
-
 	int _pickup;
 	int _defaultCommand;			// Default right-click command
-	int _lookFlag;					// Which flag LOOK   will set (if any)
-	int _requiredFlag;				// Object will be hidden if not set
-	Common::Point _noShapeSize;		// Size of a NO_SHAPE
-	int _status;					// Status (open/closed, moved/not)
-	int8 _misc;						// Misc field -- use varies with type
-	int _maxFrames;					// Number of frames
-	int _flags;						// Tells if object can be walked behind
-	AType _aType;					// Tells if this is an object, person, talk, etc.
-	int _lookFrames;				// How many frames to play of the look anim before pausing
-	int _seqCounter;				// How many times this sequence has been executed
-	Point32 _lookPosition;			// Where to walk when examining object
-	int _lookFacing;				// Direction to face when examining object
-	int _lookcAnim;
-	int _seqStack;					// Allows gosubs to return to calling frame
-	int _seqTo;						// Allows 1-5, 8-3 type sequences encoded in 2 bytes
-	uint _descOffset;					// Tells where description starts in DescText
-	int _seqCounter2;				// Counter of calling frame sequence
-	uint _seqSize;					// Tells where description starts
-	UseType _use[6];				// Serrated Scalpel uses 4, Rose Tattoo 6
 
 	// Serrated Scalpel fields
 	int _pickupFlag;				// Which flag PICKUP will set (if any)
@@ -358,15 +337,8 @@ public:
 	ActionType _aClose;
 	ActionType _aMove;
 
-	// Rose Tattoo fields
-	int _quickDraw;
-	int _scaleVal;
-	int _requiredFlag1;
-	int _gotoSeq;
-	int _talkSeq;
-	int _restoreSlot;
-
 	Object();
+	virtual ~Object() {}
 
 	/**
 	 * Load the data for the object
@@ -432,6 +404,15 @@ public:
 	 * Returns the old bounsd for the sprite from the previous frame
 	 */
 	const Common::Rect getOldBounds() const;
+
+	/**
+	 * 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.
+	 */
+	void setObjTalkSequence(int seq);
 };
 
 struct CAnim {
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index e59a90e..0113e80 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -71,6 +71,12 @@ Person::Person() : Sprite(), _walkLoaded(false), _npcIndex(0), _npcStack(0), _np
 	Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
 	_tempX = _tempScaleVal = 0;
 	_updateNPCPath = false;
+	_npcIndex = 0;
+	_npcStack = 0;
+	_savedNpcSequence = 0;
+	_savedNpcFrame = 0;
+	_updateNPCPath = false;
+	_npcPause = false;
 }
 
 void Person::clearNPC() {
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index c26630c..9d42afd 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -40,12 +40,50 @@ enum PeopleId {
 };
 
 // Animation sequence identifiers for characters
-enum {
+enum  {
 	WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4,
 	STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8,
 	WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11,
 	STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14,
-	STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4
+	STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4,
+};
+
+enum TattooSequences {
+	// Walk Sequences Numbers for NPCs
+	RT_WALK_UP			= 0,
+	RT_WALK_UPRIGHT		= 1,
+	RT_WALK_RIGHT		= 2,
+	RT_WALK_DOWNRIGHT	= 3,
+	RT_WALK_DOWN		= 4,
+	RT_WALK_DOWNLEFT	= 5,
+	RT_WALK_LEFT		= 6,
+	RT_WALK_UPLEFT		= 7,
+
+	// Stop Sequences Numbers for NPCs
+	RT_STOP_UP			= 8,
+	RT_STOP_UPRIGHT		= 9,
+	RT_STOP_RIGHT		= 10,
+	RT_STOP_DOWNRIGHT	= 11,
+	RT_STOP_DOWN		= 12,
+	RT_STOP_DOWNLEFT	= 13,
+	RT_STOP_LEFT		= 14,
+	RT_STOP_UPLEFT		= 15,
+
+	// NPC Talk Sequence Numbers
+	RT_TALK_UPRIGHT		= 16,
+	RT_TALK_RIGHT		= 17,
+	RT_TALK_DOWNRIGHT	= 18,
+	RT_TALK_DOWNLEFT	= 19,
+	RT_TALK_LEFT		= 20,
+	RT_TALK_UPLEFT		= 21,
+
+	// NPC Listen Sequence Numbers
+	RT_LISTEN_UPRIGHT	= 22,      
+	RT_LISTEN_RIGHT		= 23,
+	RT_LISTEN_DOWNRIGHT	= 24,
+	RT_LISTEN_DOWNLEFT	= 25,
+	RT_LISTEN_LEFT		= 26,
+	RT_LISTEN_UPLEFT	= 27
 };
 
 enum {
@@ -78,6 +116,8 @@ public:
 	bool _npcPause;
 	byte _npcPath[MAX_NPC_PATH];
 	Common::String _npcName;
+	int _savedNpcSequence;
+	int _savedNpcFrame;
 	int _tempX;
 	int _tempScaleVal;
 	bool _updateNPCPath;
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index 0b0259c..65f7a76 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -325,6 +325,35 @@ OpcodeReturn ScalpelTalk::cmdCarriageReturn(const byte *&str) {
 	return RET_SUCCESS;
 }
 
+void ScalpelTalk::setSequence(int speaker, int sequenceNum) {
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+
+	// If no speaker is specified, then nothing needs to be done
+	if (speaker == -1)
+		return;
+
+	if (speaker) {
+		int objNum = people.findSpeaker(speaker);
+		if (objNum != -1) {
+			Object &obj = scene._bgShapes[objNum];
+
+			if (obj._seqSize < MAX_TALK_SEQUENCES) {
+				warning("Tried to copy too many talk frames");
+			} else {
+				for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) {
+					obj._sequences[idx] = people._characters[speaker]._talkSequences[idx];
+					if (idx > 0 && !obj._sequences[idx] && !obj._sequences[idx - 1])
+						return;
+
+					obj._frameNumber = 0;
+					obj._sequenceNumber = 0;
+				}
+			}
+		}
+	}
+}
+
 } // End of namespace Scalpel
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_talk.h b/engines/sherlock/scalpel/scalpel_talk.h
index 8121e19..1947e2c 100644
--- a/engines/sherlock/scalpel/scalpel_talk.h
+++ b/engines/sherlock/scalpel/scalpel_talk.h
@@ -36,7 +36,7 @@ namespace Sherlock {
 namespace Scalpel {
 
 class ScalpelTalk : public Talk {
-protected:
+private:
 	OpcodeReturn cmdAssignPortraitLocation(const byte *&str);
 	OpcodeReturn cmdClearInfoLine(const byte *&str);
 	OpcodeReturn cmdClearWindow(const byte *&str);
@@ -49,6 +49,11 @@ protected:
 	OpcodeReturn cmdSfxCommand(const byte *&str);
 	OpcodeReturn cmdSummonWindow(const byte *&str);
 	OpcodeReturn cmdCarriageReturn(const byte *&str);
+protected:
+	/**
+	 * Change the sequence of the scene background object associated with the current speaker.
+	 */
+	virtual void setSequence(int speaker, int sequenceNum = 1);
 public:
 	ScalpelTalk(SherlockEngine *vm);
 	virtual ~ScalpelTalk() {}
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index dd2a2a9..9d67e02 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -834,7 +834,7 @@ void Talk::clearSequences() {
 void Talk::pullSequence() {
 	Scene &scene = *_vm->_scene;
 
-	if (_sequenceStack.empty())
+	if (_sequenceStack.empty() || IS_ROSE_TATTOO)
 		return;
 
 	SequenceEntry seq = _sequenceStack.pop();
@@ -858,7 +858,7 @@ void Talk::pushSequence(int speaker) {
 	Scene &scene = *_vm->_scene;
 
 	// Only proceed if a speaker is specified
-	if (speaker == -1)
+	if (speaker == -1 || IS_ROSE_TATTOO)
 		return;
 
 	SequenceEntry seqEntry;
@@ -907,35 +907,6 @@ void Talk::pushTalkSequence(Object *obj) {
 	error("Ran out of talk sequence stack space");
 }
 
-void Talk::setSequence(int speaker) {
-	People &people = *_vm->_people;
-	Scene &scene = *_vm->_scene;
-
-	// If no speaker is specified, then nothing needs to be done
-	if (speaker == -1)
-		return;
-
-	if (speaker) {
-		int objNum = people.findSpeaker(speaker);
-		if (objNum != -1) {
-			Object &obj = scene._bgShapes[objNum];
-
-			if (obj._seqSize < MAX_TALK_SEQUENCES) {
-				warning("Tried to copy too many talk frames");
-			} else {
-				for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) {
-					obj._sequences[idx] = people._characters[speaker]._talkSequences[idx];
-					if (idx > 0 && !obj._sequences[idx] && !obj._sequences[idx - 1])
-						return;
-
-					obj._frameNumber = 0;
-					obj._sequenceNumber = 0;
-				}
-			}
-		}
-	}
-}
-
 void Talk::setStillSeq(int speaker) {
 	People &people = *_vm->_people;
 	Scene &scene = *_vm->_scene;
@@ -987,6 +958,14 @@ void Talk::doScript(const Common::String &script) {
 	_noTextYet = true;
 	_endStr = false;
 
+	if (IS_ROSE_TATTOO) {
+		for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
+			Person &p = people[idx];
+			p._savedNpcSequence = p._sequenceNumber;
+			p._savedNpcFrame = p._frameNumber;
+		}
+	}
+
 	if (_scriptMoreFlag) {
 		_scriptMoreFlag = 0;
 		str = _scriptStart + _scriptSaveIndex;
@@ -998,12 +977,14 @@ void Talk::doScript(const Common::String &script) {
 		_speaker |= SPEAKER_REMOVE;
 	} else {
 		pushSequence(_speaker);
-		ui.clearWindow();
+		if (IS_SERRATED_SCALPEL || ui._windowOpen)
+			ui.clearWindow();
 
 		// Need to switch speakers?
 		if (str[0] == _opcodes[OP_SWITCH_SPEAKER]) {
 			_speaker = str[1] - 1;
-			str += 2;
+			str += IS_SERRATED_SCALPEL ? 2 : 3;
+
 			pullSequence();
 			pushSequence(_speaker);
 			setSequence(_speaker);
@@ -1011,34 +992,36 @@ void Talk::doScript(const Common::String &script) {
 			setSequence(_speaker);
 		}
 
-		// Assign portrait location?
-		if (str[0] == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION]) {
-			switch (str[1] & 15) {
-			case 1:
-				people._portraitSide = 20;
-				break;
-			case 2:
-				people._portraitSide = 220;
-				break;
-			case 3:
-				people._portraitSide = 120;
-				break;
-			default:
-				break;
+		if (IS_SERRATED_SCALPEL) {
+			// Assign portrait location?
+			if (str[0] == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION]) {
+				switch (str[1] & 15) {
+				case 1:
+					people._portraitSide = 20;
+					break;
+				case 2:
+					people._portraitSide = 220;
+					break;
+				case 3:
+					people._portraitSide = 120;
+					break;
+				default:
+					break;
 
-			}
+				}
 
-			if (str[1] > 15)
-				people._speakerFlip = true;
-			str += 2;
-		}
+				if (str[1] > 15)
+					people._speakerFlip = true;
+				str += 2;
+			}
 
-		// Remove portrait?
-		if (str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
-			_speaker = 255;
-		} else {
-			// Nope, so set the first speaker
-			people.setTalking(_speaker);
+			// Remove portrait?
+			if (str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
+				_speaker = -1;
+			} else {
+				// Nope, so set the first speaker
+				people.setTalking(_speaker);
+			}
 		}
 	}
 
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
index ccd09ae..6c33bc7 100644
--- a/engines/sherlock/talk.h
+++ b/engines/sherlock/talk.h
@@ -252,6 +252,11 @@ protected:
 	OpcodeReturn cmdToggleObject(const byte *&str);
 	OpcodeReturn cmdWalkToCAnimation(const byte *&str);
 	OpcodeReturn cmdWalkToCoords(const byte *&str);
+protected:
+	/**
+	 * Change the sequence of the scene background object associated with the current speaker.
+	 */
+	virtual void setSequence(int speaker, int sequenceNum = 1) = 0;
 public:
 	TalkSequence _talkSequenceStack[TALK_SEQUENCE_STACK_SIZE];
 	bool _talkToAbort;
@@ -335,11 +340,6 @@ public:
 	void pushTalkSequence(Object *obj);
 
 	/**
-	 * Change the sequence of the scene background object associated with the current speaker.
-	 */
-	void setSequence(int speaker);
-
-	/**
 	 * Returns true if the script stack is empty
 	 */
 	bool isSequencesEmpty() const { return _scriptStack.empty(); }
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index 4075450..c31b80f 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -182,6 +182,92 @@ TattooTalk::TattooTalk(SherlockEngine *vm) : Talk(vm) {
 	_opcodeTable = OPCODE_METHODS;
 }
 
+void TattooTalk::setSequence(int speaker, int sequenceNum) {
+	People &people = *_vm->_people;
+	Scene &scene = *_vm->_scene;
+
+	// If no speaker is specified, then nothing needs to be done
+	if (speaker == -1)
+		return;
+
+	int objNum = people.findSpeaker(speaker);
+	if (objNum != -1 && objNum < 256) {
+		Object &obj = scene._bgShapes[objNum];
+
+		// See if the Object has to wait for an Abort Talk Code
+		if (obj.hasAborts()) {
+			pushTalkSequence(&obj);
+			obj._gotoSeq = sequenceNum;
+		} else {
+			obj.setObjTalkSequence(sequenceNum);
+		}
+	} else if (objNum != -1) {
+		objNum -= 256;
+		Person &person = people[objNum];
+		int newDir = person._sequenceNumber;
+
+		switch (newDir) {
+		case RT_WALK_UP:
+		case RT_STOP_UP:
+		case RT_WALK_UPRIGHT:
+		case RT_STOP_UPRIGHT:
+		case RT_TALK_UPRIGHT:
+		case RT_LISTEN_UPRIGHT:
+			newDir = RT_TALK_UPRIGHT;
+			break;
+		case RT_WALK_RIGHT:
+		case RT_STOP_RIGHT:
+		case RT_TALK_RIGHT:
+		case RT_LISTEN_RIGHT:
+			newDir = RT_TALK_RIGHT;
+			break;
+		case RT_WALK_DOWNRIGHT:
+		case RT_STOP_DOWNRIGHT:
+		case RT_TALK_DOWNRIGHT:
+		case RT_LISTEN_DOWNRIGHT:
+			newDir = RT_TALK_DOWNRIGHT;
+			break;
+		case RT_WALK_DOWN:
+		case RT_STOP_DOWN:
+		case RT_WALK_DOWNLEFT:
+		case RT_STOP_DOWNLEFT:
+		case RT_TALK_DOWNLEFT:
+		case RT_LISTEN_DOWNLEFT:
+			newDir = RT_TALK_DOWNLEFT;
+			break;
+		case RT_WALK_LEFT:
+		case RT_STOP_LEFT:
+		case RT_TALK_LEFT:
+		case RT_LISTEN_LEFT:
+			newDir = RT_TALK_LEFT;
+			break;
+		case RT_WALK_UPLEFT:
+		case RT_STOP_UPLEFT:
+		case RT_TALK_UPLEFT:
+		case RT_LISTEN_UPLEFT:
+			newDir = RT_TALK_UPLEFT;
+			break;
+		default:
+			break;
+		}
+
+		// See if the NPC's sequence has to wait for an Abort Talk Code
+		if (person.hasAborts()) {
+			person._gotoSeq = newDir;
+		} else {
+			if (person._seqTo) {
+				// Reset to previous value
+				person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
+				person._seqTo = 0;
+			}
+
+			person._sequenceNumber = newDir;
+			person._frameNumber = 0;
+			person.checkWalkGraphics();
+		}
+	}
+}
+
 OpcodeReturn TattooTalk::cmdMouseOnOff(const byte *&str) { 
 	Events &events = *_vm->_events;
 	bool mouseOn = *++str == 2;
diff --git a/engines/sherlock/tattoo/tattoo_talk.h b/engines/sherlock/tattoo/tattoo_talk.h
index 9290a24..eb858c0 100644
--- a/engines/sherlock/tattoo/tattoo_talk.h
+++ b/engines/sherlock/tattoo/tattoo_talk.h
@@ -36,7 +36,7 @@ namespace Sherlock {
 namespace Tattoo {
 
 class TattooTalk : public Talk {
-protected:
+private:
 	OpcodeReturn cmdMouseOnOff(const byte *&str);
 	OpcodeReturn cmdNextSong(const byte *&str);
 	OpcodeReturn cmdPassword(const byte *&str);
@@ -70,6 +70,11 @@ protected:
 	OpcodeReturn cmdWalkNPCToCAnimation(const byte *&str);
 	OpcodeReturn cmdWalkNPCToCoords(const byte *&str);
 	OpcodeReturn cmdWalkHomesAndNPCToCoords(const byte *&str);
+protected:
+	/**
+	 * Change the sequence of the scene background object associated with the current speaker.
+	 */
+	virtual void setSequence(int speaker, int sequenceNum = 1);
 public:
 	TattooTalk(SherlockEngine *vm);
 	virtual ~TattooTalk() {}






More information about the Scummvm-git-logs mailing list