diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/features.cpp | 3 | ||||
-rw-r--r-- | engines/sci/engine/guest_additions.cpp | 24 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 120 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 1 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 1 |
5 files changed, 122 insertions, 27 deletions
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index bddcac920a..e64cf9cf9f 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -556,6 +556,7 @@ bool GameFeatures::supportsSpeechWithSubtitles() const { case GID_GK1: case GID_KQ7: case GID_LSL6HIRES: + case GID_LSL7: case GID_PQ4: case GID_QFG4: case GID_SQ6: @@ -573,6 +574,7 @@ bool GameFeatures::audioVolumeSyncUsesGlobals() const { case GID_GK1: case GID_GK2: case GID_LSL6HIRES: + case GID_LSL7: case GID_PHANTASMAGORIA: case GID_TORIN: // TODO: SCI3 @@ -600,6 +602,7 @@ MessageTypeSyncStrategy GameFeatures::getMessageTypeSyncStrategy() const { return g_sci->isCD() ? kMessageTypeSyncStrategyDefault : kMessageTypeSyncStrategyNone; case GID_KQ7: + case GID_LSL7: case GID_MOTHERGOOSEHIRES: case GID_PHANTASMAGORIA: case GID_SQ6: diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp index 873152b329..2cfed136aa 100644 --- a/engines/sci/engine/guest_additions.cpp +++ b/engines/sci/engine/guest_additions.cpp @@ -141,9 +141,9 @@ bool GuestAdditions::shouldSyncAudioToScummVM() const { objName == "dacVolDown" || objName == "dacVolUp")) { return true; - } else if (gameId == GID_TORIN && (objName == "oMusicScroll" || - objName == "oSFXScroll" || - objName == "oAudioScroll")) { + } else if ((gameId == GID_LSL7 || gameId == GID_TORIN) && (objName == "oMusicScroll" || + objName == "oSFXScroll" || + objName == "oAudioScroll")) { return true; #endif } @@ -227,7 +227,9 @@ void GuestAdditions::instantiateScriptHook(Script &script, const bool ignoreDela return; } - if (g_sci->getGameId() == GID_TORIN && script.getScriptNumber() == 64866) { + if ((g_sci->getGameId() == GID_LSL7 || g_sci->getGameId() == GID_TORIN) && + script.getScriptNumber() == 64866) { + patchGameSaveRestoreTorin(script); } else if (script.getScriptNumber() == 64990) { // 64990 is the system script containing SRDialog. This script is used @@ -381,9 +383,9 @@ void GuestAdditions::patchGameSaveRestoreSCI32(Script &script) const { } static const byte SRTorinPatch[] = { - 0x38, 0x8d, 0x00, // pushi $8d (new) + 0x38, 0xFF, 0xFF, // pushi new 0x76, // push0 - 0x51, 0x0f, // class $f (Str) + 0x51, 0x0f, // class Str 0x4a, 0x04, 0x00, // send 4 0xa3, 0x01, // sal 1 0x76, // push0 @@ -396,6 +398,12 @@ void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const { const uint32 address = script.validateExportFunc(2, true); byte *patchPtr = const_cast<byte *>(script.getBuf(address)); memcpy(patchPtr, SRTorinPatch, sizeof(SRTorinPatch)); + + const Selector newSelector = SELECTOR(new_); + assert(newSelector != -1); + patchPtr[1] = newSelector & 0xFF; + patchPtr[2] = (newSelector >> 8) & 0xFF; + if (g_sci->isBE()) { SWAP(patchPtr[1], patchPtr[2]); SWAP(patchPtr[8], patchPtr[9]); @@ -403,7 +411,7 @@ void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const { } reg_t GuestAdditions::kScummVMSaveLoad(EngineState *s, int argc, reg_t *argv) const { - if (g_sci->getGameId() == GID_TORIN) { + if (g_sci->getGameId() == GID_LSL7 || g_sci->getGameId() == GID_TORIN) { return promptSaveRestoreTorin(s, argc, argv); } @@ -811,6 +819,7 @@ void GuestAdditions::syncAudioVolumeGlobalsFromScummVM() const { break; } + case GID_LSL7: case GID_TORIN: { const int16 musicVolume = (ConfMan.getInt("music_volume") + 1) * 100 / Audio::Mixer::kMaxMixerVolume; const int16 sfxVolume = (ConfMan.getInt("sfx_volume") + 1) * 100 / Audio::Mixer::kMaxMixerVolume; @@ -960,6 +969,7 @@ void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_ } break; + case GID_LSL7: case GID_TORIN: if (index == kGlobalVarTorinMusicVolume || index == kGlobalVarTorinSFXVolume || diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 8c000dda74..6dcdaac550 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -262,6 +262,22 @@ static const uint16 sci2BenchmarkPatch[] = { PATCH_END }; +// Torin/LSL7-specific version of sci2NumSavesSignature1/2 +// Applies to at least: English CD +static const uint16 torinNumSavesSignature[] = { + SIG_MAGICDWORD, + 0x36, // push + 0x35, 0x14, // ldi 20 + 0x20, // ge? + SIG_END +}; + +static const uint16 torinNumSavesPatch[] = { + PATCH_ADDTOOFFSET(+1), // push + 0x35, 0x63, // ldi 99 + PATCH_END +}; + #endif // =========================================================================== @@ -2565,6 +2581,61 @@ static const SciScriptPatcherEntry larry6HiresSignatures[] = { #pragma mark - #pragma mark Leisure Suit Larry 7 +// The init code that runs when LSL7 starts up unconditionally resets the audio +// volumes to defaults, but the game should always use the volume stored in +// ScummVM. This patch is basically identical to the patch for Torin, except +// that they left line numbers in the LSL7 scripts and changed the music volume. +// Applies to at least: English CD +static const uint16 larry7VolumeResetSignature1[] = { + SIG_MAGICDWORD, + 0x35, 0x41, // ldi $41 + 0xa1, 0xe3, // sag $e3 (music volume) + 0x7e, SIG_ADDTOOFFSET(2), // line whatever + 0x35, 0x3c, // ldi $3c + 0xa1, 0xe4, // sag $e4 (sfx volume) + 0x7e, SIG_ADDTOOFFSET(2), // line whatever + 0x35, 0x64, // ldi $64 + 0xa1, 0xe5, // sag $e5 (speech volume) + SIG_END +}; + +static const uint16 larry7VolumeResetPatch1[] = { + 0x33, 0x10, // jmp [past volume resets] + PATCH_END +}; + +// The init code that runs when LSL7 starts up unconditionally resets the +// audio volumes to values stored in larry7.prf, but the game should always use +// the volume stored in ScummVM. This patch is basically identical to the patch +// for Torin, except that they left line numbers in the LSL7 scripts. +// Applies to at least: English CD +static const uint16 larry7VolumeResetSignature2[] = { + SIG_MAGICDWORD, + 0x38, SIG_UINT16(0x19d), // pushi readWord + 0x76, // push0 + SIG_ADDTOOFFSET(6), // advance file stream + 0xa1, 0xe3, // sag $e3 (music volume) + SIG_ADDTOOFFSET(3), // line whatever + SIG_ADDTOOFFSET(10), // advance file stream + 0xa1, 0xe4, // sag $e4 (sfx volume) + SIG_ADDTOOFFSET(3), // line whatever + SIG_ADDTOOFFSET(10), // advance file stream + 0xa1, 0xe5, // sag $e5 (speech volume) + SIG_END +}; + +static const uint16 larry7VolumeResetPatch2[] = { + PATCH_ADDTOOFFSET(10), // advance file stream + 0x18, 0x18, // waste bytes + PATCH_ADDTOOFFSET(3), // line whatever + PATCH_ADDTOOFFSET(10), // advance file stream + 0x18, 0x18, // waste bytes + PATCH_ADDTOOFFSET(3), // line whatever + PATCH_ADDTOOFFSET(10), // advance file stream + 0x18, 0x18, // waste bytes + PATCH_END +}; + // =========================================================================== // 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. @@ -2628,10 +2699,33 @@ static const uint16 larry7PatchMakeCheesePriority[] = { PATCH_END }; +// LSL7 tries to reset the message type twice at startup, first with a default +// value in script 0, then with a stored value from larry7.prf (if that file +// exists) or the same default value (if it does not) in script 64000. Since +// message type sync relies on the game only setting this value once at startup, +// we must stop the second attempt or the value from ScummVM will be +// overwritten. +// Applies to at least: English CD +static const uint16 larry7MessageTypeResetSignature[] = { + SIG_MAGICDWORD, + 0x35, 0x02, // ldi 2 + 0xa1, 0x5a, // sag $5a + SIG_END +}; + +static const uint16 larry7MessageTypeResetPatch[] = { + 0x33, 0x02, // jmp [past reset] + PATCH_END +}; + // script, description, signature patch static const SciScriptPatcherEntry larry7Signatures[] = { + { true, 0, "disable message type reset on startup", 1, larry7MessageTypeResetSignature, larry7MessageTypeResetPatch }, { true, 540, "fix make cheese cutscene (cycler)", 1, larry7SignatureMakeCheese, larry7PatchMakeCheese }, { true, 540, "fix make cheese cutscene (priority)", 1, larry7SignatureMakeCheesePriority, larry7PatchMakeCheesePriority }, + { true, 64000, "disable volume reset on startup 1/2", 1, larry7VolumeResetSignature1, larry7VolumeResetPatch1 }, + { true, 64000, "disable volume reset on startup 2/2", 1, larry7VolumeResetSignature2, larry7VolumeResetPatch2 }, + { true, 64866, "increase number of save games", 1, torinNumSavesSignature, torinNumSavesPatch }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -5652,8 +5746,9 @@ static const SciScriptPatcherEntry sq6Signatures[] = { #pragma mark Torins Passage // The init code that runs when Torin starts up unconditionally resets the -// master music volume to defaults, but the game should always use the volume -// stored in ScummVM. +// audio volumes to defaults, but the game should always use the volume stored +// in ScummVM. This patch is basically identical to the patch for LSL7, except +// that they left line numbers in the LSL7 scripts and changed the music volume. // Applies to at least: English CD static const uint16 torinVolumeResetSignature1[] = { SIG_MAGICDWORD, @@ -5672,8 +5767,9 @@ static const uint16 torinVolumeResetPatch1[] = { }; // The init code that runs when Torin starts up unconditionally resets the -// master music volume to values stored in torin.prf, but the game should always -// use the volume stored in ScummVM. +// audio volumes to values stored in torin.prf, but the game should always use +// the volume stored in ScummVM. This patch is basically identical to the patch +// for LSL7, except that they left line numbers in the LSL7 scripts. // Applies to at least: English CD static const uint16 torinVolumeResetSignature2[] = { SIG_MAGICDWORD, @@ -5698,22 +5794,6 @@ static const uint16 torinVolumeResetPatch2[] = { PATCH_END }; -// Torin-specific version of sci2NumSavesSignature1/2 -// Applies to at least: English CD -static const uint16 torinNumSavesSignature[] = { - SIG_MAGICDWORD, - 0x36, // push - 0x35, 0x14, // ldi 20 - 0x20, // ge? - SIG_END -}; - -static const uint16 torinNumSavesPatch[] = { - PATCH_ADDTOOFFSET(+1), // push - 0x35, 0x63, // ldi 99 - PATCH_END -}; - // In Escarpa, it is possible for Boogle to be left outside of Torin's bag // when fast-forwarding through the exit animation of the seraglio. If this // happens, when the player goes from the seraglio to the dragon's cave and then diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index e28ae799c6..9c6921b181 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -217,6 +217,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(setPos); FIND_SELECTOR(setSize); FIND_SELECTOR(displayValue); + FIND_SELECTOR2(new_, "new"); #endif } diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index 1db9e4bec4..d97a8832c0 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -174,6 +174,7 @@ struct SelectorCache { Selector setPos; // for Torin volume sync Selector setSize; // for PQ4 volume sync Selector displayValue; // for PQ:SWAT volume sync + Selector new_; // for Torin/LSL7 save/load patching #endif }; |