Skip to content

Commit

Permalink
SCI: Fix SCI3 exports
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
csnover committed Apr 23, 2017
1 parent fc02b34 commit a799cb3
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 11 deletions.
2 changes: 1 addition & 1 deletion engines/sci/engine/guest_additions.cpp
Expand Up @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion engines/sci/engine/kscripts.cpp
Expand Up @@ -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)
Expand Down
21 changes: 14 additions & 7 deletions engines/sci/engine/script.cpp
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions engines/sci/engine/script.h
Expand Up @@ -260,9 +260,10 @@ class Script : public SegmentObj {
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
Expand Down

0 comments on commit a799cb3

Please sign in to comment.