diff options
-rw-r--r-- | engines/sci/engine/script.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 66 |
2 files changed, 68 insertions, 0 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 3ba550adf9..4c940804b8 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -332,6 +332,8 @@ uint16 Script::validateExportFunc(int pubfunct) { if (offset == 0) { // Check if the game has a second export table (e.g. script 912 in Camelot) // Fixes bug #3039785 + if (g_sci->getGameId() == GID_ECOQUEST) // cheap fix in here for eco quest 1, [md5] plz look into this TODO FIXME + return offset; const uint16 *secondExportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS, 0); if (secondExportTable) { diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 080f9e3325..5fc93421cd 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -51,6 +51,70 @@ struct SciScriptSignature { // - if not EOS, an adjust offset and the actual bytes // - rinse and repeat +// stayAndHelp::changeState (0) is called when ego swims to the left or right +// boundaries of room 660. Normally a textbox is supposed to get on screen +// but the call is wrong, so not only do we get an error message the script +// is also hanging because the cue won't get sent out +// This also happens in sierra sci - ffs. bug #3038387 +const byte ecoquest1SignatureStayAndHelp[] = { + 40, + 0x3f, 0x01, // link 01 + 0x87, 0x01, // lap param[1] + 0x65, 0x14, // aTop state + 0x36, // push + 0x3c, // dup + 0x35, 0x00, // ldi 00 + 0x1a, // eq? + 0x31, 0x1c, // bnt [next state] + 0x76, // push0 + 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off) + 0x38, 0x22, 0x01, // pushi 0122 + 0x78, // push1 + 0x76, // push0 + 0x81, 0x00, // lag global[0] + 0x4a, 0x06, // send 06 - ego::setMotion(0) + 0x39, 0x6e, // pushi 6e (selector init) + 0x39, 0x04, // pushi 04 + 0x76, // push0 + 0x76, // push0 + 0x39, 0x17, // pushi 17 + 0x7c, // pushSelf + 0x51, 0x82, // class EcoNarrator + 0x4a, 0x0c, // send 0c - EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!) + 0x33, // jmp [end] + 0 +}; + +const uint16 ecoquest1PatchStayAndHelp[] = { + 0x87, 0x01, // lap param[1] + 0x65, 0x14, // aTop state + 0x36, // push + 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes) + 0x39, 0x00, // pushi 0 (wasting 1 byte here) + 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off) + 0x38, 0x22, 0x01, // pushi 0122 + 0x78, // push1 + 0x76, // push0 + 0x81, 0x00, // lag global[0] + 0x4a, 0x06, // send 06 - ego::setMotion(0) + 0x39, 0x6e, // pushi 6e (selector init) + 0x39, 0x06, // pushi 06 + 0x39, 0x02, // pushi 02 (additional 2 bytes) + 0x76, // push0 + 0x76, // push0 + 0x39, 0x17, // pushi 17 + 0x7c, // pushSelf + 0x38, 0x80, 0x02, // pushi 280 (additional 3 bytes) + 0x51, 0x82, // class EcoNarrator + 0x4a, 0x10, // send 10 - EcoNarrator::init(2, 0, 0, 23, self, 640) + PATCH_END +}; + +// script, description, magic DWORD, adjust +const SciScriptSignature ecoquest1Signatures[] = { + { 660, "CD: bad messagebox and freeze", PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp }, + { 0, NULL, 0, 0, NULL, NULL } +}; // daySixBeignet::changeState (4) is called when the cop goes out and sets cycles to 220. // this is not enough time to get to the door, so we patch that to 23 seconds @@ -346,6 +410,8 @@ int32 Script::findSignature(const SciScriptSignature *signature, const byte *scr void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) { const SciScriptSignature *signatureTable = NULL; + if (g_sci->getGameId() == GID_ECOQUEST) + signatureTable = ecoquest1Signatures; if (g_sci->getGameId() == GID_GK1) signatureTable = gk1Signatures; // hoyle4 now works due workaround inside GfxPorts |