From 13dd57d34f76004306d6105339622592236bcba9 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sat, 11 Feb 2017 04:17:31 +0000 Subject: DRASCULA: Fix sound volume synchronization When using the original drascula dialog to change volume, this was not saved to the ConfMan, which means the change was lost when quitting the engine or when opening the ScummVM options dialog. Also synchronising the _mixer volumes from ConfMan was resetting the master volume to the maximum. Since ScummVM doesn't have a master volume, there is no correct way to get it. But we now try to guess one from the music and speech volumes. --- engines/drascula/drascula.h | 2 ++ engines/drascula/sound.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h index e66220f9c6..5265324d91 100644 --- a/engines/drascula/drascula.h +++ b/engines/drascula/drascula.h @@ -325,6 +325,8 @@ public: virtual ~DrasculaEngine(); virtual bool hasFeature(EngineFeature f) const; + virtual void syncSoundSettings(); + Common::RandomSource *_rnd; const DrasculaGameDescription *_gameDescription; uint32 getFeatures() const; diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp index ef60bcc36a..70916caffe 100644 --- a/engines/drascula/sound.cpp +++ b/engines/drascula/sound.cpp @@ -34,6 +34,41 @@ namespace Drascula { +void DrasculaEngine::syncSoundSettings() { + // Sync the engine with the config manager + + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + // We need to handle the speech mute separately here. This is because the + // engine code should be able to rely on all speech sounds muted when the + // user specified subtitles only mode, which results in "speech_mute" to + // be set to "true". The global mute setting has precedence over the + // speech mute setting though. + bool speechMute = mute; + if (!speechMute) + speechMute = ConfMan.getBool("speech_mute"); + + _mixer->muteSoundType(Audio::Mixer::kPlainSoundType, mute); + _mixer->muteSoundType(Audio::Mixer::kSFXSoundType, mute); + _mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, speechMute); + _mixer->muteSoundType(Audio::Mixer::kMusicSoundType, mute); + + int voiceVolume = ConfMan.getInt("speech_volume"); + int musicVolume = ConfMan.getInt("music_volume"); + // If the music and voice volume are correct, don't change anything. + // Otherwise compute the master volume using an approximation of sqrt(max) * 16 which would result in the master + // volume being the same value as the max of music and voice. + if (_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) != voiceVolume || _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) != musicVolume) { + int masterVolume = MAX(musicVolume, voiceVolume) * 2 / 3 + 86; + _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, masterVolume); + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, voiceVolume); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, voiceVolume); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, musicVolume); + } +} + int DrasculaEngine::updateVolume(int prevVolume, int prevVolumeY) { prevVolumeY += 10; if (_mouseY < prevVolumeY && prevVolume < 15) @@ -112,9 +147,12 @@ void DrasculaEngine::volumeControls() { voiceVolume = (masterVolume + 1) * (voiceVolume + 1) - 1; _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, voiceVolume); _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, voiceVolume); + ConfMan.setInt("speech_volume", voiceVolume); + ConfMan.setInt("sfx_volume", voiceVolume); musicVolume = (masterVolume + 1) * (musicVolume + 1) - 1; _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, musicVolume); + ConfMan.setInt("music_volume", musicVolume); } } -- cgit v1.2.3