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.
This commit is contained in:
Colin Snover 2017-02-22 12:38:07 -06:00
parent fc02b34215
commit a799cb3462
4 changed files with 19 additions and 11 deletions

View file

@ -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()) {

View file

@ -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)

View file

@ -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;

View file

@ -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