From a8b00b899261d0bf1a2d65298f4162f0b71de823 Mon Sep 17 00:00:00 2001 From: Thanasis Antoniou Date: Thu, 28 May 2020 15:54:26 +0300 Subject: [PATCH] SKY: Fix music volume not syncing with ConfMan For the case that the music volume is set via the native options menu (F5) --- engines/sky/control.cpp | 62 +++++++++++++++++++++++++++++------------ engines/sky/control.h | 15 ++++++---- engines/sky/sky.cpp | 20 +++++++++---- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp index 26d32a27bf4..ec8eac003f8 100644 --- a/engines/sky/control.cpp +++ b/engines/sky/control.cpp @@ -196,7 +196,8 @@ void ControlStatus::drawToScreen() { _statusText->drawToScreen(WITH_MASK); } -Control::Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap) { +Control::Control(SkyEngine *vm, Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap) { + _vm = vm; _saveFileMan = saveFileMan; _skyScreen = screen; @@ -226,25 +227,48 @@ ConResource *Control::createResource(void *pSpData, uint32 pNSprites, uint32 pCu } void Control::removePanel() { + // + // We sync sound settings when exiting the Panel + // TODO: There's still an edge case not addressed here + // for when the player opens the native menu (F5) + // and the ScummVM in-game menu on top of it. + // In that case, the eventual music volume + // will be the one set in the ScummVM UI + // + // Setting the music volume from native menu affects only music volume + // even though the native menu has no setting for SFX and Speech volume + // TODO: Was this the behavior in the original (DOS version)? + // + // SkyEngine native sound volume range is [0, 127] + // However, via ScummVM UI, the volume range can be set within [0, 256] + // so we "translate" between them + uint8 volume = _skyMusic->giveVolume(); + if (volume == 127) { // ensure mapping of max values + ConfMan.setInt("music_volume", 256); + } else { + ConfMan.setInt("music_volume", CLIP(volume << 1, 0, 256)); + } + _vm->syncSoundSettings(); + free(_screenBuf); - free(_sprites.controlPanel); free(_sprites.button); - free(_sprites.buttonDown); free(_sprites.savePanel); - free(_sprites.yesNo); free(_sprites.slide); - free(_sprites.slide2); free(_sprites.slode); - free(_sprites.slode2); free(_sprites.musicBodge); - delete _controlPanel; delete _exitButton; + free(_sprites.controlPanel); free(_sprites.button); + free(_sprites.buttonDown); free(_sprites.savePanel); + free(_sprites.yesNo); free(_sprites.slide); + free(_sprites.slide2); free(_sprites.slode); + free(_sprites.slode2); free(_sprites.musicBodge); + delete _controlPanel; delete _exitButton; _controlPanel = NULL; - delete _slide; delete _slide2; - delete _slode; delete _restorePanButton; - delete _savePanel; delete _saveButton; - delete _downFastButton; delete _downSlowButton; - delete _upFastButton; delete _upSlowButton; - delete _quitButton; delete _autoSaveButton; - delete _savePanButton; delete _dosPanButton; - delete _restartPanButton; delete _fxPanButton; - delete _musicPanButton; delete _bodge; - delete _yesNo; delete _text; - delete _statusBar; delete _restoreButton; + delete _slide; delete _slide2; + delete _slode; delete _restorePanButton; + delete _savePanel; delete _saveButton; + delete _downFastButton; delete _downSlowButton; + delete _upFastButton; delete _upSlowButton; + delete _quitButton; delete _autoSaveButton; + delete _savePanButton; delete _dosPanButton; + delete _restartPanButton; delete _fxPanButton; + delete _musicPanButton; delete _bodge; + delete _yesNo; delete _text; + delete _statusBar; delete _restoreButton; if (_textSprite) { free(_textSprite); @@ -695,6 +719,8 @@ uint16 Control::doMusicSlide() { if (volume >= 128) volume = 0; else volume = 127 - volume; _skyMusic->setVolume(volume); + // we don't sync here with ConfMan to avoid numerous redundant I/O. + // we sync in removePanel() } buttonControl(_slide2); _text->drawToScreen(WITH_MASK); diff --git a/engines/sky/control.h b/engines/sky/control.h index eb69fe5cd33..217fde092b5 100644 --- a/engines/sky/control.h +++ b/engines/sky/control.h @@ -43,15 +43,16 @@ class Text; class MusicBase; class Sound; class SkyCompact; +class SkyEngine; struct Compact; struct DataFileHeader; struct MegaSet; -#define MAX_SAVE_GAMES 999 -#define MAX_TEXT_LEN 80 -#define PAN_LINE_WIDTH 184 -#define PAN_CHAR_HEIGHT 12 -#define STATUS_WIDTH 146 +#define MAX_SAVE_GAMES 999 +#define MAX_TEXT_LEN 80 +#define PAN_LINE_WIDTH 184 +#define PAN_CHAR_HEIGHT 12 +#define STATUS_WIDTH 146 #define MPNL_X 60 // Main Panel #define MPNL_Y 10 @@ -180,7 +181,7 @@ private: class Control { public: - Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap); + Control(SkyEngine *vm, Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap); void doControlPanel(); void doLoadSavePanel(); void restartGame(); @@ -188,6 +189,8 @@ public: uint16 quickXRestore(uint16 slot); bool loadSaveAllowed(); + SkyEngine *_vm; + uint16 _selectedGame; uint16 saveGameToFile(bool fromControlPanel, const char *filename = 0, bool isAutosave = false); diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index af992eb8d91..cbf02e49cc4 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -102,13 +102,19 @@ void SkyEngine::syncSoundSettings() { if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); - if (ConfMan.getBool("sfx_mute")) + if (ConfMan.getBool("sfx_mute")) // set mute sfx status for native options menu (F5) SkyEngine::_systemVars.systemFlags |= SF_FX_OFF; - if (ConfMan.getBool("music_mute")) + if (ConfMan.getBool("music_mute")) { // CD version allows to mute music from native options menu (F5) SkyEngine::_systemVars.systemFlags |= SF_MUS_OFF; + } + // SkyEngine native sound volume range is [0, 127] + // However, via ScummVM UI, the volume range can be set within [0, 256] + // so we "translate" between them + _skyMusic->setVolume(mute ? 0: CLIP(ConfMan.getInt("music_volume") >> 1, 0, 127)); - _skyMusic->setVolume(mute ? 0: ConfMan.getInt("music_volume") >> 1); + // write-back to ini file for persistence + ConfMan.flushToDisk(); } void SkyEngine::initVirgin() { @@ -294,7 +300,7 @@ Common::Error SkyEngine::init() { Common::Keymap *shortcutsKeymap = keymapper->getKeymap(shortcutsKeymapId); assert(shortcutsKeymap); - _skyControl = new Control(_saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system, shortcutsKeymap); + _skyControl = new Control(this, _saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system, shortcutsKeymap); _skyLogic->useControlInstance(_skyControl); switch (Common::parseLanguage(ConfMan.get("language"))) { @@ -341,7 +347,11 @@ Common::Error SkyEngine::init() { } } - // Setup mixer + // Setup mixer: Default volume is set to 127 (the game engine's max volume) + ConfMan.registerDefault("sfx_volume", 127); + ConfMan.registerDefault("music_volume", 127); + ConfMan.registerDefault("speech_volume", 127); + ConfMan.registerDefault("mute", "false"); syncSoundSettings(); _debugger = new Debugger(_skyLogic, _skyMouse, _skyScreen, _skyCompact);