[Scummvm-git-logs] scummvm master -> 6e743a97efe438b638b3f27e39b853a5b011ff61
sluicebox
noreply at scummvm.org
Tue May 24 21:07:12 UTC 2022
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c4a95fad5c SCI: Remove duplicate QFG3 uninit read workaround
b3a77a79a9 SCI: Add QFG3 workaround for casting open on wall
f45a5eff90 SCI: Fix QFG3 ring rope uninit read with script patch
6e743a97ef SCI: Fix QFG3 event bugs at the Laibon's hut
Commit: c4a95fad5c3a9158aad33854a53d38ff3a628d34
https://github.com/scummvm/scummvm/commit/c4a95fad5c3a9158aad33854a53d38ff3a628d34
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-05-24T16:57:45-04:00
Commit Message:
SCI: Remove duplicate QFG3 uninit read workaround
Changed paths:
engines/sci/engine/workarounds.cpp
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index e908973bb1e..1b1572b4d9f 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -538,8 +538,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #5169
{ GID_QFG3, 470, 470, -1, "rm470", "notify", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // closing the character screen in the Simbani village in the room with the bridge, bug #5165
{ GID_QFG3, 470, 470, -1, "<invalid name>", "notify", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // same as previous, with rm470::name used for temp storage by fan patches added by GOG
- { GID_QFG3, 490, 490, -1, "computersMove", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #5167
- { GID_QFG3, 490, 490, -1, "computersMove", "changeState", sig_uninitread_qfg3_2, 4, 4, { WORKAROUND_FAKE, 0 } }, // also when finishing awari game
+ { GID_QFG3, 490, 490, -1, "computersMove", "changeState", sig_uninitread_qfg3_2, 4, 4, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #5167
{ GID_QFG3, -1, 32, -1, "ProjObj", "doit", nullptr, 1, 1, { WORKAROUND_FAKE, 0 } }, // near the end, when throwing the spear of death or sword, bugs #5282, #11477
{ GID_QFG3, -1, 937, -1, "IconBar", "dispatchEvent", nullptr, 58, 58, { WORKAROUND_FAKE, 64 } }, // pressing the Enter key on the main menu screen, bugs #13045, #13161 (affects multiple room numbers). value must have 0x40 set for quit global to be evaluated
{ GID_QFG4, -1, 15, -1, "charInitScreen", "dispatchEvent", nullptr, 5, 5, { WORKAROUND_FAKE, 0 } }, // floppy version, when viewing the character screen
Commit: b3a77a79a9e66aeb2e3631ac830f02b5947962cf
https://github.com/scummvm/scummvm/commit/b3a77a79a9e66aeb2e3631ac830f02b5947962cf
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-05-24T16:57:45-04:00
Commit Message:
SCI: Add QFG3 workaround for casting open on wall
Changed paths:
engines/sci/engine/workarounds.cpp
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 1b1572b4d9f..719d770fe5b 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -536,6 +536,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_QFG3, 140, 140, 0, "rm140", "init", sig_uninitread_qfg3_1, 0, 0, { WORKAROUND_FAKE, 0 } }, // when importing a character and selecting the previous profession - bug #5163
{ GID_QFG3, 330, 330, -1, "Teller", "doChild", nullptr, -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #5033, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #5148, temp 1)
{ GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #5169
+ { GID_QFG3, 450, 450, -1, "castOpenOnCrack", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 1 } }, // in laibon's hut, wait for night and cast open on crack in wall
{ GID_QFG3, 470, 470, -1, "rm470", "notify", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // closing the character screen in the Simbani village in the room with the bridge, bug #5165
{ GID_QFG3, 470, 470, -1, "<invalid name>", "notify", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // same as previous, with rm470::name used for temp storage by fan patches added by GOG
{ GID_QFG3, 490, 490, -1, "computersMove", "changeState", sig_uninitread_qfg3_2, 4, 4, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #5167
Commit: f45a5eff90af49a4295583d0c23f0a449bf8fb49
https://github.com/scummvm/scummvm/commit/f45a5eff90af49a4295583d0c23f0a449bf8fb49
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-05-24T16:57:45-04:00
Commit Message:
SCI: Fix QFG3 ring rope uninit read with script patch
Restores original behavior. The workaround caused the player to
always win and receive points even if they lost.
Changed paths:
engines/sci/engine/script_patches.cpp
engines/sci/engine/workarounds.cpp
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index c85e768393c..7c507caefa3 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -14060,6 +14060,58 @@ static const uint16 qfg3PatchBarterEvents[] = {
PATCH_END
};
+// After getting the ring from the rope, the script awardPrize stores the winner
+// in a temp variable during its first state and expects it to be there during
+// a later state. We patch the script to use its register property instead.
+//
+// Applies to: All versions
+// Responsible method: awardPrize:changeState
+// Fixes bug: #5277
+static const uint16 qfg3SignatureRingRopePrize[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x01, // ldi 01
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+43),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+39),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+39),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+33),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+40),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+48),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+10),
+ 0xa5, 0x00, // sat 00
+ SIG_ADDTOOFFSET(+49),
+ 0x85, 0x00, // lat 00
+ SIG_END
+};
+
+static const uint16 qfg3PatchRingRopePrize[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+43),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+39),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+39),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+33),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+40),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+48),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+10),
+ 0x65, 0x24, // aTop register
+ PATCH_ADDTOOFFSET(+49),
+ 0x63, 0x24, // pToa register
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry qfg3Signatures[] = {
{ true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
@@ -14073,6 +14125,7 @@ static const SciScriptPatcherEntry qfg3Signatures[] = {
{ true, 285, "missing points for telling about initiation script", 1, qfg3SignatureMissingPoints2a, qfg3PatchMissingPoints2 },
{ true, 285, "missing points for telling about initiation script", 1, qfg3SignatureMissingPoints2b, qfg3PatchMissingPoints2 },
{ true, 460, "NRS: floating spears", 1, qfg3SignatureNrsFloatingSpears, qfg3PatchNrsFloatingSpears },
+ { true, 510, "ring rope prize", 1, qfg3SignatureRingRopePrize, qfg3PatchRingRopePrize },
{ true, 550, "combat speed throttling script", 1, qfg3SignatureCombatSpeedThrottling1, qfg3PatchCombatSpeedThrottling1 },
{ true, 550, "combat speed throttling heap", 1, qfg3SignatureCombatSpeedThrottling2, qfg3PatchCombatSpeedThrottling2 },
{ true, 750, "hero goes out of bounds in room 750", 2, qfg3SignatureRoom750Bounds1, qfg3PatchRoom750Bounds1 },
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 719d770fe5b..f766c884fc8 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -532,7 +532,6 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_QFG2, 260, 260, 0, "jabbarS", "changeState", sig_uninitread_qfg2_1, -1, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before Jabbar is about to enter the house (where you have to hide in the wardrobe), bug #5164, temps 1 and 2
{ GID_QFG2, 500, 500, 0, "lightNextCandleS", "changeState", nullptr, -1, -1, { WORKAROUND_FAKE, 0 } }, // Inside the last room, while Ad Avis performs the ritual to summon the genie - bug #5566
{ GID_QFG2, -1, 700, 0, nullptr, "showSign", nullptr, 10, 10, { WORKAROUND_FAKE, 0 } }, // Occurs sometimes when reading a sign in Raseir, Shapeir et al - bugs #5627, #5635
- { GID_QFG3, 510, 510, 0, "awardPrize", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 1 } }, // Simbani warrior challenge, after throwing the spears and retrieving the ring - bug #5277. Must be non-zero, otherwise the prize is awarded twice - bug #6160
{ GID_QFG3, 140, 140, 0, "rm140", "init", sig_uninitread_qfg3_1, 0, 0, { WORKAROUND_FAKE, 0 } }, // when importing a character and selecting the previous profession - bug #5163
{ GID_QFG3, 330, 330, -1, "Teller", "doChild", nullptr, -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #5033, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #5148, temp 1)
{ GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", nullptr, 0, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #5169
Commit: 6e743a97efe438b638b3f27e39b853a5b011ff61
https://github.com/scummvm/scummvm/commit/6e743a97efe438b638b3f27e39b853a5b011ff61
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-05-24T17:05:27-04:00
Commit Message:
SCI: Fix QFG3 event bugs at the Laibon's hut
Fixes some well known deadend bugs in the original game:
- Not being able to give the Laibon the horn
- Not being able to enter the Laibon's hut
Bug #11425
Changed paths:
engines/sci/engine/script_patches.cpp
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 7c507caefa3..b3ad63d01d5 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -14112,6 +14112,179 @@ static const uint16 qfg3PatchRingRopePrize[] = {
PATCH_END
};
+// The Laibon's hut has complex script bugs that create unintentional dead ends.
+// After the Laibon requests a dinosaur horn from fighters and paladins, the
+// player is unable to give the horn on subsequent visits if they have the
+// bride's price items. Upon leaving the hut, they are unable to return.
+//
+// rm450:init sets an event number based on game state. The problem events are:
+// - Event 5: Fighters/paladins give the horn to begin initiation.
+// - Event 6: The bride's price can be paid, but fighters/paladins must have
+// given the horn in event 5 for the Laibon to accept the price.
+//
+// The main problem is that rm450:init tests for event 6 before event 5. If the
+// preconditions for event 6 are met then event 5 is suppressed. This is a
+// conflict because event 6 can't be completed until event 5 has been, but the
+// horn can only be given in event 5. More inconsistencies: some code enforces
+// an incorrect rule that these events can only occur once, despite event 6
+// being designed to reoccur and event 5 allowing the player to leave without
+// giving the horn in version 1.0. Finally, the hut's event logic is out of
+// sync between the entrance (room 420) and interior (450). The entrance blocks
+// events from recurring even if they weren't completed and is missing a flag
+// check, but unlike room 450 it does test the events in the correct order.
+//
+// We fix this by allowing room 450 to select event 5 (giving the horn) even if
+// the preconditions for event 6 are met. We also allow both events to reoccur.
+// Finally, we patch the relevant entrance logic to match the interior's.
+// Although these patches touch a lot of logic, they only affect the game when
+// it is in a state where the player wouldn't have been allowed to proceed with
+// events that they've met the preconditions for. Note that these changes are
+// broken up into smaller patches to be compatible with the many different
+// versions of these scripts, including the NRS fan patches that GOG includes,
+// and the comprehensive QFG3 Unofficial Update fan patches.
+//
+// Applies to: All versions
+// Responsible methods: rm450:init, rm420:init
+// Fixes bug: #11425
+static const uint16 qfg3SignatureLaibonHutEvents1[] = {
+ 0x88, SIG_MAGICDWORD, // lsg 0188 [ johari state ]
+ SIG_UINT16(0x0188),
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq? [ Laibon said the bride price ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchLaibonHutEvents1[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x20, // ge? [ Laibon said the bride price OR you've tried to pay before ]
+ PATCH_END
+};
+
+static const uint16 qfg3SignatureLaibonHutEvents2[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x06, // ldi 06
+ 0xa3, 0x0b, // sal 0b [ room event = 6 ]
+ 0x32, // jmp [ end of cond ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchLaibonHutEvents2[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x32, PATCH_UINT16(0x0000), // jmp [ continue evaluating room events ]
+ PATCH_END
+};
+
+static const uint16 qfg3SignatureLaibonHutEvents3[] = {
+ 0x31, 0x2b, // bnt 2b [ next room event ]
+ SIG_ADDTOOFFSET(+7),
+ 0x31, 0x22, // bnt 22 [ next room event ]
+ SIG_ADDTOOFFSET(+10),
+ 0x31, 0x16, // bnt 16 [ next room event ]
+ SIG_ADDTOOFFSET(+6),
+ 0x2f, SIG_ADDTOOFFSET(+1), // bt (06, but 08 in QFG3 Unofficial Update)
+ 0x88, SIG_UINT16(0x016a), // lsg 016a [ character class ]
+ 0x35, 0x03, // ldi 03 [ impossible value ]
+ 0x1a, // eq?
+ 0x31, 0x06, // bnt 06 [ always false ]
+ SIG_MAGICDWORD,
+ 0x35, 0x05, // ldi 05
+ 0xa3, 0x0b, // sal 0b [ room event = 5 ]
+ 0x33, // jmp [ exit cond ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchLaibonHutEvents3[] = {
+ 0x31, 0x23, // bnt 23 [ next room event ]
+ PATCH_ADDTOOFFSET(+7),
+ 0x31, 0x1a, // bnt 1a [ next room event ]
+ PATCH_ADDTOOFFSET(+10),
+ 0x31, 0x0e, // bnt 0e [ next room event ]
+ PATCH_ADDTOOFFSET(+6),
+ 0x31, 0x06, // bnt 06
+ 0x35, 0x05, // ldi 05
+ 0xa3, 0x0b, // sal 0b [ room event = 5 ]
+ 0x33, 0x06, // jmp 06 [ exit cond ]
+ 0x8a, PATCH_UINT16(0x000b), // lsl 000b
+ 0x35, 0x06, // ldi 06
+ 0x1a, // eq? [ is room event 6? ]
+ 0x2f, // bt [ exit cond ]
+ PATCH_END
+};
+
+// same as above but for the NRS script due its wide branch offsets
+static const uint16 qfg3SignatureNrsLaibonHutEvents3[] = {
+ 0x30, SIG_UINT16(0x0031), // bnt 0031 [ next room event ]
+ SIG_ADDTOOFFSET(+8),
+ 0x30, SIG_UINT16(0x0026), // bnt 0026 [ next room event ]
+ SIG_ADDTOOFFSET(+10),
+ 0x30, SIG_UINT16(0x0019), // bnt 0019 [ next room event ]
+ SIG_ADDTOOFFSET(+6),
+ 0x2e, SIG_UINT16(0x0006), // bt 0006
+ 0x88, SIG_UINT16(0x016a), // lsg 016a [ character class ]
+ 0x35, 0x03, // ldi 03 [ impossible value ]
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0007), // bnt 0007 [ always false ]
+ SIG_MAGICDWORD,
+ 0x35, 0x05, // ldi 05
+ 0xa3, 0x0b, // sal 0b [ room event = 5 ]
+ 0x32, // jmp [ exit cond ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchNrsLaibonHutEvents3[] = {
+ 0x30, PATCH_UINT16(0x0028), // bnt 0028 [ next room event ]
+ PATCH_ADDTOOFFSET(+8),
+ 0x30, PATCH_UINT16(0x001d), // bnt 001d [ next room event ]
+ PATCH_ADDTOOFFSET(+10),
+ 0x30, PATCH_UINT16(0x0010), // bnt 0010 [ next room event ]
+ PATCH_ADDTOOFFSET(+6),
+ 0x30, PATCH_UINT16(0x0007), // bnt 0007
+ 0x35, 0x05, // ldi 05
+ 0xa3, 0x0b, // sal 0b [ room event = 5 ]
+ 0x32, PATCH_UINT16(0x0006), // jmp 0006 [ exit cond ]
+ 0x8a, PATCH_UINT16(0x000b), // lsl 000b
+ 0x35, 0x06, // ldi 06
+ 0x1a, // eq? [ is room event 6? ]
+ 0x2e, // bt [ exit cond ]
+ PATCH_END
+};
+
+static const uint16 qfg3SignatureLaibonHutEntrance1[] = {
+ 0x88, SIG_MAGICDWORD, // lsg 016e [ entrance event ]
+ SIG_UINT16(0x016e),
+ 0x35, 0x09, // ldi 09
+ 0x1c, // ne? [ global366 != 9 (haven't entered for event 5) ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchLaibonHutEntrance1[] = {
+ 0x78, // push1
+ 0x39, 0x26, // pushi 26 [ flag 38 ]
+ 0x45, 0x06, 0x02, // callb proc0_6 [ is flag 38 set? (dispelled Johari) ]
+ PATCH_END
+};
+
+static const uint16 qfg3SignatureLaibonHutEntrance2[] = {
+ 0x88, SIG_MAGICDWORD, // lsg 0188 [ johari state ]
+ SIG_UINT16(0x0188),
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq? [ Laibon said the bride price ]
+ SIG_ADDTOOFFSET(+59),
+ 0x88, SIG_UINT16(0x016e), // lsg 016e [ entrance event ]
+ 0x35, 0x0d, // ldi 0d
+ 0x1c, // ne? [ global366 != 13 (haven't entered for event 6) ]
+ SIG_END
+};
+
+static const uint16 qfg3PatchLaibonHutEntrance2[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x20, // ge? [ Laibon said the bride price OR you've tried to pay before ]
+ PATCH_ADDTOOFFSET(+59),
+ 0x88, PATCH_UINT16(0x0188), // lsg 0188
+ 0x35, 0x04, // ldi 04
+ PATCH_END // ne? [ Haven't paid Laibon the bride price ]
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry qfg3Signatures[] = {
{ true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
@@ -14124,6 +14297,12 @@ static const SciScriptPatcherEntry qfg3Signatures[] = {
{ true, 285, "missing points for telling about initiation heap", 1, qfg3SignatureMissingPoints1, qfg3PatchMissingPoints1 },
{ true, 285, "missing points for telling about initiation script", 1, qfg3SignatureMissingPoints2a, qfg3PatchMissingPoints2 },
{ true, 285, "missing points for telling about initiation script", 1, qfg3SignatureMissingPoints2b, qfg3PatchMissingPoints2 },
+ { true, 420, "laibon hut entrance (1/2)", 1, qfg3SignatureLaibonHutEntrance1, qfg3PatchLaibonHutEntrance1 },
+ { true, 420, "laibon hut entrance (2/2)", 1, qfg3SignatureLaibonHutEntrance2, qfg3PatchLaibonHutEntrance2 },
+ { true, 450, "laibon hut events (1/3)", 1, qfg3SignatureLaibonHutEvents1, qfg3PatchLaibonHutEvents1 },
+ { true, 450, "laibon hut events (2/3)", 1, qfg3SignatureLaibonHutEvents2, qfg3PatchLaibonHutEvents2 },
+ { true, 450, "laibon hut events (3/3)", 1, qfg3SignatureLaibonHutEvents3, qfg3PatchLaibonHutEvents3 },
+ { true, 450, "NRS: laibon hut events (3/3)", 1, qfg3SignatureNrsLaibonHutEvents3, qfg3PatchNrsLaibonHutEvents3 },
{ true, 460, "NRS: floating spears", 1, qfg3SignatureNrsFloatingSpears, qfg3PatchNrsFloatingSpears },
{ true, 510, "ring rope prize", 1, qfg3SignatureRingRopePrize, qfg3PatchRingRopePrize },
{ true, 550, "combat speed throttling script", 1, qfg3SignatureCombatSpeedThrottling1, qfg3PatchCombatSpeedThrottling1 },
More information about the Scummvm-git-logs
mailing list