SCI32: Fix PHANT1 basement fast-forward lockup

Fixes bug #14368
This commit is contained in:
sluicebox
2023-04-05 16:07:59 -07:00
parent c1c5c13d94
commit 591d2a801e
+46
View File
@@ -11723,6 +11723,51 @@ static const uint16 phant1RatPatch[] = {
PATCH_END
};
// In the basement there is a moment where clicking the fast-forward button
// locks up the game. Fast-forward changes the current room script to state
// zero and sets global 115. Most scripts' changeState methods start by testing
// this global to implement fast-forward behavior. They then reset the global
// when disposing before calling handsOn. scaryHandsOnCode:doit enables input,
// empties the event queue, and then polls and processes one final event.
// This creates a window where handsOn can process a fast-forward click and
// re-enter the room script while it's in the middle of disposing itself.
//
// Most room scripts have a structure that survives this re-entrancy, but room
// 20100's sEnterFrom20200 is unusual. It doesn't test the fast-forward global
// in state zero. Instead, it unconditionally calls handsOff, causing the
// original handsOn call to undo its work before it returns.
//
// We fix this by swapping two function calls in sEnterFrom20200:dispose:
// handsOn and super:dispose. Now the script is fully disposed before handsOn.
// If a fast-forward click occurs it will no longer have any effect, because
// the room no longer has a script. If other scripts are discovered with this
// same problem, this patch will probably apply.
//
// Applies to: All versions
// Responsible method: sEnterFrom20200:dispose
// Fixes bug: #14368
static const uint16 phant1BasementFastForwardSignature[] = {
0x35, 0x00, // ldi 00
0xa1, SIG_MAGICDWORD, 0x73, // lag 73 [ fast-forward = 0 ]
0x38, SIG_SELECTOR16(handsOn), // pushi handsOn
0x76, // push0
0x81, 0x01, // lag 01
0x4a, SIG_UINT16(0x0004), // send 04 [ Scary handsOn: ]
0x38, SIG_SELECTOR16(dispose), // pushi dispose
0x76, // push0
0x59, 0x01, // &rest 01
0x57, SIG_ADDTOOFFSET(+1), // super 04 [ super dispose: &rest ]
SIG_UINT16(0x0004),
SIG_END
};
static const uint16 phant1BasementFastForwardPatch[] = {
PATCH_ADDTOOFFSET(+4), // [ fast-forward = 0 ]
PATCH_GETORIGINALBYTES(13, 10), // [ super dispose: &rest ]
PATCH_GETORIGINALBYTES(4, 9), // [ Scary handsOn: ]
PATCH_END
};
// In Phantasmagoria the cursor's hover state will not trigger on any of the
// buttons in the main menu after returning to the main menu from a game, or
// when choosing "Quit" on the main menu and then cancelling the quit in the
@@ -12127,6 +12172,7 @@ static const SciScriptPatcherEntry phantasmagoriaSignatures[] = {
{ true, 901, "fix invalid array construction", 1, sci21IntArraySignature, sci21IntArrayPatch },
{ true, 901, "fix delete save", 1, phant1DeleteSaveSignature, phant1DeleteSavePatch },
{ true, 1111, "ignore audio settings from save game", 1, phant1SavedVolumeSignature, phant1SavedVolumePatch },
{ true, 20100, "fix basement fast-forward", 1, phant1BasementFastForwardSignature, phant1BasementFastForwardPatch },
{ true, 20200, "fix broken rat init in sEnterFromAlcove", 1, phant1RatSignature, phant1RatPatch },
{ true, 20200, "fix chapter 5 wine cask hotspot", 1, phant1WineCaskHotspotSignature, phant1WineCaskHotspotPatch },
{ true, 45950, "fix chase file deletion", 1, phant1DeleteChaseFileSignature, phant1DeleteChaseFilePatch },