aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Skovlund2010-11-18 17:04:00 +0000
committerLars Skovlund2010-11-18 17:04:00 +0000
commitc5252071db22b31cc83c2687f93606b79194efe6 (patch)
tree7d2866806624b7187854a32394f714d6bd1c1aa3
parent152e52d0156e443f8dc52bf2bddf9ef21a32f853 (diff)
downloadscummvm-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.cpp2
-rw-r--r--engines/sci/engine/script.cpp13
-rw-r--r--engines/sci/engine/script.h8
-rw-r--r--engines/sci/engine/vm.cpp6
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