diff options
Diffstat (limited to 'engines/sci/engine/script_patches.cpp')
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 110 |
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; |