diff options
Diffstat (limited to 'engines/sci/engine/script_patches.cpp')
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index ca6a439692..8039c5f282 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -408,6 +408,59 @@ static const SciScriptPatcherEntry fanmadeSignatures[] = { }; // =========================================================================== + +// WORKAROUND +// Freddy Pharkas intro screen +// Sierra used inner loops for the scaling of the 2 title views. +// Those inner loops don't call kGameIsRestarting, which is why +// we do not update the screen and we also do not throttle. +// +// This patch fixes this and makes it work. +// Applies to at least: English PC-CD +// Responsible method: sTownScript::changeState(1), sTownScript::changeState(3) (script 110) +static const uint16 freddypharkasSignatureIntroScaling[] = { + 0x38, SIG_ADDTOOFFSET(+2), // pushi (setLoop) (009b for PC CD) + 0x78, // push1 + PATCH_ADDTOOFFSET(1), // push0 for first code, push1 for second code + 0x38, SIG_ADDTOOFFSET(+2), // pushi (setStep) (0143 for PC CD) + 0x7a, // push2 + 0x39, 0x05, // pushi 05 + 0x3c, // dup + 0x72, SIG_ADDTOOFFSET(+2), // lofsa (view) + SIG_MAGICDWORD, + 0x4a, 0x1e, // send 1e + 0x35, 0x0a, // ldi 0a + 0xa3, 0x02, // sal local[2] + // start of inner loop + 0x8b, 0x02, // lsl local[2] + SIG_ADDTOOFFSET(+43), // skip almost all of inner loop + 0xa3, 0x02, // sal local[2] + 0x33, 0xcf, // jmp [inner loop start] + SIG_END +}; + +static const uint16 freddypharkasPatchIntroScaling[] = { + // remove setLoop(), objects in heap are already prepared, saves 5 bytes + 0x38, + PATCH_GETORIGINALBYTE(+6), + PATCH_GETORIGINALBYTE(+7), // pushi (setStep) + 0x7a, // push2 + 0x39, 0x05, // pushi 05 + 0x3c, // dup + 0x72, + PATCH_GETORIGINALBYTE(+13), + PATCH_GETORIGINALBYTE(+14), // lofsa (view) + 0x4a, 0x18, // send 18 - adjusted + 0x35, 0x0a, // ldi 0a + 0xa3, 0x02, // sal local[2] + // start of new inner loop + 0x39, 0x00, // pushi 00 + 0x43, 0x2c, 0x00, // callk GameIsRestarting <-- add this so that our speed throttler is triggered + SIG_ADDTOOFFSET(+47), // skip almost all of inner loop + 0x33, 0xca, // jmp [inner loop start] + PATCH_END +}; + // script 0 of freddy pharkas/CD PointsSound::check waits for a signal and if // no signal received will call kDoSound(0xD) which is a dummy in sierra sci // and ScummVM and will use acc (which is not set by the dummy) to trigger @@ -526,6 +579,7 @@ static const uint16 freddypharkasPatchMacInventory[] = { static const SciScriptPatcherEntry freddypharkasSignatures[] = { { true, 0, "CD: score early disposal", 1, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal }, { true, 15, "Mac: broken inventory", 1, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory }, + { true, 110, "intro scaling workaround", 2, freddypharkasSignatureIntroScaling, freddypharkasPatchIntroScaling }, { true, 235, "CD: canister pickup hang", 3, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang }, { true, 320, "ladder event issue", 2, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent }, SCI_SIGNATUREENTRY_TERMINATOR @@ -759,6 +813,32 @@ static const uint16 kq5PatchWitchCageInit[] = { PATCH_END }; +// The multilingual releases of KQ5 hang right at the end during the magic battle with Mordack. +// It seems additional code was added to wait for signals, but the signals are never set and thus +// the game hangs. We disable that code, so that the battle works again. +// This also happened in the original interpreter. +// We must not change similar code, that happens before. + +// Applies to at least: French PC floppy, German PC floppy, Spanish PC floppy +// Responsible method: stingScript::changeState, dragonScript::changeState, snakeScript::changeState +static const uint16 kq5SignatureMultilingualEndingGlitch[] = { + SIG_MAGICDWORD, + 0x89, 0x57, // lsg global[57h] + 0x35, 0x00, // ldi 0 + 0x1a, // eq? + 0x18, // not + 0x30, SIG_UINT16(0x0011), // bnt [skip signal check] + SIG_ADDTOOFFSET(+8), // skip globalSound::prevSignal get code + 0x36, // push + 0x35, 0x0a, // ldi 0Ah + SIG_END +}; + +static const uint16 kq5PatchMultilingualEndingGlitch[] = { + PATCH_ADDTOOFFSET(+6), + 0x32, // change BNT into JMP + PATCH_END +}; // In the final battle, the DOS version uses signals in the music to handle // timing, while in the Windows version another method is used and the GM @@ -789,9 +869,10 @@ static const uint16 kq5PatchWinGMSignals[] = { // script, description, signature patch static const SciScriptPatcherEntry kq5Signatures[] = { - { true, 0, "CD: harpy volume change", 1, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume }, - { true, 200, "CD: witch cage init", 1, kq5SignatureWitchCageInit, kq5PatchWitchCageInit }, - { false, 124, "Win: GM Music signal checks", 4, kq5SignatureWinGMSignals, kq5PatchWinGMSignals }, + { true, 0, "CD: harpy volume change", 1, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume }, + { true, 200, "CD: witch cage init", 1, kq5SignatureWitchCageInit, kq5PatchWitchCageInit }, + { true, 124, "Multilingual: Ending glitching out", 3, kq5SignatureMultilingualEndingGlitch, kq5PatchMultilingualEndingGlitch }, + { false, 124, "Win: GM Music signal checks", 4, kq5SignatureWinGMSignals, kq5PatchWinGMSignals }, SCI_SIGNATUREENTRY_TERMINATOR }; |