aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Hoenicke2003-07-18 18:55:04 +0000
committerJochen Hoenicke2003-07-18 18:55:04 +0000
commit077b643ea04188b60c5107610328619cc7f00001 (patch)
tree0784c23dfd9dfe41de6d53b57c4bcd086a6a52cd
parentdc25058c3e633cf5ac4a369833224d878a05bac4 (diff)
downloadscummvm-rg350-077b643ea04188b60c5107610328619cc7f00001.tar.gz
scummvm-rg350-077b643ea04188b60c5107610328619cc7f00001.tar.bz2
scummvm-rg350-077b643ea04188b60c5107610328619cc7f00001.zip
Fix recursive calls of object scripts. In V2 for each object two script
can be active at the same time: One 253 script and one normal script. We misuse the recursive flag to mark 253 scripts. When starting a 253 script we stop a script that has recursive flag set and when starting a normal script we stop the script that doesn't. svn-id: r9068
-rw-r--r--scumm/intern.h3
-rw-r--r--scumm/script_v2.cpp86
2 files changed, 88 insertions, 1 deletions
diff --git a/scumm/intern.h b/scumm/intern.h
index be7382d01e..1133e84b74 100644
--- a/scumm/intern.h
+++ b/scumm/intern.h
@@ -217,6 +217,9 @@ protected:
void resetSentence();
void setUserState(byte state);
+ void runObjectScript(int object, int entry, bool freezeResistant, bool recursive, int *vars);
+ void stopObjectScript(int script, bool recursive);
+
/* Version 2 script opcodes */
void o2_actorFromPos();
void o2_actorSet();
diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp
index 92c309c247..32ff3b64b6 100644
--- a/scumm/script_v2.cpp
+++ b/scumm/script_v2.cpp
@@ -906,7 +906,7 @@ void Scumm_v2::o2_doSentence() {
_sentenceNum--;
if (st->verb == 254) {
- stopObjectScript(st->objectA);
+ stopObjectScript(st->objectA, true);
} else if (st->verb != 253 && st->verb != 250) {
VAR(VAR_ACTIVE_VERB) = st->verb;
VAR(VAR_ACTIVE_OBJECT1) = st->objectA;
@@ -1477,3 +1477,87 @@ void Scumm_v2::resetSentence() {
VAR(VAR_SENTENCE_OBJECT2) = 0;
VAR(VAR_SENTENCE_PREPOSITION) = 0;
}
+
+enum {
+ ssDead = 0,
+ ssPaused = 1,
+ ssRunning = 2
+};
+
+void Scumm_v2::runObjectScript(int object, int entry, bool freezeResistant, bool recursive, int *vars) {
+ ScriptSlot *s;
+ uint32 obcd;
+ int slot, where, offs;
+
+ if (!object)
+ return;
+
+ stopObjectScript(object, recursive);
+
+ where = whereIsObject(object);
+
+ if (where == WIO_NOT_FOUND) {
+ warning("Code for object %d not in room %d", object, _roomResource);
+ return;
+ }
+
+ obcd = getOBCDOffs(object);
+ slot = getScriptSlot();
+
+ offs = getVerbEntrypoint(object, entry);
+ if (offs == 0)
+ return;
+
+ s = &vm.slot[slot];
+ s->number = object;
+ s->offs = obcd + offs;
+ s->status = ssRunning;
+ s->where = where;
+ s->freezeResistant = freezeResistant;
+ s->recursive = recursive;
+ s->freezeCount = 0;
+ s->delayFrameCount = 0;
+
+ initializeLocals(slot, vars);
+
+ runScriptNested(slot);
+}
+
+/* Stop an object script 'script'*/
+void Scumm_v2::stopObjectScript(int script, bool recursive) {
+ ScriptSlot *ss;
+ NestedScript *nest;
+ int i, num;
+
+ if (script == 0)
+ return;
+
+ nest = vm.nest;
+ num = _numNestedScripts;
+
+ while (num > 0) {
+ if (nest->number == script &&
+ vm.slot[nest->slot].recursive == recursive &&
+ (nest->where == WIO_ROOM || nest->where == WIO_INVENTORY || nest->where == WIO_FLOBJECT)) {
+ nest->number = 0xFF;
+ nest->slot = 0xFF;
+ nest->where = 0xFF;
+ }
+ nest++;
+ num--;
+ }
+
+ ss = vm.slot;
+ for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
+ if (script == ss->number && ss->status != ssDead &&
+ ss->recursive == recursive &&
+ (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;
+ }
+ }
+}