aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-08-18 20:53:31 -0400
committerPaul Gilbert2015-08-18 20:53:31 -0400
commitd4e5e447925d251afca20afec0e090b210740c82 (patch)
tree8e594456ed56d2bd478c358f214f71fd53f0dd59 /engines/sherlock
parent21666d701e79dd83411a0ba19e00642a5c51e377 (diff)
downloadscummvm-rg350-d4e5e447925d251afca20afec0e090b210740c82.tar.gz
scummvm-rg350-d4e5e447925d251afca20afec0e090b210740c82.tar.bz2
scummvm-rg350-d4e5e447925d251afca20afec0e090b210740c82.zip
SHERLOCK: Standardize sequence stack code for both games
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/objects.cpp14
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.cpp25
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.h14
-rw-r--r--engines/sherlock/scene.h2
-rw-r--r--engines/sherlock/talk.cpp83
-rw-r--r--engines/sherlock/talk.h41
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp2
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp58
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.h10
9 files changed, 124 insertions, 125 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index b412724002..533d2bcc67 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -1228,26 +1228,16 @@ void Object::setObjTalkSequence(int seq) {
// See if we're supposed to restore the object's sequence from the talk sequence stack
if (seq == -1) {
- TalkSequence &ts = talk._talkSequenceStack[_restoreSlot];
if (_seqTo != 0)
_sequences[_frameNumber] = _seqTo;
- _frameNumber = ts._frameNumber;
- _sequenceNumber = ts._sequenceNumber;
- _seqStack = ts._seqStack;
- _seqTo = ts._seqTo;
- _seqCounter = ts._seqCounter;
- _seqCounter2 = ts._seqCounter2;
- _talkSeq = 0;
-
- // Flag this slot as free again
- ts._obj = nullptr;
+ talk.pullSequence(_restoreSlot);
return;
}
assert(_type != CHARACTER);
- talk.pushTalkSequence(this);
+ talk.pushSequenceEntry(this);
int talkSeqNum = seq;
// Find where the talk sequence data begins in the object
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index 61e736483c..4debe7fc26 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -879,7 +879,26 @@ OpcodeReturn ScalpelTalk::cmdCallTalkFile(const byte *&str) {
return RET_SUCCESS;
}
-void ScalpelTalk::pullSequence() {
+void ScalpelTalk::pushSequenceEntry(Object *obj) {
+ Scene &scene = *_vm->_scene;
+ SequenceEntry seqEntry;
+ seqEntry._objNum = scene._bgShapes.indexOf(*obj);
+
+ if (seqEntry._objNum != -1) {
+ Object &obj = scene._bgShapes[seqEntry._objNum];
+ for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx)
+ seqEntry._sequences.push_back(obj._sequences[idx]);
+
+ seqEntry._frameNumber = obj._frameNumber;
+ seqEntry._seqTo = obj._seqTo;
+ }
+
+ _sequenceStack.push(seqEntry);
+ if (_scriptStack.size() >= 5)
+ error("script stack overflow");
+}
+
+void ScalpelTalk::pullSequence(int slot) {
Scene &scene = *_vm->_scene;
if (_sequenceStack.empty())
@@ -901,6 +920,10 @@ void ScalpelTalk::pullSequence() {
}
}
+void ScalpelTalk::clearSequences() {
+ _sequenceStack.clear();
+}
+
} // 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 1d70db14b9..9e07b26dc8 100644
--- a/engines/sherlock/scalpel/scalpel_talk.h
+++ b/engines/sherlock/scalpel/scalpel_talk.h
@@ -37,6 +37,8 @@ namespace Scalpel {
class ScalpelTalk : public Talk {
private:
+ Common::Stack<SequenceEntry> _sequenceStack;
+
OpcodeReturn cmdSwitchSpeaker(const byte *&str);
OpcodeReturn cmdAssignPortraitLocation(const byte *&str);
OpcodeReturn cmdGotoScene(const byte *&str);
@@ -103,15 +105,25 @@ public:
void talk3DOMovieTrigger(int subIndex);
/**
+ * Push the details of a passed object onto the saved sequences stack
+ */
+ virtual void pushSequenceEntry(Object *obj);
+
+ /**
* Pulls a background object sequence from the sequence stack and restore's the
* object's sequence
*/
- virtual void pullSequence();
+ virtual void pullSequence(int slot = -1);
/**
* Returns true if the script stack is empty
*/
virtual bool isSequencesEmpty() const { return _scriptStack.empty(); }
+
+ /**
+ * Clears the stack of pending object sequences associated with speakers in the scene
+ */
+ virtual void clearSequences();
};
} // End of namespace Scalpel
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 42bee4f127..f75dfb40cd 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -220,7 +220,7 @@ public:
Common::String _comments;
Common::Array<char> _descText;
Common::Array<Common::Rect> _zones;
- Common::Array<Object> _bgShapes;
+ ObjectArray _bgShapes;
Common::Array<CAnim> _cAnim;
Common::Array<byte> _sequenceBuffer;
Common::Array<SceneImage> _images;
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index efe0eccf60..a81041a189 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -36,8 +36,11 @@ namespace Sherlock {
SequenceEntry::SequenceEntry() {
_objNum = 0;
- _frameNumber = 0;
+ _obj = nullptr;
+ _seqStack = 0;
_seqTo = 0;
+ _sequenceNumber = _frameNumber = 0;
+ _seqCounter = _seqCounter2 = 0;
}
/*----------------------------------------------------------------*/
@@ -87,17 +90,6 @@ TalkHistoryEntry::TalkHistoryEntry() {
/*----------------------------------------------------------------*/
-TalkSequence::TalkSequence() {
- _obj = nullptr;
- _frameNumber = 0;
- _sequenceNumber = 0;
- _seqStack = 0;
- _seqTo = 0;
- _seqCounter = _seqCounter2 = 0;
-}
-
-/*----------------------------------------------------------------*/
-
Talk *Talk::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelTalk(vm);
@@ -203,7 +195,7 @@ void Talk::talkTo(const Common::String &filename) {
}
}
- while (!_sequenceStack.empty())
+ while (!isSequencesEmpty())
pullSequence();
if (IS_SERRATED_SCALPEL) {
@@ -636,62 +628,16 @@ void Talk::setTalkMap() {
}
}
-void Talk::clearSequences() {
- _sequenceStack.clear();
-}
-
void Talk::pushSequence(int speaker) {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
// Only proceed if a speaker is specified
- if (speaker == -1 || IS_ROSE_TATTOO)
- return;
-
- SequenceEntry seqEntry;
- if (!speaker) {
- seqEntry._objNum = -1;
- } else {
- seqEntry._objNum = people.findSpeaker(speaker);
-
- if (seqEntry._objNum != -1) {
- Object &obj = scene._bgShapes[seqEntry._objNum];
- for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx)
- seqEntry._sequences.push_back(obj._sequences[idx]);
-
- seqEntry._frameNumber = obj._frameNumber;
- seqEntry._seqTo = obj._seqTo;
- }
- }
-
- _sequenceStack.push(seqEntry);
- if (_scriptStack.size() >= 5)
- error("script stack overflow");
-}
-
-void Talk::pushTalkSequence(Object *obj) {
- // Check if the shape is already on the stack
- for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
- if (_talkSequenceStack[idx]._obj == obj)
- return;
- }
-
- // Find a free slot and save the details in it
- for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
- TalkSequence &ts = _talkSequenceStack[idx];
- if (ts._obj == nullptr) {
- ts._obj = obj;
- ts._frameNumber = obj->_frameNumber;
- ts._sequenceNumber = obj->_sequenceNumber;
- ts._seqStack = obj->_seqStack;
- ts._seqTo = obj->_seqTo;
- ts._seqCounter = obj->_seqCounter;
- ts._seqCounter2 = obj->_seqCounter2;
- return;
- }
+ if (speaker != -1) {
+ int objNum = people.findSpeaker(speaker);
+ if (objNum != -1)
+ pushSequenceEntry(&scene._bgShapes[objNum]);
}
-
- error("Ran out of talk sequence stack space");
}
void Talk::doScript(const Common::String &script) {
@@ -744,10 +690,15 @@ void Talk::doScript(const Common::String &script) {
// Need to switch speakers?
if (str[0] == _opcodes[OP_SWITCH_SPEAKER]) {
_speaker = str[1] - 1;
- str += IS_SERRATED_SCALPEL ? 2 : 3;
- pullSequence();
- pushSequence(_speaker);
+ if (IS_SERRATED_SCALPEL) {
+ str += 2;
+ pullSequence();
+ pushSequence(_speaker);
+ } else {
+ str += 3;
+ }
+
people.setTalkSequence(_speaker);
} else {
people.setTalkSequence(_speaker);
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
index 7d40c2235b..d0c26b529f 100644
--- a/engines/sherlock/talk.h
+++ b/engines/sherlock/talk.h
@@ -35,7 +35,6 @@ namespace Sherlock {
#define SPEAKER_REMOVE 0x80
#define MAX_TALK_SEQUENCES 11
-#define TALK_SEQUENCE_STACK_SIZE 20
enum {
OP_SWITCH_SPEAKER = 0,
@@ -120,8 +119,13 @@ typedef OpcodeReturn(Talk::*OpcodeMethod)(const byte *&str);
struct SequenceEntry {
int _objNum;
Common::Array<byte> _sequences;
- int _frameNumber;
- int _seqTo;
+ Object *_obj; // Pointer to the bgshape that these values go to
+ short _frameNumber; // Frame number in frame sequence to draw
+ short _sequenceNumber; // Start frame of sequences that are repeated
+ int _seqStack; // Allows gosubs to return to calling frame
+ int _seqTo; // Allows 1-5, 8-3 type sequences encoded
+ int _seqCounter; // How many times this sequence has been executed
+ int _seqCounter2;
SequenceEntry();
};
@@ -158,19 +162,6 @@ struct TalkHistoryEntry {
bool &operator[](int index) { return _data[index]; }
};
-struct TalkSequence {
- Object *_obj; // Pointer to the bgshape that these values go to
- short _frameNumber; // Frame number in frame sequence to draw
- short _sequenceNumber; // Start frame of sequences that are repeated
- int _seqStack; // Allows gosubs to return to calling frame
- int _seqTo; // Allows 1-5, 8-3 type sequences encoded
- int _seqCounter; // How many times this sequence has been executed
- int _seqCounter2;
-
- TalkSequence();
-};
-
-
class Talk {
friend class Scalpel::ScalpelUserInterface;
private:
@@ -182,7 +173,6 @@ protected:
SherlockEngine *_vm;
OpcodeMethod *_opcodeTable;
Common::Stack<SequenceEntry> _savedSequences;
- Common::Stack<SequenceEntry> _sequenceStack;
Common::Stack<ScriptStackEntry> _scriptStack;
Common::Array<TalkHistoryEntry> _talkHistory;
int _talkIndex;
@@ -264,7 +254,6 @@ protected:
*/
virtual void switchSpeaker(int subIndex) {}
public:
- TalkSequence _talkSequenceStack[TALK_SEQUENCE_STACK_SIZE];
Common::Array<Statement> _statements;
bool _talkToAbort;
int _talkCounter;
@@ -321,20 +310,20 @@ public:
void loadTalkFile(const Common::String &filename);
/**
- * Clears the stack of pending object sequences associated with speakers in the scene
- */
- void clearSequences();
-
- /**
* Push the sequence of a background object that's an NPC that needs to be
* saved onto the sequence stack.
*/
void pushSequence(int speaker);
/**
- * Push a given shape's sequence data onto the Rose Tattoo talk sequence stack
+ * Push the details of a passed object onto the saved sequences stack
+ */
+ virtual void pushSequenceEntry(Object *obj) = 0;
+
+ /**
+ * Clears the stack of pending object sequences associated with speakers in the scene
*/
- void pushTalkSequence(Object *obj);
+ virtual void clearSequences() {}
/**
* Pops an entry off of the script stack
@@ -366,7 +355,7 @@ public:
* Pulls a background object sequence from the sequence stack and restore's the
* object's sequence
*/
- virtual void pullSequence() = 0;
+ virtual void pullSequence(int slot = -1) = 0;
/**
* Returns true if the script stack is empty
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index 4974b3df40..a208949ae1 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -1271,7 +1271,7 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) {
// See if the Object has to wait for an Abort Talk Code
if (obj.hasAborts()) {
- talk.pushTalkSequence(&obj);
+ talk.pushSequenceEntry(&obj);
obj._gotoSeq = sequenceNum;
}
else {
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index 49becbe3b4..455d41bd48 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -216,7 +216,6 @@ void TattooTalk::showTalk() {
TattooPeople &people = *(TattooPeople *)_vm->_people;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
- _sequenceStack.clear();
people.setListenSequence(_talkTo, 129);
_talkWidget.load();
@@ -897,33 +896,60 @@ OpcodeReturn TattooTalk::cmdCallTalkFile(const byte *&str) {
return RET_SUCCESS;
}
-void TattooTalk::pullSequence() {
+void TattooTalk::pushSequenceEntry(Object *obj) {
+ // Check if the shape is already on the stack
+ for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
+ if (_sequenceStack[idx]._obj == obj)
+ return;
+ }
+
+ // Find a free slot and save the details in it
+ for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
+ SequenceEntry &seq = _sequenceStack[idx];
+ if (seq._obj == nullptr) {
+ seq._obj = obj;
+ seq._frameNumber = obj->_frameNumber;
+ seq._sequenceNumber = obj->_sequenceNumber;
+ seq._seqStack = obj->_seqStack;
+ seq._seqTo = obj->_seqTo;
+ seq._seqCounter = obj->_seqCounter;
+ seq._seqCounter2 = obj->_seqCounter2;
+ return;
+ }
+ }
+
+ error("Ran out of talk sequence stack space");
+}
+
+void TattooTalk::pullSequence(int slot) {
People &people = *_vm->_people;
for (int idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
- TalkSequence &ts = _talkSequenceStack[idx];
+ SequenceEntry &seq = _sequenceStack[idx];
+ if (slot != -1 && idx != slot)
+ continue;
// Check for an entry in this slot
- if (ts._obj) {
- Object &o = *ts._obj;
+ if (seq._obj) {
+ Object &o = *seq._obj;
// See if we're not supposed to restore it until an Allow Talk Interrupt
- if (ts._obj->hasAborts()) {
- ts._obj->_gotoSeq = -1;
- ts._obj->_restoreSlot = idx;
+ if (seq._obj->hasAborts()) {
+ seq._obj->_gotoSeq = -1;
+ seq._obj->_restoreSlot = idx;
} else {
// Restore the object's sequence information immediately
- o._frameNumber = ts._frameNumber;
- o._sequenceNumber = ts._sequenceNumber;
- o._seqStack = ts._seqStack;
- o._seqTo = ts._seqTo;
- o._seqCounter = ts._seqCounter;
- o._seqCounter2 = ts._seqCounter2;
+ o._frameNumber = seq._frameNumber;
+ o._sequenceNumber = seq._sequenceNumber;
+ o._seqStack = seq._seqStack;
+ o._seqTo = seq._seqTo;
+ o._seqCounter = seq._seqCounter;
+ o._seqCounter2 = seq._seqCounter2;
o._gotoSeq = 0;
o._talkSeq = 0;
// Flag the slot as free again
- ts._obj = nullptr;
+ seq._obj = nullptr;
}
}
}
@@ -950,7 +976,7 @@ void TattooTalk::pullSequence() {
bool TattooTalk::isSequencesEmpty() const {
for (int idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
- if (_talkSequenceStack[idx]._obj)
+ if (_sequenceStack[idx]._obj)
return false;
}
diff --git a/engines/sherlock/tattoo/tattoo_talk.h b/engines/sherlock/tattoo/tattoo_talk.h
index 68db063751..3976f15e32 100644
--- a/engines/sherlock/tattoo/tattoo_talk.h
+++ b/engines/sherlock/tattoo/tattoo_talk.h
@@ -37,6 +37,8 @@ namespace Sherlock {
namespace Tattoo {
+#define TALK_SEQUENCE_STACK_SIZE 20
+
class WidgetTalk;
class TattooTalk : public Talk {
@@ -44,6 +46,7 @@ class TattooTalk : public Talk {
private:
WidgetTalk _talkWidget;
WidgetPassword _passwordWidget;
+ SequenceEntry _sequenceStack[TALK_SEQUENCE_STACK_SIZE];
OpcodeReturn cmdCallTalkFile(const byte *&str);
OpcodeReturn cmdSwitchSpeaker(const byte *&str);
@@ -102,10 +105,15 @@ public:
virtual ~TattooTalk() {}
/**
+ * Push the details of a passed object onto the saved sequences stack
+ */
+ virtual void pushSequenceEntry(Object *obj);
+
+ /**
* Pulls a background object sequence from the sequence stack and restore's the
* object's sequence
*/
- virtual void pullSequence();
+ virtual void pullSequence(int slot = -1);
/**
* Returns true if the script stack is empty