diff options
author | Filippos Karapetis | 2010-08-31 10:12:35 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-08-31 10:12:35 +0000 |
commit | 7e6141dcfa880b5d24032351a4a0bffd2f47d3f8 (patch) | |
tree | 4a4cadd5da0cd96c77a417bddd68acc11c9eb1c4 | |
parent | 07e4fe9fdcb2a42f1c3d0de08aa9e92d0f98aba8 (diff) | |
download | scummvm-rg350-7e6141dcfa880b5d24032351a4a0bffd2f47d3f8.tar.gz scummvm-rg350-7e6141dcfa880b5d24032351a4a0bffd2f47d3f8.tar.bz2 scummvm-rg350-7e6141dcfa880b5d24032351a4a0bffd2f47d3f8.zip |
SCI: Added automatic detection of some static selectors
which keep changing location in each game
svn-id: r52466
-rw-r--r-- | engines/sci/engine/static_selectors.cpp | 92 |
1 files changed, 78 insertions, 14 deletions
diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index b65903eb82..de7adb68c4 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -27,6 +27,7 @@ // them. This includes the King's Quest IV Demo and LSL3 Demo. #include "sci/engine/kernel.h" +#include "sci/engine/seg_manager.h" namespace Sci { @@ -158,6 +159,81 @@ Common::StringArray Kernel::checkStaticSelectorNames() { } } + // Now, we need to find out selectors which keep changing place... + // We do that by dissecting game objects, and looking for selectors at + // specified locations. + + // We need to initialize script 0 here, to make sure that it's always + // located at segment 1. + _segMan->instantiateScript(0); + + // The Actor class contains the init, xLast and yLast selectors, which + // we reference directly. It's always in script 998, so we need to + // explicitly load it here. + if (_resMan->testResource(ResourceId(kResourceTypeScript, 998))) { + _segMan->instantiateScript(998); + + const Object *actorClass = _segMan->getObject(_segMan->findObjectByName("Actor")); + + if (actorClass) { + // The init selector is always the first function + int initSelectorPos = actorClass->getFuncSelector(0); + + if (names.size() < (uint32)initSelectorPos + 1) + names.resize((uint32)initSelectorPos + 1); + + names[initSelectorPos] = "init"; + + if ((getSciVersion() >= SCI_VERSION_1_EGA)) { + // Find the xLast and yLast selectors, used in kDoBresen + + // xLast and yLast always come between illegalBits and xStep + int illegalBitsSelectorPos = actorClass->locateVarSelector(_segMan, 15 + offset); // illegalBits + int xStepSelectorPos = actorClass->locateVarSelector(_segMan, 51 + offset); // xStep + if (xStepSelectorPos - illegalBitsSelectorPos != 3) { + error("illegalBits and xStep selectors aren't found in " + "known locations. illegalBits = %d, xStep = %d", + illegalBitsSelectorPos, xStepSelectorPos); + } + + int xLastSelectorPos = actorClass->getVarSelector(illegalBitsSelectorPos + 1); + int yLastSelectorPos = actorClass->getVarSelector(illegalBitsSelectorPos + 2); + + if (names.size() < (uint32)yLastSelectorPos + 1) + names.resize((uint32)yLastSelectorPos + 1); + + names[xLastSelectorPos] = "xLast"; + names[yLastSelectorPos] = "yLast"; + } // if ((getSciVersion() >= SCI_VERSION_1_EGA)) + } // if (actorClass) + + _segMan->uninstantiateScript(998); + } // if (_resMan->testResource(ResourceId(kResourceTypeScript, 998))) + + if (_resMan->testResource(ResourceId(kResourceTypeScript, 981))) { + // The SysWindow class contains the open selectors, which we + // reference directly. It's always in script 981, so we need to + // explicitly load it here + _segMan->instantiateScript(981); + + const Object *sysWindowClass = _segMan->getObject(_segMan->findObjectByName("SysWindow")); + + if (sysWindowClass) { + if (sysWindowClass->getMethodCount() < 2) + error("The SysWindow class has less than 2 methods"); + + // The open selector is always the second function + int openSelectorPos = sysWindowClass->getFuncSelector(1); + + if (names.size() < (uint32)openSelectorPos + 1) + names.resize((uint32)openSelectorPos + 1); + + names[openSelectorPos] = "open"; + } + + _segMan->uninstantiateScript(981); + } // if (_resMan->testResource(ResourceId(kResourceTypeScript, 981))) + if (g_sci->getGameId() == GID_HOYLE4) { // The demo of Hoyle 4 is one of the few demos with lip syncing and no selector vocabulary. // This needs two selectors, "syncTime" and "syncCue", which keep changing positions in each @@ -168,25 +244,13 @@ Common::StringArray Kernel::checkStaticSelectorNames() { names[274] = "syncTime"; names[275] = "syncCue"; - } else if (g_sci->getGameId() == GID_ISLANDBRAIN) { - // The demo of Island of Dr. Brain needs the init selector set to match up with the full - // game's workaround - bug #3035033 - if (names.size() < 111) - names.resize(111); - - names[110] = "init"; } else if (g_sci->getGameId() == GID_LAURABOW2) { - // The floppy of version needs the open and changeState selectors set to match up with the - // CD version's workarounds - bugs #3035694, #3036291 and #3041257. Also, xLast and yLast - // are set, since they're used inside kDoBresen() + // The floppy of version needs the changeState selector set to match up with the + // CD version's workarounds. if (names.size() < 251) names.resize(251); - names[110] = "init"; names[144] = "changeState"; - names[189] = "open"; - names[249] = "xLast"; - names[250] = "yLast"; } #ifdef ENABLE_SCI32 |