From 209012a88ea89aef380f856a3d795685925ed269 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sun, 8 Jan 2012 20:11:22 +0100 Subject: SCUMM: Work around script bug in The Dig The sound of trickling water in the spider lair is started, but never explicitly stopped, so it keeps going. (Possibly not forever. When I tried it in DOSBox, it finally stopped when I got back to the Nexus.) The same sound effect is used the underwater cavern, and in that case the exit script does fade out the sound so this workaround emulates that behaviour. --- engines/scumm/script.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index cfc4b3c419..c9e3edd728 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -29,6 +29,7 @@ #include "scumm/resource.h" #include "scumm/util.h" #include "scumm/scumm_v2.h" +#include "scumm/sound.h" #include "scumm/verbs.h" namespace Scumm { @@ -935,6 +936,17 @@ void ScummEngine::runExitScript() { } if (VAR_EXIT_SCRIPT2 != 0xFF && VAR(VAR_EXIT_SCRIPT2)) runScript(VAR(VAR_EXIT_SCRIPT2), 0, 0, 0); + +#ifdef ENABLE_SCUMM_7_8 + // WORKAROUND: The spider lair (room 44) will optionally play the sound + // of trickling water (sound 215), but it never stops it. The same sound + // effect is also used in room 33, so let's do the same fade out that it + // does in that room's exit script. + if (_game.id == GID_DIG && _currentRoom == 44) { + int scriptCmds[] = { 14, 215, 0x600, 0, 30 }; + _sound->soundKludge(scriptCmds, ARRAYSIZE(scriptCmds)); + } +#endif } void ScummEngine::runEntryScript() { -- cgit v1.2.3 From 28d5922ccaf909dc52688d41da255dff44078a35 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sat, 14 Jan 2012 09:25:52 +0100 Subject: SCUMM: Fix workaround for Dig spider lair sound glitch The soundKludge() function assumes there are always 8 parameters for Digital iMUSE script commands. --- engines/scumm/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index c9e3edd728..37ea3a9a9f 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -943,7 +943,7 @@ void ScummEngine::runExitScript() { // effect is also used in room 33, so let's do the same fade out that it // does in that room's exit script. if (_game.id == GID_DIG && _currentRoom == 44) { - int scriptCmds[] = { 14, 215, 0x600, 0, 30 }; + int scriptCmds[] = { 14, 215, 0x600, 0, 30, 0, 0, 0 }; _sound->soundKludge(scriptCmds, ARRAYSIZE(scriptCmds)); } #endif -- cgit v1.2.3 From 1c32000a004cc184a8744e2467035a4c7ba2f3a5 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 7 Jan 2012 16:08:55 +0100 Subject: SCUMM: start handling object type and id correctly in mm c64 - removed complicated and unnecessary _v0ObjectIndex, _v0ObjectInInventory, _v0ObjectFlag vars - started to merge object id and type into one object value (type<<8|id) - verb preposition ids do not dependent on language -> remove from VerbSettings Note: - objects with type=0 are foreground objects. They have a state, an owner and a bg overlay image. - objects with type=1 are bg objects. They do not have a state or owner and are already contained in the bg image. The do not have an entry in objectState/OwnerTable --- engines/scumm/script.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 37ea3a9a9f..d04c3c0891 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -131,8 +131,6 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b initializeLocals(slot, vars); - // V0 Ensure we don't try and access objects via index inside the script - _v0ObjectIndex = false; runScriptNested(slot); } -- cgit v1.2.3 From de0b5f76749add219a6b667d5d2d69fb8a86d959 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 8 Jan 2012 23:51:13 +0100 Subject: SCUMM: use command stack and SentenceTab in mm c64 - MM C64 uses command stack (SentenceTab, doSentence()) now - _cmdObject... added for current SentenceTab. The _active... variables are only used to build a sentence in the inventory but never by a script. -> many routines are not needed anymore and are removed --- engines/scumm/script.cpp | 136 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 3 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index d04c3c0891..0864022c59 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -28,6 +28,7 @@ #include "scumm/object.h" #include "scumm/resource.h" #include "scumm/util.h" +#include "scumm/scumm_v0.h" #include "scumm/scumm_v2.h" #include "scumm/sound.h" #include "scumm/verbs.h" @@ -194,9 +195,14 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) { return verboffs + 8 + READ_LE_UINT32(ptr + 1); } else if (_game.version <= 2) { do { - if (!*verbptr) - return 0; - if (*verbptr == entry || *verbptr == 0xFF) + const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF); + if (!*verbptr) { + if (_game.version == 0 && entry == kVerbWalkTo) + return 13; + else + return 0; + } + if (*verbptr == entry || *verbptr == kFallbackEntry) break; verbptr += 2; } while (1); @@ -1128,6 +1134,130 @@ void ScummEngine::checkAndRunSentenceScript() { runScript(sentenceScript, 0, 0, localParamList); } +void ScummEngine_v0::walkToActorOrObject(int object) { + int x, y, dir; + ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject"); + + _walkToObject = object; + _walkToObjectIdx = getObjectIndex(object); + + if (OBJECT_V0_TYPE(object) == kObjectTypeActor) { + walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4); + x = a->getRealPos().x; + y = a->getRealPos().y; + } else { + walkActorToObject(VAR(VAR_EGO), object); + getObjectXYPos(object, x, y, dir); + } + + VAR(6) = x; + VAR(7) = y; + + if (!(a->_miscflags & kActorMiscFlagFreeze)) { + // FIXME: walking already started -> should be stopped if condition not true + //actorStartWalk(); + } +} + +void ScummEngine_v0::checkAndRunSentenceScript() { + const ScriptSlot *ss; + + if (_walkToObjectIdx) { + ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript"); + if (a->_moving) + return; + // TODO: change actor facing + _walkToObjectIdx = 0; + runSentenceScript(); + return; + } + + if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount) + return; + + //_sentenceNum--; + SentenceTab &st = _sentence[_sentenceNum - 1]; + + if (st.preposition && st.objectB == st.objectA) + return; + + // FIXME: should this be executed? + //_currentScript = 0xFF; + + int obj1Nr = OBJECT_V0_NR(st.objectA); + int obj1Type = OBJECT_V0_TYPE(st.objectA); + int obj2Nr = OBJECT_V0_NR(st.objectB); + int obj2Type = OBJECT_V0_TYPE(st.objectB); + assert(obj1Nr); + + // If two objects are involved, at least one must be in the actors inventory + if (obj2Nr && + (obj1Type != kObjectTypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && + (obj2Type != kObjectTypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) + { + if (getVerbEntrypoint(st.objectA, kVerbPickUp)) + doSentence(kVerbPickUp, st.objectA, 0); + else if (getVerbEntrypoint(st.objectB, kVerbPickUp)) + doSentence(kVerbPickUp, st.objectB, 0); + else + _sentenceNum--; + return; + } + + _cmdVerb = st.verb; + _cmdObjectNr = obj1Nr; + _cmdObjectType = obj1Type; + _cmdObject2Nr = obj2Nr; + _cmdObject2Type = obj2Type; + _sentenceNum--; + + // TODO: check sentenceNum + + if (whereIsObject(st.objectA) != WIO_INVENTORY) { + if (_currentMode != kModeKeypad) { + walkToActorOrObject(st.objectA); + return; + } + } else if (st.objectB && whereIsObject(st.objectB) != WIO_INVENTORY) { + walkToActorOrObject(st.objectB); + return; + } + + runSentenceScript(); + if (_currentMode == kModeKeypad) { + _walkToObjectIdx = 0; + } +} + +void ScummEngine_v0::runSentenceScript() { + int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + + // FIXME: should it really ever return 0xD on WalkTo, seems wrong? + if (getVerbEntrypoint(obj, _cmdVerb) != 0) { + if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) { + //slot = 0xFF; + VAR(VAR_ACTIVE_VERB) = _cmdVerb; + runScript(3, 0, 0, 0); + return; + } else { + VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr; + runObjectScript(obj, _cmdVerb, false, false, NULL); + return; + } + } else { + if (_cmdVerb == kVerbGive) { + if (_cmdObject2Nr < 8) + setOwnerOf(obj, _cmdObject2Nr); + return; + } else if (_cmdVerb == kVerbWalkTo) { + //slot = 0xFF; + VAR(VAR_ACTIVE_VERB) = _cmdVerb; + runScript(3, 0, 0, 0); + return; + } + } +} + void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { int args[24]; int verbScript; -- cgit v1.2.3 From b337823bab5994b78f639a7625ff763f061a1c0c Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 9 Jan 2012 23:21:08 +0100 Subject: SCUMM: fix verb and script handling - getVerbEntrypoint() should not handle walk-to differently (revert 0x0D handling back to original behavior) - VAR_ACTIVE_ACTOR actually is VAR_ACTIVE_OBJECT2 - runSentenceScript(): "if (_cmdVerb == kVerbWalkTo)" must be "if (_cmdVerb != kVerbWalkTo)" --- engines/scumm/script.cpp | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 0864022c59..e34c81d0d4 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -196,12 +196,8 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) { } else if (_game.version <= 2) { do { const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF); - if (!*verbptr) { - if (_game.version == 0 && entry == kVerbWalkTo) - return 13; - else - return 0; - } + if (!*verbptr) + return 0; if (*verbptr == entry || *verbptr == kFallbackEntry) break; verbptr += 2; @@ -1160,8 +1156,6 @@ void ScummEngine_v0::walkToActorOrObject(int object) { } void ScummEngine_v0::checkAndRunSentenceScript() { - const ScriptSlot *ss; - if (_walkToObjectIdx) { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript"); if (a->_moving) @@ -1175,7 +1169,6 @@ void ScummEngine_v0::checkAndRunSentenceScript() { if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount) return; - //_sentenceNum--; SentenceTab &st = _sentence[_sentenceNum - 1]; if (st.preposition && st.objectB == st.objectA) @@ -1232,30 +1225,27 @@ void ScummEngine_v0::checkAndRunSentenceScript() { void ScummEngine_v0::runSentenceScript() { int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); - // FIXME: should it really ever return 0xD on WalkTo, seems wrong? if (getVerbEntrypoint(obj, _cmdVerb) != 0) { - if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) { - //slot = 0xFF; - VAR(VAR_ACTIVE_VERB) = _cmdVerb; - runScript(3, 0, 0, 0); - return; - } else { - VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr; + // do not read in the dark + if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { + VAR(VAR_ACTIVE_OBJECT2) = _cmdObject2Nr; runObjectScript(obj, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { + // no "give to"-script: give to other kid or ignore if (_cmdObject2Nr < 8) setOwnerOf(obj, _cmdObject2Nr); return; - } else if (_cmdVerb == kVerbWalkTo) { - //slot = 0xFF; - VAR(VAR_ACTIVE_VERB) = _cmdVerb; - runScript(3, 0, 0, 0); - return; } } + + if (_cmdVerb != kVerbWalkTo) { + // perform verb's fallback action + VAR(VAR_ACTIVE_VERB) = _cmdVerb; + runScript(3, 0, 0, 0); + } } void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { -- cgit v1.2.3 From 8392d23e6bf740fb336cc98e0bbee8882108503a Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:15:53 +0100 Subject: SCUMM: reset sentence line in v0 if sentence executed --- engines/scumm/script.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index e34c81d0d4..ded47ad60a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1225,6 +1225,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { void ScummEngine_v0::runSentenceScript() { int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + drawSentenceLine(); + if (getVerbEntrypoint(obj, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { -- cgit v1.2.3 From e89dd623ef2f44bac2768327da7faeef0e2c6f5b Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Tue, 10 Jan 2012 23:39:13 +0100 Subject: SCUMM: pop stack in v0 if command's object1 and 2 are the same Otherwise the command will never be removed and the stack overflows --- engines/scumm/script.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index ded47ad60a..eb0f7bf16a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1171,8 +1171,10 @@ void ScummEngine_v0::checkAndRunSentenceScript() { SentenceTab &st = _sentence[_sentenceNum - 1]; - if (st.preposition && st.objectB == st.objectA) + if (st.preposition && st.objectB == st.objectA) { + _sentenceNum--; return; + } // FIXME: should this be executed? //_currentScript = 0xFF; -- cgit v1.2.3 From f2309998ffbcb33a96edac7f2959abc534717827 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 20:11:30 +0100 Subject: SCUMM: fix debugger for v0 --- engines/scumm/script.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index eb0f7bf16a..bc6873edf2 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1137,7 +1137,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { _walkToObject = object; _walkToObjectIdx = getObjectIndex(object); - if (OBJECT_V0_TYPE(object) == kObjectTypeActor) { + if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4); x = a->getRealPos().x; y = a->getRealPos().y; @@ -1187,8 +1187,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // If two objects are involved, at least one must be in the actors inventory if (obj2Nr && - (obj1Type != kObjectTypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && - (obj2Type != kObjectTypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) + (obj1Type != kObjectV0TypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && + (obj2Type != kObjectV0TypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); -- cgit v1.2.3 From c138ef67099cd14bedd4e0e79080e31e2b41eddd Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 15 Jan 2012 21:43:21 +0100 Subject: SCUMM: merge _activeObjectNr/_activeObjectType and _cmdObjectNr/_cmdObjectType --- engines/scumm/script.cpp | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index bc6873edf2..3fa89b68fb 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1179,16 +1179,12 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // FIXME: should this be executed? //_currentScript = 0xFF; - int obj1Nr = OBJECT_V0_NR(st.objectA); - int obj1Type = OBJECT_V0_TYPE(st.objectA); - int obj2Nr = OBJECT_V0_NR(st.objectB); - int obj2Type = OBJECT_V0_TYPE(st.objectB); - assert(obj1Nr); + assert(st.objectA); // If two objects are involved, at least one must be in the actors inventory - if (obj2Nr && - (obj1Type != kObjectV0TypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) && - (obj2Type != kObjectV0TypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO))) + if (st.objectB && + (OBJECT_V0_TYPE(st.objectA) != kObjectV0TypeFG || _objectOwnerTable[st.objectA] != VAR(VAR_EGO)) && + (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); @@ -1200,10 +1196,8 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } _cmdVerb = st.verb; - _cmdObjectNr = obj1Nr; - _cmdObjectType = obj1Type; - _cmdObject2Nr = obj2Nr; - _cmdObject2Type = obj2Type; + _cmdObject = st.objectA; + _cmdObject2 = st.objectB; _sentenceNum--; // TODO: check sentenceNum @@ -1225,22 +1219,21 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } void ScummEngine_v0::runSentenceScript() { - int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); - drawSentenceLine(); - if (getVerbEntrypoint(obj, _cmdVerb) != 0) { + if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { - VAR(VAR_ACTIVE_OBJECT2) = _cmdObject2Nr; - runObjectScript(obj, _cmdVerb, false, false, NULL); + VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_NR(_cmdObject2); + runObjectScript(_cmdObject, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { // no "give to"-script: give to other kid or ignore - if (_cmdObject2Nr < 8) - setOwnerOf(obj, _cmdObject2Nr); + int actor = OBJECT_V0_NR(_cmdObject2); + if (actor < 8) + setOwnerOf(_cmdObject, actor); return; } } -- cgit v1.2.3 From 347035385e3608c3107db7b9cba0673ce9e03a22 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Mon, 16 Jan 2012 22:32:46 +0100 Subject: SCUMM: merge object v0 id and type into one object var --- engines/scumm/script.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 3fa89b68fb..588ebaffb9 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1138,7 +1138,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { _walkToObjectIdx = getObjectIndex(object); if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { - walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4); + walkActorToActor(VAR(VAR_EGO), OBJECT_V0_ID(object), 4); x = a->getRealPos().x; y = a->getRealPos().y; } else { @@ -1224,14 +1224,14 @@ void ScummEngine_v0::runSentenceScript() { if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark if (!(_cmdVerb == kVerbRead && _currentLights == 0)) { - VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_NR(_cmdObject2); + VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_ID(_cmdObject2); runObjectScript(_cmdObject, _cmdVerb, false, false, NULL); return; } } else { if (_cmdVerb == kVerbGive) { // no "give to"-script: give to other kid or ignore - int actor = OBJECT_V0_NR(_cmdObject2); + int actor = OBJECT_V0_ID(_cmdObject2); if (actor < 8) setOwnerOf(_cmdObject, actor); return; -- cgit v1.2.3 From 2f1336cdf07b59c560d082a1ce3bb7986a3913df Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 21 Jan 2012 14:06:19 +0100 Subject: SCUMM: fix blank sentence line in v0 after cutscenes and remove unused parameter of resetSentence() --- engines/scumm/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 588ebaffb9..6dac647714 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1219,7 +1219,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { } void ScummEngine_v0::runSentenceScript() { - drawSentenceLine(); + _redrawSentenceLine = true; if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) { // do not read in the dark -- cgit v1.2.3 From 1da715719c89e5cb185accf48300ba1d75c63b96 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:10:46 +0100 Subject: SCUMM: handle actor freeze in walkToActorOrObject() --- engines/scumm/script.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 6dac647714..31eef50a6a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1149,9 +1149,9 @@ void ScummEngine_v0::walkToActorOrObject(int object) { VAR(6) = x; VAR(7) = y; - if (!(a->_miscflags & kActorMiscFlagFreeze)) { - // FIXME: walking already started -> should be stopped if condition not true - //actorStartWalk(); + // actor must not move if frozen + if (a->_miscflags & kActorMiscFlagFreeze) + a->stopActorMoving(); } } -- cgit v1.2.3 From fb684565412c69aeb0d0a9837fc5a76b98cbe285 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:13:58 +0100 Subject: SCUMM: complete handling of pending walkTo actions for sentence commands in v0 --- engines/scumm/script.cpp | 53 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 10 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 31eef50a6a..cda2b3cd82 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1135,7 +1135,7 @@ void ScummEngine_v0::walkToActorOrObject(int object) { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject"); _walkToObject = object; - _walkToObjectIdx = getObjectIndex(object); + _walkToObjectState = kWalkToObjectStateWalk; if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) { walkActorToActor(VAR(VAR_EGO), OBJECT_V0_ID(object), 4); @@ -1152,19 +1152,52 @@ void ScummEngine_v0::walkToActorOrObject(int object) { // actor must not move if frozen if (a->_miscflags & kActorMiscFlagFreeze) a->stopActorMoving(); +} + +bool ScummEngine_v0::checkPendingWalkAction() { + // before a sentence script is executed, it might be necessary to walk to + // and pickup objects before. Check if such an action is pending and handle + // it if available. + if (_walkToObjectState == kWalkToObjectStateDone) + return false; + + int actor = VAR(VAR_EGO); + ActorC64 *a = (ActorC64 *)derefActor(actor, "checkAndRunSentenceScript"); + + // wait until walking or turning action is finished + if (a->_moving) + return true; + + // after walking and turning finally execute the script + if (_walkToObjectState == kWalkToObjectStateTurn) { + runSentenceScript(); + // change actor facing + } else if (getObjActToObjActDist(actorToObj(actor), _walkToObject) <= 4) { + if (objIsActor(_walkToObject)) { // walk to actor finished + // make actors turn to each other + a->faceToObject(_walkToObject); + int otherActor = objToActor(_walkToObject); + // ignore the plant + if (otherActor != 19) { + Actor *b = derefActor(otherActor, "checkAndRunSentenceScript(2)"); + b->faceToObject(actorToObj(actor)); + } + } else { // walk to object finished + int x, y, dir; + getObjectXYPos(_walkToObject, x, y, dir); + a->turnToDirection(dir); + } + _walkToObjectState = kWalkToObjectStateTurn; + return true; } + + _walkToObjectState = kWalkToObjectStateDone; + return false; } void ScummEngine_v0::checkAndRunSentenceScript() { - if (_walkToObjectIdx) { - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript"); - if (a->_moving) - return; - // TODO: change actor facing - _walkToObjectIdx = 0; - runSentenceScript(); + if (checkPendingWalkAction()) return; - } if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount) return; @@ -1214,7 +1247,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { runSentenceScript(); if (_currentMode == kModeKeypad) { - _walkToObjectIdx = 0; + _walkToObjectState = kWalkToObjectStateDone; } } -- cgit v1.2.3 From e3f9a09d49aaeb4657862ca734d20279e75c869f Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sun, 22 Jan 2012 23:20:27 +0100 Subject: SCUMM: keep track of the number of nested script calls for a sentence command in v0 If for instance an object necessary for the sentence command is not reachable or pickupable (try to use faucet (object 55) with jar with water in microwave (object 50), the pick-up script of the jar will tell the actor to pickup object 99 (jar not in microwave)) the actor will try to pick-up the jar infinitely. This is fixed by counting the amount of nested scripts the sentence command has called (directly or indirectly) so far and aborts it if there have been too many. --- engines/scumm/script.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index cda2b3cd82..b51452170a 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1209,8 +1209,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { return; } - // FIXME: should this be executed? - //_currentScript = 0xFF; + _currentScript = 0xFF; assert(st.objectA); @@ -1233,7 +1232,19 @@ void ScummEngine_v0::checkAndRunSentenceScript() { _cmdObject2 = st.objectB; _sentenceNum--; - // TODO: check sentenceNum + // abort sentence execution if the number of nested scripts is too high. + // This might happen for instance if the sentence command depends on an + // object that the actor has to pick-up in a nested doSentence() call. + // If the actor is not able to pick-up the object (e.g. because it is not + // reachable or pickupable) a nested pick-up command is triggered again + // and again, so the actual sentence command will never be executed. + // In this case the sentence command has to be aborted. + _sentenceNestedCount++; + if (_sentenceNestedCount > 6) { + _sentenceNestedCount = 0; + _sentenceNum = 0; + return; + } if (whereIsObject(st.objectA) != WIO_INVENTORY) { if (_currentMode != kModeKeypad) { -- cgit v1.2.3 From f299fc295e620a71d5fbb783b549b10807c97b99 Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sat, 28 Jan 2012 00:02:05 +1100 Subject: SCUMM: Fix for V0 objects --- engines/scumm/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index b51452170a..1d2581f915 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1000,7 +1000,7 @@ void ScummEngine::killScriptsAndResources() { for (i = 0; i < _numNewNames; i++) { const int obj = _newNames[i]; if (obj) { - const int owner = getOwner(obj); + const int owner = getOwner( (_game.version != 0 ? obj : OBJECT_V0_ID(obj) ) ); // We can delete custom name resources if either the object is // no longer in use (i.e. not owned by anyone anymore); or if // it is an object which is owned by a room. -- cgit v1.2.3 From 08e1e127e9a03b10b83b790458bdfff5130aa510 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 28 Jan 2012 21:15:05 +0100 Subject: SCUMM: handle v0 distance check in checkPendingWalkAction() correctly --- engines/scumm/script.cpp | 50 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 1d2581f915..63f04c1f32 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1162,7 +1162,7 @@ bool ScummEngine_v0::checkPendingWalkAction() { return false; int actor = VAR(VAR_EGO); - ActorC64 *a = (ActorC64 *)derefActor(actor, "checkAndRunSentenceScript"); + ActorC64 *a = (ActorC64 *)derefActor(actor, "checkPendingWalkAction"); // wait until walking or turning action is finished if (a->_moving) @@ -1172,23 +1172,41 @@ bool ScummEngine_v0::checkPendingWalkAction() { if (_walkToObjectState == kWalkToObjectStateTurn) { runSentenceScript(); // change actor facing - } else if (getObjActToObjActDist(actorToObj(actor), _walkToObject) <= 4) { - if (objIsActor(_walkToObject)) { // walk to actor finished - // make actors turn to each other - a->faceToObject(_walkToObject); - int otherActor = objToActor(_walkToObject); - // ignore the plant - if (otherActor != 19) { - Actor *b = derefActor(otherActor, "checkAndRunSentenceScript(2)"); - b->faceToObject(actorToObj(actor)); + } else { + int x, y, distX, distY; + if (objIsActor(_walkToObject)) { + Actor *b = derefActor(objToActor(_walkToObject), "checkPendingWalkAction(2)"); + x = b->getRealPos().x; + y = b->getRealPos().y; + if (x < a->getRealPos().x) + x += 4; + else + x -= 4; + } else { + getObjectXYPos(_walkToObject, x, y); + } + AdjustBoxResult abr = a->adjustXYToBeInBox(x, y); + distX = ABS(a->getRealPos().x - abr.x); + distY = ABS(a->getRealPos().y - abr.y); + + if (distX <= 4 && distY <= 8) { + if (objIsActor(_walkToObject)) { // walk to actor finished + // make actors turn to each other + a->faceToObject(_walkToObject); + int otherActor = objToActor(_walkToObject); + // ignore the plant + if (otherActor != 19) { + Actor *b = derefActor(otherActor, "checkPendingWalkAction(3)"); + b->faceToObject(actorToObj(actor)); + } + } else { // walk to object finished + int x, y, dir; + getObjectXYPos(_walkToObject, x, y, dir); + a->turnToDirection(dir); } - } else { // walk to object finished - int x, y, dir; - getObjectXYPos(_walkToObject, x, y, dir); - a->turnToDirection(dir); + _walkToObjectState = kWalkToObjectStateTurn; + return true; } - _walkToObjectState = kWalkToObjectStateTurn; - return true; } _walkToObjectState = kWalkToObjectStateDone; -- cgit v1.2.3 From 434aaaf0c0cdbcc8a1ebc0e461f1e31582126f92 Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 11:18:14 +0100 Subject: SCUMM: fix gcc compiler warnings --- engines/scumm/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 63f04c1f32..8880963698 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1200,8 +1200,8 @@ bool ScummEngine_v0::checkPendingWalkAction() { b->faceToObject(actorToObj(actor)); } } else { // walk to object finished - int x, y, dir; - getObjectXYPos(_walkToObject, x, y, dir); + int tmpX, tmpY, dir; + getObjectXYPos(_walkToObject, tmpX, tmpY, dir); a->turnToDirection(dir); } _walkToObjectState = kWalkToObjectStateTurn; -- cgit v1.2.3 From e14e4ab3b035012781abfbac500e6de88e0ad60b Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 14:49:44 +0100 Subject: SCUMM: adjust to coding style-guide --- engines/scumm/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 8880963698..3bd70d0e24 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1000,7 +1000,7 @@ void ScummEngine::killScriptsAndResources() { for (i = 0; i < _numNewNames; i++) { const int obj = _newNames[i]; if (obj) { - const int owner = getOwner( (_game.version != 0 ? obj : OBJECT_V0_ID(obj) ) ); + const int owner = getOwner((_game.version != 0 ? obj : OBJECT_V0_ID(obj))); // We can delete custom name resources if either the object is // no longer in use (i.e. not owned by anyone anymore); or if // it is an object which is owned by a room. @@ -1234,7 +1234,7 @@ void ScummEngine_v0::checkAndRunSentenceScript() { // If two objects are involved, at least one must be in the actors inventory if (st.objectB && (OBJECT_V0_TYPE(st.objectA) != kObjectV0TypeFG || _objectOwnerTable[st.objectA] != VAR(VAR_EGO)) && - (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) + (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO))) { if (getVerbEntrypoint(st.objectA, kVerbPickUp)) doSentence(kVerbPickUp, st.objectA, 0); -- cgit v1.2.3 From 9dd6105ce62210509207dc61607543b7bcf5639d Mon Sep 17 00:00:00 2001 From: Tobias Gunkel Date: Sat, 4 Feb 2012 18:34:08 +0100 Subject: SCUMM: replace "c64" with "v0" when it applies to both C64 and AppleII v0 versions In addition some routines (e.g. the gfx ones) that are even used in v1. --- engines/scumm/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/scumm/script.cpp') diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 3bd70d0e24..39420ee974 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1132,7 +1132,7 @@ void ScummEngine::checkAndRunSentenceScript() { void ScummEngine_v0::walkToActorOrObject(int object) { int x, y, dir; - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject"); + Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "walkToObject"); _walkToObject = object; _walkToObjectState = kWalkToObjectStateWalk; @@ -1162,7 +1162,7 @@ bool ScummEngine_v0::checkPendingWalkAction() { return false; int actor = VAR(VAR_EGO); - ActorC64 *a = (ActorC64 *)derefActor(actor, "checkPendingWalkAction"); + Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction"); // wait until walking or turning action is finished if (a->_moving) -- cgit v1.2.3