diff options
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/sherlock/objects.cpp | 132 | ||||
| -rw-r--r-- | engines/sherlock/objects.h | 155 | ||||
| -rw-r--r-- | engines/sherlock/people.cpp | 6 | ||||
| -rw-r--r-- | engines/sherlock/people.h | 44 | ||||
| -rw-r--r-- | engines/sherlock/scalpel/scalpel_talk.cpp | 29 | ||||
| -rw-r--r-- | engines/sherlock/scalpel/scalpel_talk.h | 7 | ||||
| -rw-r--r-- | engines/sherlock/talk.cpp | 99 | ||||
| -rw-r--r-- | engines/sherlock/talk.h | 10 | ||||
| -rw-r--r-- | engines/sherlock/tattoo/tattoo_talk.cpp | 86 | ||||
| -rw-r--r-- | engines/sherlock/tattoo/tattoo_talk.h | 7 | 
10 files changed, 382 insertions, 193 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 52c13d8a44..2131626bc9 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 c35b777be1..a21a37e580 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 e59a90e5f8..0113e80f22 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 c26630c431..9d42afd6e7 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 0b0259ce0f..65f7a76049 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 8121e1985e..1947e2cd79 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 dd2a2a93ca..9d67e024b3 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 ccd09aee66..6c33bc72a9 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 4075450c2e..c31b80fbfa 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 9290a244c9..eb858c09bc 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() {}  | 
