aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/script_patches.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/script_patches.cpp')
-rw-r--r--engines/sci/engine/script_patches.cpp110
1 files changed, 107 insertions, 3 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 1a276b1dd6..6d8938c7a4 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -76,6 +76,7 @@ namespace Sci {
// before they can get used using the SIG_SELECTORx and PATCH_SELECTORx commands.
// You have to use the exact same order in both the table and the enum, otherwise
// it won't work.
+// ATTENTION: selectors will only work here, when they are also in SelectorCache (selector.h)
static const char *const selectorNameTable[] = {
"cycles", // system selector
@@ -91,6 +92,7 @@ static const char *const selectorNameTable[] = {
"cel", // system selector
"setMotion", // system selector
"overlay", // system selector
+ "setPri", // system selector - for setting priority
"deskSarg", // Gabriel Knight
"localize", // Freddy Pharkas
"put", // Police Quest 1 VGA
@@ -128,6 +130,7 @@ enum ScriptPatcherSelectors {
SELECTOR_cel,
SELECTOR_setMotion,
SELECTOR_overlay,
+ SELECTOR_setPri,
SELECTOR_deskSarg,
SELECTOR_localize,
SELECTOR_put,
@@ -2133,9 +2136,34 @@ static const uint16 kq7BenchmarkPatch[] = {
PATCH_END
};
+// When attempting to use an inventory item on an object that does not interact
+// with that item, the game temporarily displays an X cursor, but does this by
+// spinning for 90000 cycles, which make the duration dependent on CPU speed,
+// maxes out the CPU for no reason, and keeps the engine from polling for events
+// (which may make the window appear nonresponsive to the OS)
+// Applies to at least: KQ7 English 2.00b
+static const uint16 kq7PragmaFailSpinSignature[] = {
+ 0x35, 0x00, // ldi 0
+ 0xa5, 0x02, // sat 2
+ SIG_MAGICDWORD,
+ 0x8d, 0x02, // lst 2
+ 0x35, 0x03, // ldi 3
+ 0x22, // lt?
+ SIG_END
+};
+
+static const uint16 kq7PragmaFailSpinPatch[] = {
+ 0x78, // push1
+ 0x39, 0x12, // pushi 18 (~300ms)
+ 0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+ 0x33, 0x16, // jmp to setCursor
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry kq7Signatures[] = {
{ true, 0, "disable video benchmarking", 1, kq7BenchmarkSignature, kq7BenchmarkPatch },
+ { true, 0, "remove hardcoded spinloop", 1, kq7PragmaFailSpinSignature, kq7PragmaFailSpinPatch },
{ true, 31, "subtitle fix 1/3", 1, kq7SignatureSubtitleFix1, kq7PatchSubtitleFix1 },
{ true, 64928, "subtitle fix 2/3", 1, kq7SignatureSubtitleFix2, kq7PatchSubtitleFix2 },
{ true, 64928, "subtitle fix 3/3", 1, kq7SignatureSubtitleFix3, kq7PatchSubtitleFix3 },
@@ -2498,6 +2526,79 @@ static const SciScriptPatcherEntry larry6HiresSignatures[] = {
SCI_SIGNATUREENTRY_TERMINATOR
};
+#pragma mark -
+#pragma mark Leisure Suit Larry 7
+
+// ===========================================================================
+// In room 540 of Leisure Suit Larry 7, Larry will use 4 items on a so called cheese maker.
+// A short cutscene will then play.
+// During that cutscene on state 6, an animation will get triggered via a special
+// cycler ("End", but from script 64041), that is capable of doing ::cues on specific cels.
+// The code of the state is broken and pushes the object itself as the 2nd cel to cue on.
+// This parameter gets later changed to last cel by CycleCueList::init.
+// Right now, we do not handle comparisons between references to objects and regular values like
+// SSCI, so this will need to get fixed too. But this script bug should also get fixed, because
+// otherwise it works just by accident.
+//
+// Applies to at least: English PC-CD, German PC-CD
+// Responsible method: soMakeCheese::changeState(6) in script 540
+static const uint16 larry7SignatureMakeCheese[] = {
+ 0x38, SIG_UINT16(4), // pushi 04
+ 0x51, 0xc4, // class End
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x7c, // pushSelf
+ 0x39, 0x04, // pushi 04
+ 0x7c, // pushSelf
+ SIG_END
+};
+
+static const uint16 larry7PatchMakeCheese[] = {
+ 0x39, 0x04, // pushi 04 - save 1 byte
+ 0x51, 0xc4, // class End
+ 0x36,
+ 0x7c, // pushSelf
+ 0x39, 0x04, // pushi 04
+ 0x39, 0x10, // pushi 10h (last cel of view 54007, loop 0)
+ PATCH_END
+};
+
+// ===========================================================================
+// During the same cheese maker cutscene as mentioned before, there is also
+// a little priority issue, which also happens in the original interpreter.
+// While Larry is pouring liquid into the cheese maker, he appears shortly right
+// in front of the guillotine instead of behind it.
+// This is caused by soMakeCheese::changeState(2) setting priority of ego to 500.
+// It is needed to change priority a bit, otherwise Larry would also appear behind the cheese
+// maker and that wouldn't make sense, but the cheese maker has a priority of only 373.
+//
+// This of course also happens, when using the original interpreter.
+//
+// We change this to set priority to 374, which works fine.
+//
+// Applies to at least: English PC-CD, German PC-CD
+// Responsible method: soMakeCheese::changeState(2) in script 540
+static const uint16 larry7SignatureMakeCheesePriority[] = {
+ 0x38, SIG_SELECTOR16(setPri), // pushi (setPri)
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x38, SIG_UINT16(500), // pushi 1F4h (500d)
+ SIG_END
+};
+
+static const uint16 larry7PatchMakeCheesePriority[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x38, PATCH_UINT16(374), // pushi 176h (374d)
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry larry7Signatures[] = {
+ { true, 540, "fix make cheese cutscene (cycler)", 1, larry7SignatureMakeCheese, larry7PatchMakeCheese },
+ { true, 540, "fix make cheese cutscene (priority)", 1, larry7SignatureMakeCheesePriority, larry7PatchMakeCheesePriority },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
#endif
// ===========================================================================
@@ -3323,9 +3424,9 @@ static const uint16 mothergooseHiresPatchLogo[] = {
// Responsible method: rhymeScript::changeState
static const uint16 mothergooseHiresSignatureHorse[] = {
SIG_MAGICDWORD,
- 0x39, 0x4a, // pushi $4a (setPri)
- 0x78, // push1
- 0x38, SIG_UINT16(0xb7), // pushi $b7
+ 0x39, SIG_SELECTOR8(setPri), // pushi $4a (setPri)
+ 0x78, // push1
+ 0x38, SIG_UINT16(0xb7), // pushi $b7
SIG_END
};
@@ -5962,6 +6063,9 @@ void ScriptPatcher::processScript(uint16 scriptNr, SciSpan<byte> scriptData) {
case GID_LSL6HIRES:
signatureTable = larry6HiresSignatures;
break;
+ case GID_LSL7:
+ signatureTable = larry7Signatures;
+ break;
#endif
case GID_MOTHERGOOSE256:
signatureTable = mothergoose256Signatures;