aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2017-10-09 01:58:16 +0200
committerMartin Kiewitz2017-10-09 01:58:16 +0200
commitbd94bbc3e309c8107688640023b95d7601651e05 (patch)
treeb6822f6aef1f7e8c1ca9a987b56277fc15286c2d
parent870cd802029c25077818f0a03c8396b3f763ebaf (diff)
downloadscummvm-rg350-bd94bbc3e309c8107688640023b95d7601651e05.tar.gz
scummvm-rg350-bd94bbc3e309c8107688640023b95d7601651e05.tar.bz2
scummvm-rg350-bd94bbc3e309c8107688640023b95d7601651e05.zip
SCI: Add QfG4 script patch to fix sliding down slope bug #9801
It's quite difficult to patch. I hope this finally solved it.
-rw-r--r--engines/sci/engine/script_patches.cpp95
-rw-r--r--engines/sci/engine/selector.cpp4
-rw-r--r--engines/sci/engine/selector.h5
3 files changed, 97 insertions, 7 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index f7dc620af4..bc4974955b 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -100,6 +100,9 @@ static const char *const selectorNameTable[] = {
"number", // system selector
"setScript", // system selector
"setCycle", // system selector
+ "setStep", // system selector
+ "cycleSpeed", // system selector
+ "handsOff", // system selector
"localize", // Freddy Pharkas
"put", // Police Quest 1 VGA
"say", // Quest For Glory 1 VGA
@@ -168,6 +171,9 @@ enum ScriptPatcherSelectors {
SELECTOR_number,
SELECTOR_setScript,
SELECTOR_setCycle,
+ SELECTOR_setStep,
+ SELECTOR_cycleSpeed,
+ SELECTOR_handsOff,
SELECTOR_localize,
SELECTOR_put,
SELECTOR_say,
@@ -5846,14 +5852,89 @@ static const uint16 qfg4BenchmarkPatch[] = {
PATCH_END
};
-// script, description, signature patch
+// Right at the start of the game inside room 800, when automatically sliding down a slope
+// an error may happen inside Grooper::doit caused by a timing issue.
+//
+// We delay a bit, so that hero::cycler should always be set.
+//
+// Applies to: English CD, English floppy, German floppy
+// Responsible method: sFallsBackSide::changeState (script 803)
+// Fixes bug #9801
+static const uint16 qfg4SlidingDownSlopeSignature[] = {
+ 0x87, 0x01, // lap param[1]
+ 0x65, SIG_ADDTOOFFSET(+1), // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x30, // bnt [skip state 0]
+ 0x38, SIG_SELECTOR16(handsOff), // pushi handsOff
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, SIG_UINT16(0x0004), // send 04
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16(cycleSpeed), // pushi cycleSpeed
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, SIG_UINT16(0x0004), // send 04
+ 0xa3, 0x00, // sal local[0]
+ 0x38, SIG_SELECTOR16(setStep), // pushi setStep
+ 0x7a, // push2
+ 0x78, // push1
+ 0x78, // push1
+ 0x38, SIG_SELECTOR16(setMotion), // pushi setMotion
+ 0x38, SIG_UINT16(0x0004), // pushi 04
+ 0x51, SIG_ADDTOOFFSET(+1), // class PolyPath
+ 0x36, // push
+ 0x39, 0x49, // pushi $49
+ 0x39, 0x50, // pushi $50
+ 0x7c, // pushSelf
+ 0x81, 0x00, // lag global[0]
+ 0x4a, SIG_UINT16(0x0014), // send $14
+ SIG_END
+};
+
+static const uint16 qfg4SlidingDownSlopePatch[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x2f, 0x34, // bt [skip state 0]
+ 0x38, PATCH_SELECTOR16(handsOff), // pushi handsOff
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, PATCH_UINT16(0x0004), // send 04
+
+ 0x78, // push1
+ 0x39, 0x20, // pushi $20
+ 0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, $2
+ 0x38, PATCH_SELECTOR16(setStep), // pushi setStep
+ 0x7a, // push2
+ 0x78, // push1
+ 0x78, // push1
+ 0x38, PATCH_SELECTOR16(setMotion), // pushi setMotion
+ 0x38, PATCH_UINT16(0x0004), // pushi 04
+ 0x51, PATCH_GETORIGINALBYTE(+44), // class PolyPath
+ 0x36, // push
+ 0x39, 0x49, // pushi $49
+ 0x39, 0x50, // pushi $50
+ 0x7c, // pushSelf
+ 0x81, 0x00, // lag global[0]
+ 0x38, PATCH_SELECTOR16(cycleSpeed), // pushi cycleSpeed
+ 0x76, // push0
+ 0x4a, PATCH_UINT16(0x0018), // send $18
+ 0xa3, 0x00, // sal local[0]
+ 0x3a, // toss
+ 0x48, // ret
+ PATCH_END
+};
+
+// script, description, signature patch
static const SciScriptPatcherEntry qfg4Signatures[] = {
- { true, 1, "disable volume reset on startup", 1, sci2VolumeResetSignature, sci2VolumeResetPatch },
- { true, 1, "disable video benchmarking", 1, qfg4BenchmarkSignature, qfg4BenchmarkPatch },
- { true, 83, "fix incorrect array type", 1, qfg4TrapArrayTypeSignature, qfg4TrapArrayTypePatch },
- { true, 64990, "increase number of save games (1/2)", 1, sci2NumSavesSignature1, sci2NumSavesPatch1 },
- { true, 64990, "increase number of save games (2/2)", 1, sci2NumSavesSignature2, sci2NumSavesPatch2 },
- { true, 64990, "disable change directory button", 1, sci2ChangeDirSignature, sci2ChangeDirPatch },
+ { true, 1, "disable volume reset on startup", 1, sci2VolumeResetSignature, sci2VolumeResetPatch },
+ { true, 1, "disable video benchmarking", 1, qfg4BenchmarkSignature, qfg4BenchmarkPatch },
+ { true, 83, "fix incorrect array type", 1, qfg4TrapArrayTypeSignature, qfg4TrapArrayTypePatch },
+ { true, 803, "fix sliding down slope", 1, qfg4SlidingDownSlopeSignature, qfg4SlidingDownSlopePatch },
+ { true, 64990, "increase number of save games (1/2)", 1, sci2NumSavesSignature1, sci2NumSavesPatch1 },
+ { true, 64990, "increase number of save games (2/2)", 1, sci2NumSavesSignature2, sci2NumSavesPatch2 },
+ { true, 64990, "disable change directory button", 1, sci2ChangeDirSignature, sci2ChangeDirPatch },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 42c71c4d31..d2f6a14797 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -165,6 +165,10 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(vanishingY);
FIND_SELECTOR(iconIndex);
FIND_SELECTOR(select);
+ FIND_SELECTOR(handsOff);
+ FIND_SELECTOR(setStep);
+ FIND_SELECTOR(setMotion);
+ FIND_SELECTOR(cycleSpeed);
#ifdef ENABLE_SCI32
FIND_SELECTOR(data);
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index 2debd3204d..2c1a34e938 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -131,6 +131,11 @@ struct SelectorCache {
Selector iconIndex; ///< Used to index icon bar objects
Selector select;
+ Selector handsOff;
+ Selector setStep;
+ Selector setMotion;
+ Selector cycleSpeed;
+
#ifdef ENABLE_SCI32
Selector data; // Used by Array()/String()
Selector picture; // Used to hold the picture ID for SCI32 pictures