Skip to content

Commit

Permalink
SCI: Fix QFG3 ring rope uninit read with script patch
Browse files Browse the repository at this point in the history
Restores original behavior. The workaround caused the player to
always win and receive points even if they lost.
  • Loading branch information
sluicebox committed May 24, 2022
1 parent b3a77a7 commit f45a5ef
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
53 changes: 53 additions & 0 deletions engines/sci/engine/script_patches.cpp
Expand Up @@ -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 },
Expand All @@ -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 },
Expand Down
1 change: 0 additions & 1 deletion engines/sci/engine/workarounds.cpp
Expand Up @@ -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
Expand Down

0 comments on commit f45a5ef

Please sign in to comment.