aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2017-02-22 12:38:07 -0600
committerColin Snover2017-04-23 13:07:25 -0500
commita799cb3462a220afcd705c74291075f98520d87c (patch)
treeb5ac536e8532cec31e0462f6b43fe27df0ce808c /engines
parentfc02b34215f218d2e0a0f20990654b120f52efd0 (diff)
downloadscummvm-rg350-a799cb3462a220afcd705c74291075f98520d87c.tar.gz
scummvm-rg350-a799cb3462a220afcd705c74291075f98520d87c.tar.bz2
scummvm-rg350-a799cb3462a220afcd705c74291075f98520d87c.zip
SCI: Fix SCI3 exports
Export functions may be relocated above 64k in SCI3, but exports that do not have an entry in the relocation table must be handled the same as SCI1.1-2.1.
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/guest_additions.cpp2
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/script.cpp21
-rw-r--r--engines/sci/engine/script.h5
4 files changed, 19 insertions, 11 deletions
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index 4a3afcdca9..6ed2cd901a 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -397,7 +397,7 @@ static const byte SRTorinPatch[] = {
};
void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const {
- const uint16 address = script.validateExportFunc(2, true);
+ const uint32 address = script.validateExportFunc(2, true);
byte *patchPtr = const_cast<byte *>(script.getBuf(address));
memcpy(patchPtr, SRTorinPatch, sizeof(SRTorinPatch));
if (g_sci->isBE()) {
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 30a1fab71a..98c35fcb49 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -246,7 +246,7 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
- uint16 address = scr->validateExportFunc(index, true);
+ uint32 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_LATE)
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index fa17dc0419..cd75a97969 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -505,6 +505,7 @@ void Script::identifyOffsets() {
if (_buf->size() < 22)
error("Script::identifyOffsets(): script %d smaller than expected SCI3-header", _nr);
+ _codeOffset = _buf->getUint32LEAt(0);
sci3StringOffset = _buf->getUint32LEAt(4);
sci3RelocationOffset = _buf->getUint32LEAt(8);
@@ -796,23 +797,29 @@ uint32 Script::validateExportFunc(int pubfunct, bool relocSci3) {
if (exportsAreWide)
pubfunct *= 2;
- uint32 offset;
+ int offset;
if (getSciVersion() != SCI_VERSION_3) {
offset = _exports.getUint16SEAt(pubfunct);
} else {
- if (!relocSci3)
- offset = _exports.getUint16SEAt(pubfunct) + getCodeBlockOffsetSci3();
- else
- offset = relocateOffsetSci3(pubfunct * 2 + 22);
+ if (!relocSci3) {
+ offset = _exports.getUint16SEAt(pubfunct) + getCodeBlockOffset();
+ } else {
+ offset = relocateOffsetSci3(pubfunct * sizeof(uint16) + /* header size */ 22);
+ // Some offsets below 0xFFFF are left as-is in the export table,
+ // e.g. Lighthouse script 64990
+ if (offset == -1) {
+ offset = _exports.getUint16SEAt(pubfunct) + getCodeBlockOffset();
+ }
+ }
}
// TODO: Check if this should be done for SCI1.1 games as well
if (getSciVersion() >= SCI_VERSION_2 && offset == 0) {
- offset = _codeOffset;
+ offset = getCodeBlockOffset();
}
- if (offset >= _buf->size())
+ if (offset == -1 || offset >= (int)_buf->size())
error("Invalid export function pointer");
return offset;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 2be3fd0264..f63b312647 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -260,9 +260,10 @@ public:
int relocateOffsetSci3(uint32 offset) const;
/**
- * Gets an offset to the beginning of the code block in a SCI3 script
+ * Gets an offset to the beginning of the code block in a SCI1.1 or later
+ * script
*/
- int getCodeBlockOffsetSci3() { return _buf->getInt32SEAt(0); }
+ int getCodeBlockOffset() { return _codeOffset; }
/**
* Get the offset array