From ed865856dc1b486c52e0a22ae6d39f686e9a79ab Mon Sep 17 00:00:00 2001 From: m-kiewitz Date: Tue, 17 Sep 2013 23:27:02 +0200 Subject: SCI: PQ1 script patch, fixes gun locker crash fixes bug #3303802 / bug #3036933 --- engines/sci/engine/script_patches.cpp | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'engines/sci') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index a8054e5bd5..5f461aab3f 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -909,6 +909,68 @@ const SciScriptSignature mothergoose256Signatures[] = { SCI_SIGNATUREENTRY_TERMINATOR }; +// =========================================================================== +// Police Quest 1 VGA +// When at the police station, you can put or get your gun from your locker. +// The script, that handles this, is buggy. It disposes the gun as soon as +// you click, but then waits 2 seconds before it also closes the locker. +// Problem is that it's possible to click again, which then results in a +// disposed object getting accessed. This happened to work by pure luck in +// SSCI. +// This patch changes the code, so that the gun is actually given away +// when the 2 seconds have passed and the locker got closed. +// Responsible method: putGun::changeState (script 341) +// Fixes bug #3036933 / #3303802 +const byte pq1vgaSignaturePutGunInLockerBug[] = { + 5, + 0x35, 0x00, // ldi 00 + 0x1a, // eq? + 0x31, 0x25, // bnt [next state check] + +22, 29, // [skip 22 bytes] + 0x38, 0x5f, 0x01, // pushi 15fh + 0x78, // push1 + 0x76, // push0 + 0x81, 0x00, // lag 00 + 0x4a, 0x06, // send 06 - ego::put(0) + 0x35, 0x02, // ldi 02 + 0x65, 0x1c, // aTop 1c (set timer to 2 seconds) + 0x33, 0x0e, // jmp [end of method] + 0x3c, // dup --- next state check target + 0x35, 0x01, // ldi 01 + 0x1a, // eq? + 0x31, 0x08, // bnt [end of method] + 0x39, 0x6f, // pushi 6fh + 0x76, // push0 + 0x72, 0x88, 0x00, // lofsa 0088 + 0x4a, 0x04, // send 04 - locker::dispose + 0 +}; + +const uint16 pq1vgaPatchPutGunInLockerBug[] = { + PATCH_ADDTOOFFSET | +3, + 0x31, 0x1c, // bnt [next state check] + PATCH_ADDTOOFFSET | +22, + 0x35, 0x02, // ldi 02 + 0x65, 0x1c, // aTop 1c (set timer to 2 seconds) + 0x33, 0x17, // jmp [end of method] + 0x3c, // dup --- next state check target + 0x35, 0x01, // ldi 01 + 0x1a, // eq? + 0x31, 0x11, // bnt [end of method] + 0x38, 0x5f, 0x01, // pushi 15fh + 0x78, // push1 + 0x76, // push0 + 0x81, 0x00, // lag 00 + 0x4a, 0x06, // send 06 - ego::put(0) + PATCH_END +}; + +// script, description, magic DWORD, adjust +const SciScriptSignature pq1vgaSignatures[] = { + { 341, "put gun in locker bug", 1, PATCH_MAGICDWORD(0x38, 0x5f, 0x01, 0x78), -27, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug }, + SCI_SIGNATUREENTRY_TERMINATOR +}; + // =========================================================================== // script 215 of qfg1vga pointBox::doit actually processes button-presses // during fighting with monsters. It strangely also calls kGetEvent. Because @@ -1496,6 +1558,9 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin case GID_MOTHERGOOSE256: signatureTable = mothergoose256Signatures; break; + case GID_PQ1: + signatureTable = pq1vgaSignatures; + break; case GID_QFG1VGA: signatureTable = qfg1vgaSignatures; break; -- cgit v1.2.3