aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-06 21:31:48 -0400
committerPaul Gilbert2015-06-06 21:31:48 -0400
commit3511f30a2621af4773df5271cdffb6275b9e829e (patch)
tree7a49bb802aecb9e64a2ba5c30f6314e54ff22f05 /engines/sherlock
parent75610e7119b415779380805912de40101e3be656 (diff)
downloadscummvm-rg350-3511f30a2621af4773df5271cdffb6275b9e829e.tar.gz
scummvm-rg350-3511f30a2621af4773df5271cdffb6275b9e829e.tar.bz2
scummvm-rg350-3511f30a2621af4773df5271cdffb6275b9e829e.zip
SHERLOCK: Created common base class for Sprite and Object
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/objects.cpp132
-rw-r--r--engines/sherlock/objects.h155
-rw-r--r--engines/sherlock/people.cpp6
-rw-r--r--engines/sherlock/people.h44
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.cpp29
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.h7
-rw-r--r--engines/sherlock/talk.cpp99
-rw-r--r--engines/sherlock/talk.h10
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp86
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.h7
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() {}