diff options
author | Filippos Karapetis | 2010-08-06 21:21:39 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-08-06 21:21:39 +0000 |
commit | 96fd9e6c8273715c48556bdc6e150908f0fa04c7 (patch) | |
tree | 6a68e8fff77674f7d474bcff99693860c3a7c805 /engines | |
parent | d0ff92e2a0c96dbea82989cf94aacc28430dcfa4 (diff) | |
download | scummvm-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')
-rw-r--r-- | engines/sci/engine/script.cpp | 18 | ||||
-rw-r--r-- | engines/sci/engine/script.h | 2 |
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: /** |