diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/guest_additions.cpp | 25 | ||||
-rw-r--r-- | engines/sci/engine/guest_additions.h | 15 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 27 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 7 | ||||
-rw-r--r-- | engines/sci/sound/audio32.cpp | 11 |
5 files changed, 67 insertions, 18 deletions
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp index 0452cc2850..90d797aee9 100644 --- a/engines/sci/engine/guest_additions.cpp +++ b/engines/sci/engine/guest_additions.cpp @@ -50,12 +50,6 @@ enum { kMessageTypeSpeech = 2 }; -enum { - kLSL6HiresUIVolumeMax = 13, - kLSL6HiresSubtitleFlag = 105 -}; - - GuestAdditions::GuestAdditions(EngineState *state, GameFeatures *features, Kernel *kernel) : _state(state), _features(features), @@ -912,7 +906,7 @@ void GuestAdditions::syncAudioVolumeGlobalsFromScummVM() const { } case GID_PHANTASMAGORIA2: { - const int16 masterVolume = (ConfMan.getInt("sfx_volume") + 1) * Audio32::kMaxVolume / Audio::Mixer::kMaxMixerVolume; + const int16 masterVolume = (ConfMan.getInt("sfx_volume") + 1) * kPhant2VolumeMax / Audio::Mixer::kMaxMixerVolume; syncPhant2VolumeFromScummVM(masterVolume); syncPhant2UI(masterVolume); break; @@ -1016,12 +1010,13 @@ void GuestAdditions::syncLSL6HiresVolumeFromScummVM(const int16 musicVolume) con g_sci->_soundCmd->setMasterVolume(ConfMan.getBool("mute") ? 0 : (musicVolume * MUSIC_MASTERVOLUME_MAX / kLSL6HiresUIVolumeMax)); } -void GuestAdditions::syncPhant2VolumeFromScummVM(const int16 musicVolume) const { - _state->variables[VAR_GLOBAL][kGlobalVarPhant2MasterVolume] = make_reg(0, musicVolume); +void GuestAdditions::syncPhant2VolumeFromScummVM(const int16 masterVolume) const { + _state->variables[VAR_GLOBAL][kGlobalVarPhant2MasterVolume] = make_reg(0, masterVolume); + _state->variables[VAR_GLOBAL][kGlobalVarPhant2SecondaryVolume] = make_reg(0, masterVolume); const reg_t soundsId = _state->variables[VAR_GLOBAL][kGlobalVarSounds]; if (!soundsId.isNull()) { - reg_t params[] = { make_reg(0, SELECTOR(setVol)), make_reg(0, musicVolume) }; + reg_t params[] = { make_reg(0, SELECTOR(setVol)), make_reg(0, masterVolume) }; invokeSelector(soundsId, SELECTOR(eachElementDo), 2, params); } } @@ -1080,7 +1075,7 @@ void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_ case GID_PHANTASMAGORIA2: if (index == kGlobalVarPhant2MasterVolume) { - const int16 masterVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume; + const int16 masterVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / kPhant2VolumeMax; ConfMan.setInt("music_volume", masterVolume); ConfMan.setInt("sfx_volume", masterVolume); ConfMan.setInt("speech_volume", masterVolume); @@ -1247,18 +1242,18 @@ void GuestAdditions::syncPhant1UI(const int16 oldMusicVolume, const int16 musicV } } -void GuestAdditions::syncPhant2UI(const int16 musicVolume) const { - const reg_t musicVolumeScript = _segMan->findObjectByName("foo2"); +void GuestAdditions::syncPhant2UI(const int16 masterVolume) const { + const reg_t masterVolumeScript = _segMan->findObjectByName("foo2"); Common::Array<reg_t> scrollBars = _segMan->findObjectsByName("P2ScrollBar"); for (uint i = 0; i < scrollBars.size(); ++i) { - if (readSelector(_segMan, scrollBars[i], SELECTOR(client)) == musicVolumeScript) { + if (readSelector(_segMan, scrollBars[i], SELECTOR(client)) == masterVolumeScript) { // P2ScrollBar objects may exist without actually being on-screen; // the easiest way to tell seems to be to look to see if it has // non-null pointers to subviews. (The game will correctly set the // position of the scrollbar when it first becomes visible, so this // is fine.) if (!readSelector(_segMan, scrollBars[i], SELECTOR(physicalBar)).isNull()) { - reg_t params[] = { make_reg(0, musicVolume), make_reg(0, 1) }; + reg_t params[] = { make_reg(0, masterVolume), make_reg(0, 1) }; invokeSelector(scrollBars[i], SELECTOR(move), 2, params); break; } diff --git a/engines/sci/engine/guest_additions.h b/engines/sci/engine/guest_additions.h index 7c80c29aac..64bd667414 100644 --- a/engines/sci/engine/guest_additions.h +++ b/engines/sci/engine/guest_additions.h @@ -33,6 +33,21 @@ class Kernel; class Script; class SegManager; +#ifdef ENABLE_SCI32 +enum { + // The in-game volumes for Phant2 use a volume range smaller than the + // actual master volume because movie volume needs to be controllable from + // the normal ScummVM launcher volume controls, but movie dialogue cannot be + // heard if the game audio is at the same level as movies. The game normally + // sets defaults so that the in-game volume is 85 and movies are 127, so we + // will just use 85 as the maximum volume. + kPhant2VolumeMax = 85, + + kLSL6HiresUIVolumeMax = 13, + kLSL6HiresSubtitleFlag = 105 +}; +#endif + /** * The GuestAdditions class hooks into the SCI virtual machine to provide * enhanced interactions between the ScummVM GUI and the game engine. Currently, diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 443920128b..e8458480e7 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -26,6 +26,9 @@ #include "sci/engine/state.h" #include "sci/engine/features.h" #include "sci/engine/script_patches.h" +#ifdef ENABLE_SCI32 +#include "sci/engine/guest_additions.h" +#endif #include "common/util.h" @@ -3879,6 +3882,29 @@ static const uint16 phant2RatboyPatch[] = { PATCH_END }; +// Phant2 has separate in-game volume controls for handling movie volume and +// in-game volume (misleading labelled "music volume"), but really needs the +// in-game volume to always be significantly lower than the movie volume in +// order for dialogue in movies to be consistently audible, so patch the in-game +// volume slider to limit it to our maximum. +// Applies to at least: US English +static const uint16 phant2AudioVolumeSignature[] = { + SIG_MAGICDWORD, + 0x39, 0x7f, // pushi 127 (clientMax) + 0x39, 0x14, // pushi 20 (clientPageSize) + SIG_ADDTOOFFSET(+10), // skip other init arguments + 0x51, 0x5e, // class P2ScrollBar + SIG_ADDTOOFFSET(+3), // skip send + 0xa3, 0x06, // sal 6 (identifies correct slider) + SIG_END +}; + +static const uint16 phant2AudioVolumePatch[] = { + 0x39, kPhant2VolumeMax, // pushi (our custom volume max) + 0x39, 0x14 * kPhant2VolumeMax / 127, // pushi (ratio of original value) + PATCH_END +}; + // When censorship is disabled the game sticks <PROTECTED> at the end of every // save game name, and when it is enabled it pads the save game name with a // bunch of spaces. This is annoying and not helpful, so just disable all of @@ -3945,6 +3971,7 @@ static const SciScriptPatcherEntry phantasmagoria2Signatures[] = { { true, 0, "slow interface fades", 3, phant2SlowIFadeSignature, phant2SlowIFadePatch }, { true, 0, "bad arguments to get game version", 1, phant2GetVersionSignature, phant2GetVersionPatch }, { true, 4081, "non-responsive mouse after ratboy puzzle", 1, phant2RatboySignature, phant2RatboyPatch }, + { true, 63004, "limit in-game audio volume", 1, phant2AudioVolumeSignature, phant2AudioVolumePatch }, { true, 63016, "non-responsive mouse during music fades", 1, phant2Wait4FadeSignature, phant2Wait4FadePatch }, { true, 63019, "non-responsive mouse during computer load", 1, phant2CompSlideDoorsSignature, phant2CompSlideDoorsPatch }, { true, 64990, "remove save game name mangling (1/2)", 1, phant2SaveNameSignature1, phant2SaveNamePatch1 }, diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 67729bfbf9..792287ba53 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -149,9 +149,10 @@ enum GlobalVar { kGlobalVarNewRoomNo = 13, kGlobalVarScore = 15, kGlobalVarGK2MusicVolume = 76, // 0 to 127 - kGlobalVarFastCast = 84, // SCI16 - kGlobalVarMessageType = 90, - kGlobalVarTextSpeed = 94, // SCI32; 0 is fastest, 8 is slowest + kGlobalVarPhant2SecondaryVolume = 76, // 0 to 127 + kGlobalVarFastCast = 84, // SCI16 + kGlobalVarMessageType = 90, + kGlobalVarTextSpeed = 94, // SCI32; 0 is fastest, 8 is slowest kGlobalVarGK1Music1 = 102, // 0 to 127 kGlobalVarGK1Music2 = 103, // 0 to 127 kGlobalVarLSL6HiresGameFlags = 137, diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp index c3f9eb4098..ad9af4ebf6 100644 --- a/engines/sci/sound/audio32.cpp +++ b/engines/sci/sound/audio32.cpp @@ -359,6 +359,17 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples) } else if (volume > 84 && volume < kMaxVolume) { volume = 63; } + } else if (getSciVersion() == SCI_VERSION_3 && volume != kMaxVolume) { + // In SCI3, granularity of the non-maximum volumes is 1/32 + volume &= ~4; + + // NOTE: In the SSCI DOS interpreter, non-maximum volumes are + // divided by 8 which puts them in a range of [0, 16). That + // reduced volume range gets passed into a volume function which + // expects values [0, 32). So, effectively, all non-maximum + // volumes are half-volume in DOS in SCI3. In Windows, volumes + // [120, 124) are the same as 127 due to a programming bug. + // We do not emulate either of these incorrect behaviors. } leftVolume = rightVolume = volume * Audio::Mixer::kMaxChannelVolume / kMaxVolume; |