diff options
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 49 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.h | 1 |
4 files changed, 50 insertions, 8 deletions
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 614d1b18b2..b26290612c 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -434,7 +434,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, { MAP_CALL(Sqrt), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, kStrAt_workarounds }, - { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, kStrCat_workarounds }, + { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, NULL }, { MAP_CALL(StrCmp), SIG_EVERYWHERE, "rr(i)", NULL, NULL }, { MAP_CALL(StrCpy), SIG_EVERYWHERE, "r[r0](i)", NULL, NULL }, { MAP_CALL(StrEnd), SIG_EVERYWHERE, "r", NULL, NULL }, diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index f69b6a767f..d292c4a430 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -571,6 +571,52 @@ const SciScriptSignature kq6Signatures[] = { }; // =========================================================================== +// Script 210 in the German version of Longbow handles the case where Robin +// hands out the scroll to Marion and then types his name using the hand code. +// The German version script contains a typo (probably a copy/paste error), +// and the function that is used to show each letter is called twice. The +// second time that the function is called, the second parameter passed to +// the function is undefined, thus kStrCat() that is called inside the function +// reads a random pointer and crashes. We patch all of the 5 function calls +// (one for each letter typed from "R", "O", "B", "I", "N") so that they are +// the same as the English version. Fixes bug #3048054. +const byte longbowSignatureShowHandCode[] = { + 3, + 0x78, // push1 + 0x78, // push1 + 0x72, // lofsa + +2, 2, // skip 2 bytes, offset of lofsa (the letter typed) + 0x36, // push + 0x40, // call + +2, 3, // skip 2 bytes, offset of call + 0x02, // perform the call above with 2 parameters + 0x36, // push + 0x40, // call + +2, 8, // skip 2 bytes, offset of call + 0x02, // perform the call above with 2 parameters + 0x38, 0x1c, 0x01, // pushi 011c (setMotion) + 0x39, 0x04, // pushi 04 (x) + 0x51, 0x1e, // class MoveTo + 0 +}; + +const uint16 longbowPatchShowHandCode[] = { + 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version) + PATCH_ADDTOOFFSET | +3, // leave the lofsa call untouched + // The following will remove the duplicate call + 0x32, 0x02, 0x00, // jmp 02 - skip 2 bytes (the remainder of the first call) + 0x48, // ret (dummy, should never be reached) + 0x48, // ret (dummy, should never be reached) + PATCH_END +}; + +// script, description, magic DWORD, adjust +const SciScriptSignature longbowSignatures[] = { + { 210, "hand code crash", 5, PATCH_MAGICDWORD(0x02, 0x38, 0x1c, 0x01), -14, longbowSignatureShowHandCode, longbowPatchShowHandCode }, + SCI_SIGNATUREENTRY_TERMINATOR +}; + +// =========================================================================== // this is called on every death dialog. Problem is at least the german // version of lsl6 gets title text that is far too long for the // available temp space resulting in temp space corruption @@ -1111,6 +1157,9 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin case GID_LAURABOW2: signatureTable = laurabow2Signatures; break; + case GID_LONGBOW: + signatureTable = longbowSignatures; + break; case GID_LSL6: signatureTable = larry6Signatures; break; diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index fb6c0e485f..17c9f9fa0f 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -368,12 +368,6 @@ const SciWorkaroundEntry kStrAt_workarounds[] = { }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround -const SciWorkaroundEntry kStrCat_workarounds[] = { - { GID_LONGBOW, 210, 210, 0, "giveScroll", "changeState",0x3294, 0, { WORKAROUND_FAKE, 0 } }, // German version, when handing the scroll with the druid hand code to Marion - bug #3048054 - SCI_WORKAROUNDENTRY_TERMINATOR -}; - -// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kStrLen_workarounds[] = { { GID_QFG2, 210, 2, 0, "", "export 21", 0xdeb, 0, { WORKAROUND_FAKE, 0 } }, // When saying something incorrect at the WIT, an integer is passed instead of a reference - bug #3100292 SCI_WORKAROUNDENTRY_TERMINATOR diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h index 7ab73cdff2..c7721aa787 100644 --- a/engines/sci/engine/workarounds.h +++ b/engines/sci/engine/workarounds.h @@ -95,7 +95,6 @@ extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[]; extern const SciWorkaroundEntry kSetCursor_workarounds[]; extern const SciWorkaroundEntry kSetPort_workarounds[]; extern const SciWorkaroundEntry kStrAt_workarounds[]; -extern const SciWorkaroundEntry kStrCat_workarounds[]; extern const SciWorkaroundEntry kStrLen_workarounds[]; extern const SciWorkaroundEntry kUnLoad_workarounds[]; |