aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorFilippos Karapetis2010-08-06 21:21:39 +0000
committerFilippos Karapetis2010-08-06 21:21:39 +0000
commit96fd9e6c8273715c48556bdc6e150908f0fa04c7 (patch)
tree6a68e8fff77674f7d474bcff99693860c3a7c805 /engines/sci/engine
parentd0ff92e2a0c96dbea82989cf94aacc28430dcfa4 (diff)
downloadscummvm-rg350-96fd9e6c8273715c48556bdc6e150908f0fa04c7.tar.gz
scummvm-rg350-96fd9e6c8273715c48556bdc6e150908f0fa04c7.tar.bz2
scummvm-rg350-96fd9e6c8273715c48556bdc6e150908f0fa04c7.zip
SCI: Added support for scripts that have more than one export table. Fixes bug #3039785 - "Conquests of Camelot: Crash in Glastonbury Tor"
svn-id: r51805
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/script.cpp18
-rw-r--r--engines/sci/engine/script.h2
2 files changed, 17 insertions, 3 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 0e4104170f..8ccedc0c00 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -476,12 +476,25 @@ uint16 Script::validateExportFunc(int pubfunct) {
uint16 offset = READ_SCI11ENDIAN_UINT16(_exportTable + pubfunct);
VERIFY(offset < _bufSize, "invalid export function pointer");
+ if (offset == 0) {
+ // Check if the game has a second export table (e.g. script 912 in Camelot)
+ // Fixes bug #3039785
+ const uint16 *secondExportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS, 0);
+
+ if (secondExportTable) {
+ secondExportTable += 3; // skip header plus 2 bytes (secondExportTable is a uint16 pointer)
+ offset = READ_SCI11ENDIAN_UINT16(secondExportTable + pubfunct);
+ VERIFY(offset < _bufSize, "invalid export function pointer");
+ }
+ }
+
return offset;
}
-byte *Script::findBlock(int type) {
+byte *Script::findBlock(int type, int skipBlockIndex) {
byte *buf = _buf;
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
+ int blockIndex = 0;
if (oldScriptHeader)
buf += 2;
@@ -491,12 +504,13 @@ byte *Script::findBlock(int type) {
if (seekerType == 0)
break;
- if (seekerType == type)
+ if (seekerType == type && blockIndex != skipBlockIndex)
return buf;
int seekerSize = READ_LE_UINT16(buf + 2);
assert(seekerSize > 0);
buf += seekerSize;
+ blockIndex++;
} while (1);
return NULL;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 4e38c68954..35daf20191 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -255,7 +255,7 @@ public:
/**
* Finds the pointer where a block of a specific type starts from
*/
- byte *findBlock(int type);
+ byte *findBlock(int type, int skipBlockIndex = -1);
private:
/**