mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-20 17:03:05 +00:00
SCI: Added proper fix for bug #3048054 - "LONGBOW: crash when opening hand code"
This was caused by a buggy script, most probably the result of an incorrect copy/paste while processing the original script. Fixed with a script patch.
This commit is contained in:
parent
5dce3235e9
commit
fa10ee66e4
@ -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 },
|
||||
|
@ -570,6 +570,52 @@ const SciScriptSignature kq6Signatures[] = {
|
||||
SCI_SIGNATUREENTRY_TERMINATOR
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
// 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
|
||||
@ -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;
|
||||
|
@ -367,12 +367,6 @@ const SciWorkaroundEntry kStrAt_workarounds[] = {
|
||||
SCI_WORKAROUNDENTRY_TERMINATOR
|
||||
};
|
||||
|
||||
// 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
|
||||
|
@ -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[];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user