From c14f27aa48f89ec1a903effe87d03029c90060c1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 16 Aug 2015 21:43:12 -0400 Subject: SHERLOCK: RT: Add missing talk sequence stack handling --- engines/sherlock/scalpel/scalpel_talk.cpp | 22 +++++++++++++ engines/sherlock/scalpel/scalpel_talk.h | 6 ++++ engines/sherlock/talk.cpp | 22 ------------- engines/sherlock/talk.h | 12 ++++---- engines/sherlock/tattoo/tattoo_talk.cpp | 51 +++++++++++++++++++++++++++++++ engines/sherlock/tattoo/tattoo_talk.h | 6 ++++ 6 files changed, 91 insertions(+), 28 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp index 2fd9ede763..b844979ffb 100644 --- a/engines/sherlock/scalpel/scalpel_talk.cpp +++ b/engines/sherlock/scalpel/scalpel_talk.cpp @@ -878,6 +878,28 @@ OpcodeReturn ScalpelTalk::cmdCallTalkFile(const byte *&str) { return RET_SUCCESS; } +void ScalpelTalk::pullSequence() { + Scene &scene = *_vm->_scene; + + if (_sequenceStack.empty()) + return; + + SequenceEntry seq = _sequenceStack.pop(); + if (seq._objNum != -1) { + Object &obj = scene._bgShapes[seq._objNum]; + + if (obj._seqSize < MAX_TALK_SEQUENCES) { + warning("Tried to restore too few frames"); + } else { + for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) + obj._sequences[idx] = seq._sequences[idx]; + + obj._frameNumber = seq._frameNumber; + obj._seqTo = seq._seqTo; + } + } +} + } // 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 7ef67050d0..6f8b62cd2f 100644 --- a/engines/sherlock/scalpel/scalpel_talk.h +++ b/engines/sherlock/scalpel/scalpel_talk.h @@ -101,6 +101,12 @@ public: * Trigger to play a 3DO talk dialog movie */ void talk3DOMovieTrigger(int subIndex); + + /** + * Pulls a background object sequence from the sequence stack and restore's the + * object's sequence + */ + virtual void pullSequence(); }; } // End of namespace Scalpel diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 4be8730da8..5213445cc7 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -640,28 +640,6 @@ void Talk::clearSequences() { _sequenceStack.clear(); } -void Talk::pullSequence() { - Scene &scene = *_vm->_scene; - - if (_sequenceStack.empty() || IS_ROSE_TATTOO) - return; - - SequenceEntry seq = _sequenceStack.pop(); - if (seq._objNum != -1) { - Object &obj = scene._bgShapes[seq._objNum]; - - if (obj._seqSize < MAX_TALK_SEQUENCES) { - warning("Tried to restore too few frames"); - } else { - for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) - obj._sequences[idx] = seq._sequences[idx]; - - obj._frameNumber = seq._frameNumber; - obj._seqTo = seq._seqTo; - } - } -} - void Talk::pushSequence(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 87ed547be7..d765b80484 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -330,12 +330,6 @@ public: * Clears the stack of pending object sequences associated with speakers in the scene */ void clearSequences(); - - /** - * Pulls a background object sequence from the sequence stack and restore's the - * object's sequence - */ - void pullSequence(); /** * Push the sequence of a background object that's an NPC that needs to be @@ -378,6 +372,12 @@ public: * Prints a single conversation option in the interface window */ virtual int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { return 0; } + + /** + * Pulls a background object sequence from the sequence stack and restore's the + * object's sequence + */ + virtual void pullSequence() = 0; }; } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp index 9d5a3dbc93..b8b8944688 100644 --- a/engines/sherlock/tattoo/tattoo_talk.cpp +++ b/engines/sherlock/tattoo/tattoo_talk.cpp @@ -897,6 +897,57 @@ OpcodeReturn TattooTalk::cmdCallTalkFile(const byte *&str) { return RET_SUCCESS; } +void TattooTalk::pullSequence() { + People &people = *_vm->_people; + + for (int idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) { + TalkSequence &ts = _talkSequenceStack[idx]; + + // Check for an entry in this slot + if (ts._obj) { + Object &o = *ts._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; + } 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._gotoSeq = 0; + o._talkSeq = 0; + + // Flag the slot as free again + ts._obj = nullptr; + } + } + } + + // Handle restoring any character positioning + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { + Person &person = people[idx]; + + if (person._type == CHARACTER && !person._walkSequences.empty() && person._sequenceNumber >= TALK_UPRIGHT + && person._sequenceNumber <= LISTEN_UPLEFT) { + person.gotoStand(); + + bool done = false; + do { + person.checkSprite(); + for (int frameNum = 0; frameNum < person._frameNumber; ++frameNum) { + if (person._walkSequences[person._sequenceNumber]._sequences[frameNum] == 0) + done = true; + } + } while (!done); + } + } +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_talk.h b/engines/sherlock/tattoo/tattoo_talk.h index f84bceef87..22ac3fcc94 100644 --- a/engines/sherlock/tattoo/tattoo_talk.h +++ b/engines/sherlock/tattoo/tattoo_talk.h @@ -100,6 +100,12 @@ protected: public: TattooTalk(SherlockEngine *vm); virtual ~TattooTalk() {} + + /** + * Pulls a background object sequence from the sequence stack and restore's the + * object's sequence + */ + virtual void pullSequence(); }; } // End of namespace Tattoo -- cgit v1.2.3