diff options
-rw-r--r-- | scumm/intern.h | 2 | ||||
-rw-r--r-- | scumm/script.cpp | 11 | ||||
-rw-r--r-- | scumm/script_v2.cpp | 92 | ||||
-rw-r--r-- | scumm/scumm.h | 2 |
4 files changed, 45 insertions, 62 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index ca2d50e38f..88a2dbfea4 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -220,8 +220,6 @@ protected: void resetSentence(); void setUserState(byte state); - void stopObjectScript(int script, bool background); - /* Version 2 script opcodes */ void o2_actorFromPos(); void o2_actorSet(); diff --git a/scumm/script.cpp b/scumm/script.cpp index 37f6bb8e0c..d3fb2f72e0 100644 --- a/scumm/script.cpp +++ b/scumm/script.cpp @@ -76,15 +76,15 @@ void Scumm::runScript(int script, bool freezeResistant, bool recursive, int *lva runScriptNested(slot); } -void Scumm::runObjectScript(int object, int entry, bool freezeResistant, bool recursive, int *vars) { +void Scumm::runObjectScript(int object, int entry, bool freezeResistant, bool recursive, int *vars, int slot) { ScriptSlot *s; uint32 obcd; - int slot, where, offs; + int where, offs; if (!object) return; - if (!recursive) + if (!recursive && (_version >= 3)) stopObjectScript(object); where = whereIsObject(object); @@ -95,7 +95,10 @@ void Scumm::runObjectScript(int object, int entry, bool freezeResistant, bool re } obcd = getOBCDOffs(object); - slot = getScriptSlot(); + + // Find a free object slot, unless one was specified + if (slot == -1) + slot = getScriptSlot(); offs = getVerbEntrypoint(object, entry); if (offs == 0) diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index ea8546b8a7..04e13b83b9 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -918,17 +918,44 @@ void Scumm_v2::o2_doSentence() { if (st->verb == 254) { Scumm::stopObjectScript(st->objectA); - } else if (st->verb != 253 && st->verb != 250) { - VAR(VAR_ACTIVE_VERB) = st->verb; - VAR(VAR_ACTIVE_OBJECT1) = st->objectA; - VAR(VAR_ACTIVE_OBJECT2) = st->objectB; - - stopObjectScript(st->objectA, false); - runObjectScript(st->objectA, st->verb, false, false, NULL); } else { - bool isBackgroundScript = (st->verb == 250); - stopObjectScript(st->objectA, isBackgroundScript); - runObjectScript(st->objectA, 253, isBackgroundScript, false, NULL); + bool isBackgroundScript; + bool isSpecialVerb; + if (st->verb != 253 && st->verb != 250) { + VAR(VAR_ACTIVE_VERB) = st->verb; + VAR(VAR_ACTIVE_OBJECT1) = st->objectA; + VAR(VAR_ACTIVE_OBJECT2) = st->objectB; + + isBackgroundScript = false; + isSpecialVerb = false; + } else { + isBackgroundScript = (st->verb == 250); + isSpecialVerb = true; + st->verb = 253; + } + + // Check if an object script for this object is already running. If + // so, reuse its script slot. Note that we abuse two script flags: + // freezeResistant and recursive. We use them to track two + // script flags used in V1/V2 games. The main reason we do it this + // ugly evil way is to avoid having to introduce yet another save + // game revision. + int slot = -1; + ScriptSlot *ss; + int i; + + ss = vm.slot; + for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) { + if (st->objectA == ss->number && + ss->freezeResistant == isBackgroundScript && + ss->recursive == isSpecialVerb && + (ss->where == WIO_ROOM || ss->where == WIO_INVENTORY || ss->where == WIO_FLOBJECT)) { + slot = i; + break; + } + } + + runObjectScript(st->objectA, st->verb, isBackgroundScript, isSpecialVerb, NULL, slot); } break; case 2: @@ -1550,48 +1577,3 @@ void Scumm_v2::resetSentence() { VAR(VAR_SENTENCE_OBJECT2) = 0; VAR(VAR_SENTENCE_PREPOSITION) = 0; } - -enum { - ssDead = 0, - ssPaused = 1, - ssRunning = 2 -}; - -/* Stop an object script 'script'*/ -void Scumm_v2::stopObjectScript(int script, bool background) { - ScriptSlot *ss; - NestedScript *nest; - int i, num; - - if (script == 0) - return; - - ss = vm.slot; - for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) { - if (script == ss->number && ss->status != ssDead && - ss->freezeResistant == background && - (ss->where == WIO_ROOM || ss->where == WIO_INVENTORY || ss->where == WIO_FLOBJECT)) { - if (ss->cutsceneOverride) - error("Object %d stopped with active cutscene/override", script); - ss->number = 0; - ss->status = ssDead; - if (_currentScript == i) - _currentScript = 0xFF; - } - } - - nest = vm.nest; - num = _numNestedScripts; - - while (num > 0) { - if (nest->number == script && - vm.slot[nest->slot].freezeResistant == background && - (nest->where == WIO_ROOM || nest->where == WIO_INVENTORY || nest->where == WIO_FLOBJECT)) { - nest->number = 0xFF; - nest->slot = 0xFF; - nest->where = 0xFF; - } - nest++; - num--; - } -} diff --git a/scumm/scumm.h b/scumm/scumm.h index 41d5ad3b1c..4fc2396023 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -563,7 +563,7 @@ public: bool isScriptRunning(int script) const; // FIXME - should be protected, used by Sound::startTalkSound protected: - void runObjectScript(int script, int entry, bool freezeResistant, bool recursive, int *vars); + void runObjectScript(int script, int entry, bool freezeResistant, bool recursive, int *vars, int slot = -1); void runScriptNested(int script); void executeScript(); void updateScriptPtr(); |