diff options
author | Lars Skovlund | 2010-11-18 17:04:00 +0000 |
---|---|---|
committer | Lars Skovlund | 2010-11-18 17:04:00 +0000 |
commit | c5252071db22b31cc83c2687f93606b79194efe6 (patch) | |
tree | 7d2866806624b7187854a32394f714d6bd1c1aa3 | |
parent | 152e52d0156e443f8dc52bf2bddf9ef21a32f853 (diff) | |
download | scummvm-rg350-c5252071db22b31cc83c2687f93606b79194efe6.tar.gz scummvm-rg350-c5252071db22b31cc83c2687f93606b79194efe6.tar.bz2 scummvm-rg350-c5252071db22b31cc83c2687f93606b79194efe6.zip |
SCI3: Add proper support for the calle instruction
svn-id: r54327
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/script.cpp | 13 | ||||
-rw-r--r-- | engines/sci/engine/script.h | 8 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 6 |
4 files changed, 23 insertions, 6 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index d91662a695..f711530e86 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -262,7 +262,7 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } - uint16 address = scr->validateExportFunc(index); + uint16 address = scr->validateExportFunc(index, true); // Point to the heap for SCI1.1 - SCI2.1 games if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index aeeaf240fd..365db99c58 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -398,7 +398,7 @@ void Script::setLockers(int lockers) { _lockers = lockers; } -uint16 Script::validateExportFunc(int pubfunct) { +uint16 Script::validateExportFunc(int pubfunct, bool relocate) { bool exportsAreWide = (g_sci->_features->detectLofsType() == SCI_VERSION_1_MIDDLE); if (_numExports <= pubfunct) { @@ -408,8 +408,15 @@ uint16 Script::validateExportFunc(int pubfunct) { if (exportsAreWide) pubfunct *= 2; - uint16 offset = getSciVersion() != SCI_VERSION_3 ? READ_SCI11ENDIAN_UINT16(_exportTable + pubfunct) : - relocateOffsetSci3(pubfunct * 2 + 22); + + uint16 offset; + + if (getSciVersion() != SCI_VERSION_3 || !relocate) { + offset = READ_SCI11ENDIAN_UINT16(_exportTable + pubfunct); + } else { + offset = relocateOffsetSci3(pubfunct * 2 + 22); + } + VERIFY(offset < _bufSize, "invalid export function pointer"); // Check if the offset found points to a second export table (e.g. script 912 diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 2d17dde5d4..03c470b4e0 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -206,10 +206,11 @@ public: * Validate whether the specified public function is exported by * the script in the specified segment. * @param pubfunct Index of the function to validate + * @param relocate Decide whether to relocate this public function or not * @return NULL if the public function is invalid, its * offset into the script's segment otherwise */ - uint16 validateExportFunc(int pubfunct); + uint16 validateExportFunc(int pubfunct, bool relocate); /** * Marks the script as deleted. @@ -254,6 +255,11 @@ public: */ int relocateOffsetSci3(uint32 offset); + /** + * Gets an offset to the beginning of the code block in a SCI3 script + */ + int getCodeBlockOffset() { return READ_SCI11ENDIAN_UINT32(_buf); } + private: /** * Processes a relocation block within a SCI0-SCI2.1 script diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 2cd5170921..9fa579cead 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -328,7 +328,11 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP scr = s->_segMan->getScript(seg); } - const int temp = scr->validateExportFunc(pubfunct); + int temp = scr->validateExportFunc(pubfunct, false); + + if (getSciVersion() == SCI_VERSION_3) + temp += scr->getCodeBlockOffset(); + if (!temp) { #ifdef ENABLE_SCI32 // HACK: Temporarily switch to a warning in SCI32 games until we can figure out why Torin has |