aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorsluicebox2018-10-23 09:06:06 -0700
committerFilippos Karapetis2018-10-23 19:06:06 +0300
commit2b28bf942e0e140136aa4b95628ea19f40512b67 (patch)
treec649e443c4e35b55ec7ffcdfa2a95841ea3bef1f /engines
parent07f208f59e570bb81d99433ff57418601ad36f20 (diff)
downloadscummvm-rg350-2b28bf942e0e140136aa4b95628ea19f40512b67.tar.gz
scummvm-rg350-2b28bf942e0e140136aa4b95628ea19f40512b67.tar.bz2
scummvm-rg350-2b28bf942e0e140136aa4b95628ea19f40512b67.zip
SCI: Script patch for LB1 input/collision lockups (#1353)
Fixes 20+ lockups in the original game, bug #10733
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/script_patches.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 7b46101c27..a5c22a461a 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -3494,6 +3494,99 @@ static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix2[] = {
PATCH_END
};
+// LB1 contains over 20 commands which lockup the game if entered while ego is
+// colliding with an obstacle. Opening and moving closets in room 43 are prime
+// examples. They are all symptoms of a global bug.
+
+// Every cycle, CB1:doit checks to see if ego appears to be walking and blocked,
+// and if so it stops ego's motion and sets ego's view to 11 (standing). If ego
+// has just collided with an obstacle but is still displaying view 1 (walking)
+// when a command is entered which disables input and sets ego's motion without
+// setting an avoider then CB1:doit will stop that new motion at the start of
+// the next cycle and lockup the game. This occurs in part because CB1:doit
+// tests potentially stale values that the new motion hasn't yet had a chance
+// to set. Scripts which set an avoider aren't vulnerable because CB1:doit
+// won't stop ego if one is set. Other SCI games don't have this kind of code
+// in their Game's doit and so they don't have this bug.
+
+// We fix this by clearing the kSignalHitObstacle flag whenever Act:setMotion is
+// called with a new motion. This causes CB1:doit's subsequent call to
+// ego:isBlocked to return false, instead of a stale true value, preventing
+// CB1:doit from stopping the new motion before it's had a chance to start.
+// Should the new motion actually be blocked then the interpreter will then set
+// the flag when processing the motion as usual. This patch closes the short
+// window during which this value is stale and CB1:doit tests it.
+
+// Applies to: DOS, Amiga, Atari ST and occurs in Sierra's interpreter.
+// Responsible method: Act:setMotion
+// Fixes bug #10733
+static const uint16 laurabow1SignatureObstacleCollisionLockupsFix[] = {
+ SIG_MAGICDWORD,
+ 0x30, SIG_UINT16(0x002f), // bnt 2f
+ 0x38, SIG_UINT16(0x00a3), // pushi a3 [ startUpd ]
+ 0x76, // push0
+ 0x54, 0x04, // self 4
+ 0x7a, // push2 [ -info- ]
+ 0x76, // push0
+ 0x87, 0x01, // lap param1
+ 0x4a, 0x04, // send 4
+ 0x36, // push
+ 0x34, SIG_UINT16(0x8000), // ldi 8000
+ 0x12, // and
+ 0x30, SIG_UINT16(0x000a), // bnt a
+ 0x39, 0x56, // pushi 56 [ new ]
+ 0x76, // push0
+ 0x87, 0x01, // lap param1
+ 0x4a, 0x04, // send 4
+ 0x32, SIG_UINT16(0x0002), // jmp 2
+ 0x87, 0x01, // lap param1
+ 0x65, 0x4c, // aTop mover
+ 0x39, 0x57, // pushi 57 [ init ]
+ 0x78, // push1
+ 0x7c, // pushSelf
+ 0x59, 0x02, // &rest 2
+ 0x63, 0x4c, // pToa mover
+ 0x4a, 0x06, // send 6
+ 0x32, SIG_UINT16(0x0004), // jmp 4
+ 0x35, 0x00, // ldi 0
+ SIG_END
+};
+
+static const uint16 laurabow1PatchObstacleCollisionLockupsFix[] = {
+ 0x31, 0x32, // bnt 32 [ save 1 byte ]
+
+ 0x63, 0x1c, // pToa signal
+ 0x38, PATCH_UINT16(0xfbff), // pushi fbff
+ 0x12, // and
+ 0x65, 0x1c, // aTop signal [ clear kSignalHitObstacle (0400) ]
+
+ 0x38, PATCH_UINT16(0x00a3), // pushi a3 [ startUpd ]
+ 0x76, // push0
+ 0x54, 0x04, // self 4
+ 0x7a, // push2 [ -info- ]
+ 0x76, // push0
+ 0x87, 0x01, // lap param1
+ 0x4a, 0x04, // send 4
+ 0x38, PATCH_UINT16(0x8000), // pushi 8000 [ save 1 byte ]
+ 0x12, // and
+ 0x31, 0x09, // bnt 9 [ save 1 byte ]
+ 0x39, 0x56, // pushi 56 [ new ]
+ 0x76, // push0
+ 0x87, 0x01, // lap param1
+ 0x4a, 0x04, // send 4
+ 0x33, 0x02, // jmp 2 [ save 1 byte ]
+ 0x87, 0x01, // lap param1
+ 0x65, 0x4c, // aTop mover
+ 0x39, 0x57, // pushi 57 [ init ]
+ 0x78, // push1
+ 0x7c, // pushSelf
+ 0x59, 0x02, // &rest 2
+ 0x63, 0x4c, // pToa mover
+ 0x4a, 0x06, // send 6
+ 0x48, // ret [ save 4 bytes ]
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry laurabow1Signatures[] = {
{ true, 4, "easter egg view fix", 1, laurabow1SignatureEasterEggViewFix, laurabow1PatchEasterEggViewFix },
@@ -3504,6 +3597,7 @@ static const SciScriptPatcherEntry laurabow1Signatures[] = {
{ true, 58, "chapel candles persistence", 1, laurabow1SignatureChapelCandlesPersistence, laurabow1PatchChapelCandlesPersistence },
{ true, 236, "tell Lilly about Gertie blocking fix 1/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix1, laurabow1PatchTellLillyAboutGertieBlockingFix1 },
{ true, 236, "tell Lilly about Gertie blocking fix 2/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix2, laurabow1PatchTellLillyAboutGertieBlockingFix2 },
+ { true, 998, "obstacle collision lockups fix", 1, laurabow1SignatureObstacleCollisionLockupsFix, laurabow1PatchObstacleCollisionLockupsFix },
SCI_SIGNATUREENTRY_TERMINATOR
};