aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2017-07-17 22:29:07 -0500
committerColin Snover2017-07-17 22:42:18 -0500
commitafe344cc1f001bffc40f04f9b14f8af8b2c5349c (patch)
tree1365fbf45c132ce11045d3b23462f4ef485c3489 /engines
parent2528ecf26e0b3767aca53019262d0c133827ddbb (diff)
downloadscummvm-rg350-afe344cc1f001bffc40f04f9b14f8af8b2c5349c.tar.gz
scummvm-rg350-afe344cc1f001bffc40f04f9b14f8af8b2c5349c.tar.bz2
scummvm-rg350-afe344cc1f001bffc40f04f9b14f8af8b2c5349c.zip
SCI32: Add guest additions support for LSL7
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/features.cpp3
-rw-r--r--engines/sci/engine/guest_additions.cpp24
-rw-r--r--engines/sci/engine/script_patches.cpp120
-rw-r--r--engines/sci/engine/selector.cpp1
-rw-r--r--engines/sci/engine/selector.h1
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
};