From d603fe32e4b94f6b5c9382eaf6725664b9d68a95 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 11 Jan 2015 21:14:36 +0000 Subject: SCI: fix definition of GK1 police-sleep patch --- engines/sci/engine/script_patches.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 03cd1d06e9..c2a0b8b95d 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -562,12 +562,12 @@ static const uint16 gk1SignatureDay6PoliceSleep[] = { 0x34, SIG_UINT16(0x00dc), // ldi 220 0x65, SIG_ADDTOOFFSET(+1), // aTop cycles (1a for PC, 1c for Mac) 0x32, // jmp [end] - 0 + SIG_END }; static const uint16 gk1PatchDay6PoliceSleep[] = { PATCH_ADDTOOFFSET(+5), - 0x34, SIG_UINT16(0x002a), // ldi 42 + 0x34, PATCH_UINT16(0x002a), // ldi 42 0x65, PATCH_GETORIGINALBYTEADJUST(+9, +2), // aTop seconds (1c for PC, 1e for Mac) PATCH_END }; -- cgit v1.2.3 From fdc09c2cb7ff3041dbd11c146d3d669cc7aa4777 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 17 Feb 2015 19:53:43 +0100 Subject: SCI: Add alternative version of QfG3 "Woo" dialog patch The GOG version of QfG3 is shipped with a patch to script 440 that broke our existing internal script patch for this script bug. See bug #6806. --- engines/sci/engine/script_patches.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index c2a0b8b95d..45e0155950 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2282,10 +2282,40 @@ static const uint16 qfg3PatchWooDialog[] = { PATCH_END }; +// Alternative version, with uint16 offsets, for GOG release of QfG3. +static const uint16 qfg3SignatureWooDialogAlt[] = { + SIG_MAGICDWORD, + 0x67, 0x12, // pTos 12 (query) + 0x35, 0xb6, // ldi b6 + 0x1a, // eq? + 0x2e, SIG_UINT16(0x0005), // bt 05 + 0x67, 0x12, // pTos 12 (query) + 0x35, 0x9b, // ldi 9b + 0x1a, // eq? + 0x30, SIG_UINT16(0x000c), // bnt 0c + 0x38, SIG_SELECTOR16(solvePuzzle), // pushi 0297 + 0x7a, // push2 + 0x38, SIG_UINT16(0x010c), // pushi 010c + 0x7a, // push2 + 0x81, 0x00, // lag 00 + 0x4a, 0x08, // send 08 + 0x67, 0x12, // pTos 12 (query) + 0x35, 0xb5, // ldi b5 + SIG_END +}; + +static const uint16 qfg3PatchWooDialogAlt[] = { + PATCH_ADDTOOFFSET(+0x2C), + 0x33, 0x12, // jmp to 0x708, the call to hero::solvePuzzle for 0xFFFC + PATCH_END +}; + + // script, description, signature patch static const SciScriptPatcherEntry qfg3Signatures[] = { { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From 84631468561c3df20cfd073d20c35344be4c6f3f Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Fri, 20 Mar 2015 15:30:58 +0100 Subject: SCI: SQ1VGA: added script patch for bug #6816 fixes SQ1VGA Ulence Flats force field generator script glitch --- engines/sci/engine/script_patches.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 45e0155950..5c0e84fa01 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2501,6 +2501,29 @@ static const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = { PATCH_END }; +// In Ulence Flats, there is a space ship, that you will use at some point. +// Near that space ship are 2 force field generators. +// When you look at the top of those generators, the game will crash. +// This happens also in Sierra SCI. It's caused by a jump, that goes out of bounds. +// We currently do not know if this was caused by a compiler glitch or if it was a developer error. +// Anyway we patch this glitchy code, so that the game won't crash anymore. +// +// Applies to at least: English Floppy +// Responsible method: radar1::doVerb +// Fixes bug: #6816 +static const uint16 sq1vgaSignatureUlenceFlatsGeneratorGlitch[] = { + SIG_MAGICDWORD, 0x1a, // eq? + 0x30, SIG_UINT16(0xcdf4), // bnt absolute 0xf000 + SIG_END +}; + +static const uint16 sq1vgaPatchUlenceFlatsGeneratorGlitch[] = { + PATCH_ADDTOOFFSET(+1), + 0x32, PATCH_UINT16(0x0000), // jmp 0x0000 (waste bytes) + PATCH_END +}; + +// No documentation for this patch (TODO) static const uint16 sq1vgaSignatureEgoShowsCard[] = { SIG_MAGICDWORD, 0x38, SIG_SELECTOR16(timesShownID), // push "timesShownID" @@ -2625,6 +2648,7 @@ static const uint16 sq1vgaPatchSpiderDroidTiming[] = { // script, description, signature patch static const SciScriptPatcherEntry sq1vgaSignatures[] = { { true, 45, "Ulence Flats: timepod graphic glitch", 1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch }, + { true, 45, "Ulence Flats: force field generator glitch", 1, sq1vgaSignatureUlenceFlatsGeneratorGlitch, sq1vgaPatchUlenceFlatsGeneratorGlitch }, { true, 58, "Sarien armory droid zapping ego first time", 1, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard }, { true, 704, "spider droid timing issue", 1, sq1vgaSignatureSpiderDroidTiming, sq1vgaPatchSpiderDroidTiming }, SCI_SIGNATUREENTRY_TERMINATOR -- cgit v1.2.3 From 1f65284ada41b7156b5d68507fcdad6255694140 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Fri, 20 Mar 2015 23:58:47 +0100 Subject: SCI: QFG1VGA: added script patch fixes bug #6706 fixes healer's hut buy/steal issue effectively removes 60 tick delay from script --- engines/sci/engine/script_patches.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 5c0e84fa01..b6b9f72996 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2140,6 +2140,7 @@ static const uint16 qfg1vgaPatchCheetaurDescription[] = { // Local 5 of that room is a timer, that closes the door (object door11). // Setting it to 1 during happyFace::changeState(0) stops door11::doit from // calling goTo6::init, so the whole issue is stopped from happening. +// // Applies to at least: English floppy // Responsible method: happyFace::changeState, door11::doit // Fixes bug #6181 @@ -2166,8 +2167,40 @@ static const uint16 qfg1vgaPatchFunnyRoomFix[] = { PATCH_END }; +// The player is able to buy (and also steal) potions in the healer's hut +// Strangely Sierra delays the actual buy/get potion code for 60 ticks +// Why they did that is unknown. The code is triggered anyway only after +// the relevant dialog boxes are closed. +// +// This delay causes problems in case the user quickly enters the inventory. +// That's why we remove the code related to the delay completely. +// +// Applies to at least: English floppy +// Responsible method: cueItScript::changeState +// Fixes bug #6706 +static const uint16 qfg1vgaSignatureHealerHutNoDelay[] = { + 0x65, 0x14, // aTop 14 (state) + 0x36, // push + 0x3c, // dup + 0x35, 0x00, // ldi 00 + 0x1a, // eq? + 0x31, 0x07, // bnt 07 [-> next state] + SIG_MAGICDWORD, + 0x35, 0x3c, // ldi 3c (60 ticks) + 0x65, 0x20, // aTop ticks + 0x32, // jmp [-> end of method] + SIG_END +}; + +static const uint16 qfg1vgaPatchHealerHutNoDelay[] = { + PATCH_ADDTOOFFSET(+9), + 0x35, 0x01, // ldi 01 (1 tick only, so that execution will resume as soon as dialog box is closed) + PATCH_END +}; + // script, description, signature patch static const SciScriptPatcherEntry qfg1vgaSignatures[] = { + { true, 55, "healer's hut, no delay for buy/steal", 1, qfg1vgaSignatureHealerHutNoDelay, qfg1vgaPatchHealerHutNoDelay }, { true, 215, "fight event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, { true, 216, "weapon master event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, { true, 814, "window text temp space", 1, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace }, -- cgit v1.2.3 From 4550e8c5ef0429e1c917d455049419871acfabec Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 21 Mar 2015 00:05:22 +0100 Subject: SCI: fix script patch description --- engines/sci/engine/script_patches.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index b6b9f72996..711078d29c 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2173,7 +2173,8 @@ static const uint16 qfg1vgaPatchFunnyRoomFix[] = { // the relevant dialog boxes are closed. // // This delay causes problems in case the user quickly enters the inventory. -// That's why we remove the code related to the delay completely. +// That's why we change the amount of ticks to 1, so that the remaining states +// are executed right after the dialog boxes are closed. // // Applies to at least: English floppy // Responsible method: cueItScript::changeState -- cgit v1.2.3 From 537f33d9cf60fffdd473ae3cd32e2abffc9cb24f Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Mon, 13 Apr 2015 18:08:20 +0200 Subject: SCI: script patch for qfg3 hero export bug #6807 --- engines/sci/engine/script_patches.cpp | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 711078d29c..6d5b49f441 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2344,12 +2344,76 @@ static const uint16 qfg3PatchWooDialogAlt[] = { PATCH_END }; +// When exporting characters at the end of Quest for Glory 3, the underlying +// code has issues with values, that are above 9999. +// For further study: https://github.com/Blazingstix/QFGImporter/blob/master/QFGImporter/QFGImporter/QFG3.txt +// +// If a value is above 9999, parts or even the whole character file will get corrupted. +// +// We are fixing the code because of that. We are patching code, that is calculating the checksum +// and add extra code to lower such values to 9999. +// +// Applies to at least: English, French, German, Italian, Spanish floppy +// Responsible method: saveHero::changeState +// Fixes bug #6807 +static const uint16 qfg3SignatureExportChar[] = { + 0x35, SIG_ADDTOOFFSET(+1), // ldi 00 / ldi 01 (2 loops, we patch both) + 0xa5, 0x00, // sat temp[0] [contains index to data] + 0x8d, 0x00, // lst temp[0] + SIG_MAGICDWORD, + 0x35, 0x2c, // ldi 2c + 0x22, // lt? [index above or equal 2Ch (44d)? + 0x31, 0x23, // bnt [exit loop] + // from this point it's actually useless code, maybe a sci compiler bug + 0x8d, 0x00, // lst temp[0] + 0x35, 0x01, // ldi 01 + 0x02, // add + 0x9b, 0x00, // lsli local[0] ---------- load local[0 + ACC] onto stack + 0x8d, 0x00, // lst temp[0] + 0x35, 0x01, // ldi 01 + 0x02, // add + 0xb3, 0x00, // sali local[0] ---------- save stack to local[0 + ACC] + // end of useless code + 0x8b, SIG_ADDTOOFFSET(+1), // lsl local[36h/37h] ---- load local[36h/37h] onto stack + 0x8d, 0x00, // lst temp[0] + 0x35, 0x01, // ldi 01 + 0x02, // add + 0x93, 0x00, // lali local[0] ---------- load local[0 + ACC] into ACC + 0x02, // add -------------------- add ACC + stack and put into ACC + 0xa3, SIG_ADDTOOFFSET(+1), // sal local[36h/37h] ---- save ACC to local[36h/37h] + 0x8d, 0x00, // lst temp[0] ------------ temp[0] to stack + 0x35, 0x02, // ldi 02 + 0x02, // add -------------------- add 2 to stack + 0xa5, 0x00, // sat temp[0] ------------ save ACC to temp[0] + 0x33, 0xd6, // jmp [loop] + SIG_END +}; + +static const uint16 qfg3PatchExportChar[] = { + PATCH_ADDTOOFFSET(+11), + 0x85, 0x00, // lat temp[0] + 0x9b, 0x01, // lsli local[0] + 1 ------ load local[ ACC + 1] onto stack + 0x3c, // dup + 0x34, PATCH_UINT16(0x2710), // ldi 2710h (10000d) + 0x2c, // ult? ------------------- is value smaller than 10000? + 0x2f, 0x0a, // bt [jump over] + 0x3a, // toss + 0x38, PATCH_UINT16(0x270f), // pushi 270fh (9999d) + 0x3c, // dup + 0x85, 0x00, // lat temp[0] + 0xba, PATCH_UINT16(0x0001), // ssli local[0] + 1 ------ save stack to local[ ACC + 1] (UINT16 to waste 1 byte) + // jump offset + 0x83, PATCH_GETORIGINALBYTE(+26), // lal local[37h/36h] ---- load local[37h/36h] into ACC + 0x02, // add -------------------- add local[37h/36h] + data value + PATCH_END +}; // script, description, signature patch static const SciScriptPatcherEntry qfg3Signatures[] = { { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, + { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From cb8e40c116ba23293cbf5f30b45da7c24892753c Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Thu, 16 Apr 2015 01:26:23 +0200 Subject: SCI: QFG3 fix priority of chief in hut bug #5173 this is a script issue and also happens in Sierra's SCI. Gets solved by script patch. --- engines/sci/engine/script_patches.cpp | 36 +++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 6d5b49f441..48b1292d1b 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2408,12 +2408,40 @@ static const uint16 qfg3PatchExportChar[] = { PATCH_END }; +// The chief in his hut (room 640) is not drawn using the correct priority, +// which results in a graphical glitch. This is a game bug and also happens +// in Sierra's SCI. We adjust priority accordingly to fix it. +// +// Applies to at least: English, French, German, Italian, Spanish floppy +// Responsible method: heap in script 640 +// Fixes bug #5173 +static const uint16 qfg3SignatureChiefPriority[] = { + SIG_MAGICDWORD, + SIG_UINT16(0x0002), // yStep 0x0002 + SIG_UINT16(0x0281), // view 0x0281 + SIG_UINT16(0x0000), // loop 0x0000 + SIG_UINT16(0x0000), // cel 0x0000 + SIG_UINT16(0x0000), // priority 0x0000 + SIG_UINT16(0x0000), // underbits 0x0000 + SIG_UINT16(0x1000), // signal 0x1000 + SIG_END +}; + +static const uint16 qfg3PatchChiefPriority[] = { + PATCH_ADDTOOFFSET(+8), + PATCH_UINT16(0x000A), // new priority 0x000A (10d) + PATCH_ADDTOOFFSET(+2), + PATCH_UINT16(0x1010), // signal 0x1010 (set fixed priority flag) + PATCH_END +}; + // script, description, signature patch static const SciScriptPatcherEntry qfg3Signatures[] = { - { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, - { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, - { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, - { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar }, + { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, + { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar }, + { true, 640, "chief in hut priority fix", 1, qfg3SignatureChiefPriority, qfg3PatchChiefPriority }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From 882b1c218fedf5ea45d81524f405df1178080e7a Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Fri, 17 Apr 2015 23:40:12 +0200 Subject: SCI: patch qfg2 import bug for 1.102 and below this patches the known character type import bug (which made all imported characters a fighter) --- engines/sci/engine/script_patches.cpp | 52 +++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 48b1292d1b..44ceb15f63 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2245,9 +2245,57 @@ static const uint16 qfg2PatchImportDialog[] = { PATCH_END }; -// script, description, signature patch +// Quest For Glory 2 character import doesn't properly set the character type +// in versions 1.102 and below, which makes all importerted characters a fighter. +// +// Sierra released an official patch. However the fix is really easy to +// implement on our side, so we also patch the flaw in here in case we find it. +// +// The version released on GOG is 1.102 without this patch applied, so us +// patching it is quite useful. +// +// Applies to at least: English Floppy +// Responsible method: importHero::changeState +// Fixes bug: inside versions 1.102 and below +static const uint16 qfg2SignatureImportCharType[] = { + 0x35, 0x04, // ldi 04 + 0x90, SIG_UINT16(0x023b), // lagi global[23Bh] + 0x02, // add + 0x36, // push + 0x35, 0x04, // ldi 04 + 0x08, // div + 0x36, // push + 0x35, 0x0d, // ldi 0D + 0xb0, SIG_UINT16(0x023b), // sagi global[023Bh] + 0x8b, 0x1f, // lsl local[1Fh] + 0x35, 0x05, // ldi 05 + SIG_MAGICDWORD, + 0xb0, SIG_UINT16(0x0150), // sagi global[0150h] + 0x8b, 0x02, // lsl local[02h] + SIG_END +}; + +static const uint16 qfg2PatchImportCharType[] = { + 0x80, PATCH_UINT16(0x023f), // lag global[23Fh] <-- patched to save 2 bytes + 0x02, // add + 0x36, // push + 0x35, 0x04, // ldi 04 + 0x08, // div + 0x36, // push + 0xa8, SIG_UINT16(0x0248), // ssg global[0248h] <-- patched to save 2 bytes + 0x8b, 0x1f, // lsl local[1Fh] + 0xa8, SIG_UINT16(0x0155), // ssg global[0155h] <-- patched to save 2 bytes + // new code, directly from the official sierra patch file + 0x83, 0x01, // lal local[01h] + 0xa1, 0xbb, // sag global[BBh] + 0xa1, 0x73, // sag global[73h] + PATCH_END +}; + +// script, description, signature patch static const SciScriptPatcherEntry qfg2Signatures[] = { - { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog }, + { true, 805, "import character type fix", 1, qfg2SignatureImportCharType, qfg2PatchImportCharType }, + { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From 8e3f537019647874e12c9c4a1a90a2e004479102 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 18 Apr 2015 09:28:18 +0200 Subject: SCI: QfG3 fix importing QfG1 character files character type was always imported as fighter was never fixed by Sierra --- engines/sci/engine/script_patches.cpp | 36 ++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 44ceb15f63..b704a1c4b3 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2456,6 +2456,31 @@ static const uint16 qfg3PatchExportChar[] = { PATCH_END }; +// Quest for Glory 3 doesn't properly import the character type of Quest for Glory 1 character files. +// This issue was never addressed. It's caused by Sierra reading data directly from the local +// area, which is only set by Quest For Glory 2 import data, instead of reading the properly set global variable. +// +// We fix it, by also directly setting the local variable. +// +// Applies to at least: English, French, German, Italian, Spanish floppy +// Responsible method: importHero::changeState(4) +static const uint16 qfg3SignatureImportQfG1Char[] = { + SIG_MAGICDWORD, + 0x82, SIG_UINT16(0x0238), // lal local[0x0238] + 0xa0, SIG_UINT16(0x016a), // sag global[0x016a] + 0xa1, 0x7d, // sag global[0x7d] + 0x35, 0x01, // ldi 01 + 0x99, 0xfb, // lsgi global[0xfb] + SIG_END +}; + +static const uint16 qfg3PatchImportQfG1Char[] = { + PATCH_ADDTOOFFSET(+8), + 0xa3, 0x01, // sal 01 -> also set local[01] + 0x89, 0xfc, // lsg global[0xFD] -> save 2 bytes + PATCH_END +}; + // The chief in his hut (room 640) is not drawn using the correct priority, // which results in a graphical glitch. This is a game bug and also happens // in Sierra's SCI. We adjust priority accordingly to fix it. @@ -2483,12 +2508,13 @@ static const uint16 qfg3PatchChiefPriority[] = { PATCH_END }; -// script, description, signature patch +// script, description, signature patch static const SciScriptPatcherEntry qfg3Signatures[] = { - { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, - { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, - { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, - { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar }, + { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt }, + { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar }, + { true, 54, "import character from QfG1 bug", 1, qfg3SignatureImportQfG1Char, qfg3PatchImportQfG1Char }, { true, 640, "chief in hut priority fix", 1, qfg3SignatureChiefPriority, qfg3PatchChiefPriority }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From 38444d6024870d31656c911b2af1512a1cd6281a Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 18 Apr 2015 22:18:57 +0200 Subject: SCI: add signatures for workaround local-calls instead of using hardcoded offsets, we can now use regular script patcher signatures. only 1 qfg3 workaround has been migrated, the others will follow. --- engines/sci/engine/script_patches.cpp | 190 ++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 92 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index b704a1c4b3..e88aa98f42 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2924,6 +2924,7 @@ ScriptPatcher::ScriptPatcher() { _selectorIdTable[selectorNr] = -1; _runtimeTable = NULL; + _isMacSci11 = false; } ScriptPatcher::~ScriptPatcher() { @@ -2932,7 +2933,7 @@ ScriptPatcher::~ScriptPatcher() { } // will actually patch previously found signature area -void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) { +void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) { const uint16 *patchData = patchEntry->patchData; byte orgData[PATCH_VALUELIMIT]; int32 offset = signatureOffset; @@ -2996,7 +2997,7 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc default: byte1 = 0; byte2 = 0; } - if (!isMacSci11) { + if (!_isMacSci11) { scriptData[offset++] = byte1; scriptData[offset++] = byte2; } else { @@ -3023,8 +3024,94 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc } } +bool ScriptPatcher::verifySignature(uint32 byteOffset, const uint16 *signatureData, const char *signatureDescription, const byte *scriptData, const uint32 scriptSize) { + uint16 sigSelector = 0; + + uint16 sigWord = *signatureData; + while (sigWord != SIG_END) { + uint16 sigCommand = sigWord & SIG_COMMANDMASK; + uint16 sigValue = sigWord & SIG_VALUEMASK; + switch (sigCommand) { + case SIG_CODE_ADDTOOFFSET: { + // add value to offset + byteOffset += sigValue; + break; + } + case SIG_CODE_UINT16: + case SIG_CODE_SELECTOR16: { + if ((byteOffset + 1) < scriptSize) { + byte byte1; + byte byte2; + + switch (sigCommand) { + case SIG_CODE_UINT16: { + byte1 = sigValue & SIG_BYTEMASK; + signatureData++; sigWord = *signatureData; + if (sigWord & SIG_COMMANDMASK) + error("Script-Patcher: signature inconsistent\nFaulty signature: '%s'", signatureDescription); + byte2 = sigWord & SIG_BYTEMASK; + break; + } + case SIG_CODE_SELECTOR16: { + sigSelector = _selectorIdTable[sigValue]; + byte1 = sigSelector & 0xFF; + byte2 = sigSelector >> 8; + break; + } + default: + byte1 = 0; byte2 = 0; + } + if (!_isMacSci11) { + if ((scriptData[byteOffset] != byte1) || (scriptData[byteOffset + 1] != byte2)) + sigWord = SIG_MISMATCH; + } else { + // SCI1.1+ on macintosh had uint16s in script in BE-order + if ((scriptData[byteOffset] != byte2) || (scriptData[byteOffset + 1] != byte1)) + sigWord = SIG_MISMATCH; + } + byteOffset += 2; + } else { + sigWord = SIG_MISMATCH; + } + break; + } + case SIG_CODE_SELECTOR8: { + if (byteOffset < scriptSize) { + sigSelector = _selectorIdTable[sigValue]; + if (sigSelector & 0xFF00) + error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty signature: '%s'", signatureDescription); + if (scriptData[byteOffset] != (sigSelector & 0xFF)) + sigWord = SIG_MISMATCH; + byteOffset++; + } else { + sigWord = SIG_MISMATCH; // out of bounds + } + break; + } + case SIG_CODE_BYTE: + if (byteOffset < scriptSize) { + if (scriptData[byteOffset] != sigWord) + sigWord = SIG_MISMATCH; + byteOffset++; + } else { + sigWord = SIG_MISMATCH; // out of bounds + } + } + + if (sigWord == SIG_MISMATCH) + break; + + signatureData++; + sigWord = *signatureData; + } + + if (sigWord == SIG_END) // signature fully matched? + return true; + return false; +} + // will return -1 if no match was found, otherwise an offset to the start of the signature match -int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) { +int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize) { if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay return -1; @@ -3036,89 +3123,8 @@ int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciS if (magicDWord == READ_UINT32(scriptData + DWordOffset)) { // magic DWORD found, check if actual signature matches uint32 offset = DWordOffset + runtimeEntry->magicOffset; - uint32 byteOffset = offset; - const uint16 *signatureData = patchEntry->signatureData; - uint16 sigSelector = 0; - - uint16 sigWord = *signatureData; - while (sigWord != SIG_END) { - uint16 sigCommand = sigWord & SIG_COMMANDMASK; - uint16 sigValue = sigWord & SIG_VALUEMASK; - switch (sigCommand) { - case SIG_CODE_ADDTOOFFSET: { - // add value to offset - byteOffset += sigValue; - break; - } - case SIG_CODE_UINT16: - case SIG_CODE_SELECTOR16: { - if ((byteOffset + 1) < scriptSize) { - byte byte1; - byte byte2; - - switch (sigCommand) { - case SIG_CODE_UINT16: { - byte1 = sigValue & SIG_BYTEMASK; - signatureData++; sigWord = *signatureData; - if (sigWord & SIG_COMMANDMASK) - error("Script-Patcher: signature inconsistent\nFaulty patch: '%s'", patchEntry->description); - byte2 = sigWord & SIG_BYTEMASK; - break; - } - case SIG_CODE_SELECTOR16: { - sigSelector = _selectorIdTable[sigValue]; - byte1 = sigSelector & 0xFF; - byte2 = sigSelector >> 8; - break; - } - default: - byte1 = 0; byte2 = 0; - } - if (!isMacSci11) { - if ((scriptData[byteOffset] != byte1) || (scriptData[byteOffset + 1] != byte2)) - sigWord = SIG_MISMATCH; - } else { - // SCI1.1+ on macintosh had uint16s in script in BE-order - if ((scriptData[byteOffset] != byte2) || (scriptData[byteOffset + 1] != byte1)) - sigWord = SIG_MISMATCH; - } - byteOffset += 2; - } else { - sigWord = SIG_MISMATCH; - } - break; - } - case SIG_CODE_SELECTOR8: { - if (byteOffset < scriptSize) { - sigSelector = _selectorIdTable[sigValue]; - if (sigSelector & 0xFF00) - error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", patchEntry->description); - if (scriptData[byteOffset] != (sigSelector & 0xFF)) - sigWord = SIG_MISMATCH; - byteOffset++; - } else { - sigWord = SIG_MISMATCH; // out of bounds - } - break; - } - case SIG_CODE_BYTE: - if (byteOffset < scriptSize) { - if (scriptData[byteOffset] != sigWord) - sigWord = SIG_MISMATCH; - byteOffset++; - } else { - sigWord = SIG_MISMATCH; // out of bounds - } - } - - if (sigWord == SIG_MISMATCH) - break; - - signatureData++; - sigWord = *signatureData; - } - if (sigWord == SIG_END) // signature fully matched? + if (verifySignature(offset, patchEntry->signatureData, patchEntry->description, scriptData, scriptSize)) return offset; } DWordOffset++; @@ -3129,7 +3135,7 @@ int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciS // This method calculates the magic DWORD for each entry in the signature table // and it also initializes the selector table for selectors used in the signatures/patches of the current game -void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11) { +void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable) { const SciScriptPatcherEntry *curEntry = patchTable; SciScriptPatcherRuntimeEntry *curRuntimeEntry; Selector curSelector = -1; @@ -3197,7 +3203,7 @@ void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool curData++; curWord = *curData; if (curWord & SIG_COMMANDMASK) error("Script-Patcher: signature entry inconsistent\nFaulty patch: '%s'", curEntry->description); - if (!isMacSci11) { + if (!_isMacSci11) { byte1 = curValue; byte2 = curWord & SIG_BYTEMASK; } else { @@ -3212,7 +3218,7 @@ void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]); _selectorIdTable[curValue] = curSelector; } - if (!isMacSci11) { + if (!_isMacSci11) { byte1 = curSelector & 0x00FF; byte2 = curSelector >> 8; } else { @@ -3374,7 +3380,7 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3 } if (signatureTable) { - bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1); + _isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1); if (!_runtimeTable) { // Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary) @@ -3382,7 +3388,7 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3 return; // signature table needs to get initialized (Magic DWORD set, selector table set) - initSignature(signatureTable, isMacSci11); + initSignature(signatureTable); // Do additional game-specific initialization switch (gameId) { @@ -3417,11 +3423,11 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3 int32 foundOffset = 0; int16 applyCount = curEntry->applyCount; do { - foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize, isMacSci11); + foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize); if (foundOffset != -1) { // found, so apply the patch debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", curEntry->description, scriptNr, foundOffset); - applyPatch(curEntry, scriptData, scriptSize, foundOffset, isMacSci11); + applyPatch(curEntry, scriptData, scriptSize, foundOffset); } applyCount--; } while ((foundOffset != -1) && (applyCount)); -- cgit v1.2.3 From 817217c225475e5908bd3e7f3cfe1076df10ac8d Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Fri, 24 Apr 2015 18:25:58 +0200 Subject: SCI: qfg1vga script patch 4 stag dagger bug #6135 fixes animation issue when throwing a dagger at white stag in room 77 --- engines/sci/engine/script_patches.cpp | 82 ++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index e88aa98f42..03bf4387b7 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -94,6 +94,7 @@ static const char *const selectorNameTable[] = { "deskSarg", // Gabriel Knight "localize", // Freddy Pharkas "put", // Police Quest 1 VGA + "say", // Quest For Glory 1 VGA "solvePuzzle", // Quest For Glory 3 "timesShownID", // Space Quest 1 VGA "startText", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support @@ -119,6 +120,7 @@ enum ScriptPatcherSelectors { SELECTOR_deskSarg, SELECTOR_localize, SELECTOR_put, + SELECTOR_say, SELECTOR_solvePuzzle, SELECTOR_timesShownID, SELECTOR_startText, @@ -2116,7 +2118,7 @@ static const uint16 qfg1vgaSignatureCheetaurDescription[] = { 0x34, SIG_UINT16(0x01b8), // ldi 01b8 0x1a, // eq? 0x31, 0x16, // bnt 16 - 0x38, SIG_UINT16(0x0127), // pushi 0127 + 0x38, SIG_SELECTOR16(say), // pushi 0127h (selector "say") 0x39, 0x06, // pushi 06 0x39, 0x03, // pushi 03 0x78, // push1 @@ -2199,17 +2201,87 @@ static const uint16 qfg1vgaPatchHealerHutNoDelay[] = { PATCH_END }; +// When following the white stag, you can actually enter the 2nd room from the mushroom/fairy location, +// which results in ego entering from the top. When you then throw a dagger at the stag, one animation +// frame will stay on screen, because of a script bug. +// +// Applies to at least: English floppy, Mac floppy +// Responsible method: stagHurt::changeState +// Fixes bug #6135 +static const uint16 qfg1vgaSignatureWhiteStagDagger[] = { + 0x87, 0x01, // lap param[1] + 0x65, 0x14, // aTop state + 0x36, // push + 0x3c, // dup + 0x35, 0x00, // ldi 0 + 0x1a, // eq? + 0x31, 0x16, // bnt [next parameter check] + 0x76, // push0 + 0x45, 0x02, 0x00, // callb export 2 from script 0, 0 + SIG_MAGICDWORD, + 0x38, SIG_SELECTOR16(say), // pushi 0127h (selector "say") + 0x39, 0x05, // pushi 05 + 0x39, 0x03, // pushi 03 + 0x39, 0x51, // pushi 51h + 0x76, // push0 + 0x76, // push0 + 0x7c, // pushSelf + 0x81, 0x5b, // lag global[5Bh] -> qg1Messager + 0x4a, 0x0e, // send 0Eh -> qg1Messager::say(3, 51h, 0, 0, stagHurt) + 0x33, 0x12, // jmp -> [ret] + 0x3c, // dup + 0x35, 0x01, // ldi 1 + 0x1a, // eq? + 0x31, 0x0c, // bnt [ret] + 0x38, // pushi... + SIG_ADDTOOFFSET(+11), + 0x3a, // toss + 0x48, // ret + SIG_END +}; + +static const uint16 qfg1vgaPatchWhiteStagDagger[] = { + PATCH_ADDTOOFFSET(+4), + 0x2f, 0x05, // bt [next check] (state != 0) + // state = 0 code + 0x35, 0x01, // ldi 1 + 0x65, 0x1a, // aTop cycles + 0x48, // ret + 0x36, // push + 0x35, 0x01, // ldi 1 + 0x1a, // eq? + 0x31, 0x16, // bnt [state = 2 code] + // state = 1 code + 0x76, // push0 + 0x45, 0x02, 0x00, // callb export 2 from script 0, 0 + 0x38, PATCH_SELECTOR16(say), // pushi 0127h (selector "say") + 0x39, 0x05, // pushi 05 + 0x39, 0x03, // pushi 03 + 0x39, 0x51, // pushi 51h + 0x76, // push0 + 0x76, // push0 + 0x7c, // pushSelf + 0x81, 0x5b, // lag global[5Bh] -> qg1Messager + 0x4a, 0x0e, // send 0Eh -> qg1Messager::say(3, 51h, 0, 0, stagHurt) + 0x48, // ret + // state = 2 code + PATCH_ADDTOOFFSET(+13), + 0x48, // ret (remove toss) + PATCH_END +}; + // script, description, signature patch static const SciScriptPatcherEntry qfg1vgaSignatures[] = { + { true, 41, "moving to castle gate", 1, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate }, { true, 55, "healer's hut, no delay for buy/steal", 1, qfg1vgaSignatureHealerHutNoDelay, qfg1vgaPatchHealerHutNoDelay }, + { true, 77, "white stag dagger throw animation glitch", 1, qfg1vgaSignatureWhiteStagDagger, qfg1vgaPatchWhiteStagDagger }, + { true, 96, "funny room script bug fixed", 1, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix }, + { true, 210, "cheetaur description fixed", 1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription }, { true, 215, "fight event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, { true, 216, "weapon master event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, + { true, 331, "moving to crusher", 1, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher }, { true, 814, "window text temp space", 1, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace }, { true, 814, "dialog header offset", 3, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader }, - { true, 331, "moving to crusher", 1, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher }, - { true, 41, "moving to castle gate", 1, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate }, - { true, 210, "cheetaur description fixed", 1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription }, - { true, 96, "funny room script bug fixed", 1, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From f4ce7851f849f37851831c3888337feb532425ca Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 25 Apr 2015 20:06:59 +0200 Subject: SCI: script patch for sq4cd, walk in bug #5468 walk right up in the first room, only for SQ4 CD --- engines/sci/engine/script_patches.cpp | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 03bf4387b7..b4844e3e7e 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2647,6 +2647,47 @@ static const uint16 sq4FloppyPatchThrowStuffAtSequelPoliceBug[] = { PATCH_END }; +// Right at the start of Space Quest 4 CD, when walking up in the first room, ego will +// immediately walk down just after entering the upper room. +// +// This is caused by the scripts setting ego's vertical coordinate to 189 (BDh), which is the +// trigger in rooms to walk to the room below it. Sometimes this isn't triggered, because +// the scripts also initiate a motion to vertical coordinate 188 (BCh). When you lower the game's speed, +// this bug normally always triggers. And it triggers of course also in the original interpreter. +// +// It doesn't happen in PC floppy, because nsRect is not the same as in CD. +// +// We fix it by setting ego's vertical coordinate to 188 and we also initiate a motion to 187. +// +// Applies to at least: English PC CD +// Responsible method: rm045::doit +// Fixes bug: #5468 +static const uint16 sq4CdSignatureWalkInFromBelowRoom45[] = { + 0x76, // push0 + SIG_MAGICDWORD, + 0x78, // push1 + 0x38, SIG_UINT16(0x00bd), // pushi 00BDh + 0x38, SIG_ADDTOOFFSET(+2), // pushi [setMotion selector] + 0x39, 0x03, // pushi 3 + 0x51, SIG_ADDTOOFFSET(+1), // class [MoveTo] + 0x36, // push + 0x78, // push1 + 0x76, // push0 + 0x81, 0x00, // lag global[0] + 0x4a, 0x04, // send 04 -> get ego::x + 0x36, // push + 0x38, SIG_UINT16(0x00bc), // pushi 00BCh + SIG_END +}; + +static const uint16 sq4CdPatchWalkInFromBelowRoom45[] = { + PATCH_ADDTOOFFSET(+2), + 0x38, PATCH_UINT16(0x00bc), // pushi 00BCh + PATCH_ADDTOOFFSET(+15), + 0x38, PATCH_UINT16(0x00bb), // pushi 00BBh + PATCH_END +}; + // The scripts in SQ4CD support simultaneous playing of speech and subtitles, // but this was not available as an option. The following two patches enable // this functionality in the game's GUI options dialog. @@ -2741,8 +2782,9 @@ static const uint16 sq4CdPatchTextOptions[] = { static const SciScriptPatcherEntry sq4Signatures[] = { { true, 298, "Floppy: endless flight", 1, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight }, { true, 700, "Floppy: throw stuff at sequel police bug", 1, sq4FloppySignatureThrowStuffAtSequelPoliceBug, sq4FloppyPatchThrowStuffAtSequelPoliceBug }, - { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions }, + { true, 45, "CD: walk in from below for room 45 fix", 1, sq4CdSignatureWalkInFromBelowRoom45, sq4CdPatchWalkInFromBelowRoom45 }, { true, 0, "CD: Babble icon speech and subtitles fix", 1, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon }, + { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions }, { true, 818, "CD: Speech and subtitles option button", 1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From 53f9dac75ef0c0c22c513068eaccf8c96457a438 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 25 Apr 2015 22:42:20 +0200 Subject: SCI: script patch qfg2 saurus freeze - bug #5156 getting back on saurus in the desert by typing command "ride" freezes the game. This patch fixes the issue. Attention: difficult bug to fix, may cause issues --- engines/sci/engine/script_patches.cpp | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index b4844e3e7e..173641f7ee 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -95,6 +95,7 @@ static const char *const selectorNameTable[] = { "localize", // Freddy Pharkas "put", // Police Quest 1 VGA "say", // Quest For Glory 1 VGA + "contains", // Quest For Glory 2 "solvePuzzle", // Quest For Glory 3 "timesShownID", // Space Quest 1 VGA "startText", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support @@ -121,6 +122,7 @@ enum ScriptPatcherSelectors { SELECTOR_localize, SELECTOR_put, SELECTOR_say, + SELECTOR_contains, SELECTOR_solvePuzzle, SELECTOR_timesShownID, SELECTOR_startText, @@ -2286,6 +2288,47 @@ static const SciScriptPatcherEntry qfg1vgaSignatures[] = { }; // =========================================================================== + +// This is a very complicated bug. +// When the player encounters an enemy in the desert while riding a saurus and later +// tries to get back on it by entering "ride", the game will not give control back +// to the player. +// +// This is caused by script mountSaurus getting triggered twice. +// Once by entering the command "ride" and then a second time by a proximity check. +// +// Both are calling mountSaurus::init() in script 20, this one disables controls +// then mountSaurus::changeState() from script 660 is triggered +// mountSaurus::changeState(5) finally calls mountSaurus::dispose(), which is also in script 20 +// which finally re-enables controls +// +// A fix is difficult to implement. The code in script 20 is generic and used by multiple objects +// That's why I have decided to change the responsible globals (66h and A1h) during mountSaurus::changeState(5) +// +// This fix could cause issues in case there is a cutscene, that contains ego getting on a saurus and +// requires controls not getting re-enabled after getting back up on the saurus. +// +// Applies to at least: English PC Floppy, English Amiga Floppy +// Responsible method: mountSaurus::changeState(), mountSaurus::init(), mountSaurus::dispose() +// Fixes bug: #5156 +static const uint16 qfg2SignatureSaurusFreeze[] = { + 0x3c, // dup + 0x35, 0x05, // ldi 5 + SIG_MAGICDWORD, + 0x1a, // eq? + 0x30, SIG_UINT16(0x004e), // bnt [ret] + 0x39, SIG_SELECTOR8(contains), // pushi [selector contains] + 0x78, // push1 + SIG_END +}; + +static const uint16 qfg2PatchSaurusFreeze[] = { + 0x35, 0x01, // ldi 1 + 0xa1, 0x66, // sag 66h + 0xa0, SIG_UINT16(0x00a1), // sag 00A1h + PATCH_END +}; + // Script 944 in QFG2 contains the FileSelector system class, used in the // character import screen. This gets incorrectly called constantly, whenever // the user clicks on a button in order to refresh the file list. This was @@ -2366,6 +2409,7 @@ static const uint16 qfg2PatchImportCharType[] = { // script, description, signature patch static const SciScriptPatcherEntry qfg2Signatures[] = { + { true, 660, "getting back on saurus freeze fix", 1, qfg2SignatureSaurusFreeze, qfg2PatchSaurusFreeze }, { true, 805, "import character type fix", 1, qfg2SignatureImportCharType, qfg2PatchImportCharType }, { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog }, SCI_SIGNATUREENTRY_TERMINATOR -- cgit v1.2.3 From cd2ead0a78d2f78cd0b4aecddf4e54520483855f Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 2 May 2015 21:41:19 +0200 Subject: SCI: lsl5 script patch to fix game breaking bug fixes green card phone number also calling limo at the same time bug for the English PC 1.000 release. --- engines/sci/engine/script_patches.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 173641f7ee..4011273ca3 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -1425,6 +1425,37 @@ static const SciScriptPatcherEntry larry2Signatures[] = { // =========================================================================== // Leisure Suit Larry 5 +// In Miami the player can call the green card telephone number and get +// green card including limo at the same time in the English 1.000 PC release. +// This results later in a broken game in case the player doesn't read +// the second telephone number for the actual limousine service, because +// in that case it's impossible for the player to get back to the airport. +// +// We disable the code, that is responsible to make the limo arrive. +// +// This bug was fixed in the European (dual language) versions of the game. +// +// Applies to at least: English PC floppy (1.000) +// Responsible method: sPhone::changeState(40) +static const uint16 larry5SignatureGreenCardLimoBug[] = { + 0x7a, // push2 + SIG_MAGICDWORD, + 0x39, 0x07, // pushi 07 + 0x39, 0x0c, // pushi 0Ch + 0x45, 0x0a, 0x04, // call export 10 of script 0 + 0x78, // push1 + 0x39, 0x26, // pushi 26h (limo arrived flag) + 0x45, 0x07, 0x02, // call export 7 of script 0 (sets flag) + SIG_END +}; + +static const uint16 larry5PatchGreenCardLimoBug[] = { + PATCH_ADDTOOFFSET(+8), + 0x34, PATCH_UINT16(0), // ldi 0000 (dummy) + 0x34, PATCH_UINT16(0), // ldi 0000 (dummy) + PATCH_END +}; + // In one of the conversations near the end (to be exact - room 380 and the text // about using champagne on Reverse Biaz - only used when you actually did that // in the game), the German text is too large, causing the textbox to get too large. @@ -1448,6 +1479,7 @@ static const uint16 larry5PatchGermanEndingPattiTalker[] = { // script, description, signature patch static const SciScriptPatcherEntry larry5Signatures[] = { + { true, 280, "English-only: fix green card limo bug", 1, larry5SignatureGreenCardLimoBug, larry5PatchGreenCardLimoBug }, { true, 380, "German-only: Enlarge Patti Textbox", 1, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker }, SCI_SIGNATUREENTRY_TERMINATOR }; -- cgit v1.2.3 From fdfb7775a49ec6b93cbaa720b88fee37e052a86c Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Thu, 14 May 2015 17:58:31 +0200 Subject: SCI: change qfg2 saurus ride script patch the original script patch messed up room changes --- engines/sci/engine/script_patches.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 4011273ca3..0eefe19854 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2335,29 +2335,37 @@ static const SciScriptPatcherEntry qfg1vgaSignatures[] = { // which finally re-enables controls // // A fix is difficult to implement. The code in script 20 is generic and used by multiple objects -// That's why I have decided to change the responsible globals (66h and A1h) during mountSaurus::changeState(5) // -// This fix could cause issues in case there is a cutscene, that contains ego getting on a saurus and -// requires controls not getting re-enabled after getting back up on the saurus. +// Originally I decided to change the responsible globals (66h and A1h) during mountSaurus::changeState(5). +// This worked as far as for controls, but mountSaurus::init changes a few selectors of ego as well, which +// won't get restored in that situation, which then messes up room changes and other things. +// +// I have now decided to change sheepScript::changeState(2) in script 665 instead. +// +// This fix could cause issues in case there is a cutscene, where ego is supposed to get onto the saurus using +// sheepScript. // // Applies to at least: English PC Floppy, English Amiga Floppy // Responsible method: mountSaurus::changeState(), mountSaurus::init(), mountSaurus::dispose() // Fixes bug: #5156 static const uint16 qfg2SignatureSaurusFreeze[] = { 0x3c, // dup - 0x35, 0x05, // ldi 5 + 0x35, 0x02, // ldi 5 SIG_MAGICDWORD, 0x1a, // eq? - 0x30, SIG_UINT16(0x004e), // bnt [ret] - 0x39, SIG_SELECTOR8(contains), // pushi [selector contains] - 0x78, // push1 + 0x30, SIG_UINT16(0x0043), // bnt [ret] + 0x76, // push0 + SIG_ADDTOOFFSET(+61), // skip to dispose code + 0x39, SIG_SELECTOR8(dispose), // pushi "dispose" + 0x76, // push0 + 0x54, 0x04, // self 04 SIG_END }; static const uint16 qfg2PatchSaurusFreeze[] = { - 0x35, 0x01, // ldi 1 - 0xa1, 0x66, // sag 66h - 0xa0, SIG_UINT16(0x00a1), // sag 00A1h + 0x81, 0x66, // lag 66h + 0x2e, SIG_UINT16(0x0040), // bt [to dispose code] + 0x35, 0x00, // ldi 0 (waste 2 bytes) PATCH_END }; @@ -2441,7 +2449,7 @@ static const uint16 qfg2PatchImportCharType[] = { // script, description, signature patch static const SciScriptPatcherEntry qfg2Signatures[] = { - { true, 660, "getting back on saurus freeze fix", 1, qfg2SignatureSaurusFreeze, qfg2PatchSaurusFreeze }, + { true, 665, "getting back on saurus freeze fix", 1, qfg2SignatureSaurusFreeze, qfg2PatchSaurusFreeze }, { true, 805, "import character type fix", 1, qfg2SignatureImportCharType, qfg2PatchImportCharType }, { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog }, SCI_SIGNATUREENTRY_TERMINATOR -- cgit v1.2.3 From a6ceee0d67dadb5300716e0f8b6c5ba7ac503a79 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sun, 17 May 2015 11:54:27 +0200 Subject: SCI: qfg1vga: fix script patch sneak into castle The original script patch only worked when speed slider was all the way up. --- engines/sci/engine/script_patches.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 0eefe19854..a954d65a90 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2123,21 +2123,30 @@ static const uint16 qfg1vgaPatchMoveToCrusher[] = { // Same pathfinding bug as above, where Ego is set to move to an impossible // spot when sneaking. In GuardsTrumpet::changeState, we change the final -// location where Ego is moved from 111, 111 to 114, 114. +// location where Ego is moved from 111, 111 to 116, 116. +// target coordinate is really problematic here. +// +// 114, 114 works when the speed slider is all the way up, but doesn't work +// when the speed slider is not. +// +// It seems that this bug was fixed by Sierra for the Macintosh version. +// +// Applies to at least: English PC floppy +// Responsible method: GuardsTrumpet::changeState(8) // Fixes bug: #6248 static const uint16 qfg1vgaSignatureMoveToCastleGate[] = { + 0x51, SIG_ADDTOOFFSET(+1), // class MoveTo SIG_MAGICDWORD, - 0x51, 0x1f, // class MoveTo 0x36, // push - 0x39, 0x6f, // pushi 6f (111 - x) - 0x3c, // dup (111 - y) + 0x39, 0x6f, // pushi 6f (111d) + 0x3c, // dup (111d) - coordinates 111, 111 0x7c, // pushSelf SIG_END }; static const uint16 qfg1vgaPatchMoveToCastleGate[] = { PATCH_ADDTOOFFSET(+3), - 0x39, 0x72, // pushi 72 (114 - x) + 0x39, 0x74, // pushi 74 (116d), changes coordinates to 116, 116 PATCH_END }; -- cgit v1.2.3 From f0ccd3f91a2a412f7e4a1cab067ef6d8dddf561b Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Mon, 18 May 2015 19:15:35 +0200 Subject: SCI: sq4cd scriptpatch clothes change points #6866 script patch, so that points are awarded, when changing back clothes. You have to clean out the bank account again, because that's the problematic script. Also happened in original interpreter. Only happened for Space Quest 4 CD worked in floppy --- engines/sci/engine/script_patches.cpp | 60 +++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) (limited to 'engines/sci/engine/script_patches.cpp') diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index a954d65a90..6915e12a0e 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2775,9 +2775,64 @@ static const uint16 sq4CdSignatureWalkInFromBelowRoom45[] = { static const uint16 sq4CdPatchWalkInFromBelowRoom45[] = { PATCH_ADDTOOFFSET(+2), - 0x38, PATCH_UINT16(0x00bc), // pushi 00BCh + 0x38, PATCH_UINT16(0x00bc), // pushi 00BCh PATCH_ADDTOOFFSET(+15), - 0x38, PATCH_UINT16(0x00bb), // pushi 00BBh + 0x38, PATCH_UINT16(0x00bb), // pushi 00BBh + PATCH_END +}; + +// It seems that Sierra forgot to set a script flag, when cleaning out the bank account +// in Space Quest 4 CD. This was probably caused by the whole bank account interaction +// getting a rewrite and polish in the CD version. +// +// Because of this bug, points for changing back clothes will not get awarded, which +// makes it impossible to get a perfect point score in the CD version of the game. +// The points are awarded by rm371::doit in script 371. +// +// We fix this. Bug also happened, when using the original interpreter. +// Bug does not happen for PC floppy. +// +// Attention: Some Let's Plays on youtube show that points are in fact awarded. Which is true. +// But those Let's Plays were actually created by playing a hacked Space Quest 4 version +// (which is part Floppy, part CD version - we consider it to be effectively pirated) +// and not the actual CD version of Space Quest 4. +// It's easy to identify - talkie + store called "Radio Shack" -> is hacked version. +// +// Applies to at least: English PC CD +// Responsible method: but2Script::changeState(2) +// Fixes bug: #6866 +static const uint16 sq4CdSignatureGetPointsForChangingBackClothes[] = { + 0x35, 0x02, // ldi 02 + SIG_MAGICDWORD, + 0x1a, // eq? + 0x30, SIG_UINT16(0x006a), // bnt [state 3] + 0x76, + SIG_ADDTOOFFSET(+46), // jump over "withdraw funds" code + 0x33, 0x33, // jmp [end of state 2, set cycles code] + SIG_ADDTOOFFSET(+51), // jump over "clean bank account" code + 0x35, 0x02, // ldi 02 + 0x65, 0x1a, // aTop cycles + 0x33, 0x0b, // jmp [toss/ret] + 0x3c, // dup + 0x35, 0x03, // ldi 03 + 0x1a, // eq? + 0x31, 0x05, // bnt [toss/ret] + SIG_END +}; + +static const uint16 sq4CdPatchGetPointsForChangingBackClothes[] = { + PATCH_ADDTOOFFSET(+3), + 0x30, PATCH_UINT16(0x0070), // bnt [state 3] + PATCH_ADDTOOFFSET(+47), // "withdraw funds" code + 0x33, 0x39, // jmp [end of state 2, set cycles code] + PATCH_ADDTOOFFSET(+51), + 0x78, // push1 + 0x39, 0x1d, // ldi 1Dh + 0x45, 0x07, 0x02, // call export 7 of script 0 (set flag) -> effectively sets global 73h, bit 2 + 0x35, 0x02, // ldi 02 + 0x65, 0x1c, // aTop cycles + 0x33, 0x05, // jmp [toss/ret] + // check for state 3 code removed to save 6 bytes PATCH_END }; @@ -2876,6 +2931,7 @@ static const SciScriptPatcherEntry sq4Signatures[] = { { true, 298, "Floppy: endless flight", 1, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight }, { true, 700, "Floppy: throw stuff at sequel police bug", 1, sq4FloppySignatureThrowStuffAtSequelPoliceBug, sq4FloppyPatchThrowStuffAtSequelPoliceBug }, { true, 45, "CD: walk in from below for room 45 fix", 1, sq4CdSignatureWalkInFromBelowRoom45, sq4CdPatchWalkInFromBelowRoom45 }, + { true, 396, "CD: get points for changing back clothes fix",1, sq4CdSignatureGetPointsForChangingBackClothes, sq4CdPatchGetPointsForChangingBackClothes }, { true, 0, "CD: Babble icon speech and subtitles fix", 1, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon }, { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions }, { true, 818, "CD: Speech and subtitles option button", 1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton }, -- cgit v1.2.3