diff --git a/base/main.cpp b/base/main.cpp index 8ab43d0e12c..063da86bd3c 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -185,10 +185,7 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common // Set default values for all of the custom engine options // Apparently some engines query them in their constructor, thus we // need to set this up before instance creation. - const ExtraGuiOptions engineOptions = metaEngine.getExtraGuiOptions(Common::String()); - for (uint i = 0; i < engineOptions.size(); i++) { - ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState); - } + metaEngine.registerDefaultSettings(target); err = metaEngine.createInstance(&system, &engine); } diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index aaf30c8abf5..cc22223d9fe 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -358,4 +358,59 @@ void ConfigDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 } } +ExtraGuiOptionsWidget::ExtraGuiOptionsWidget(GuiObject *containerBoss, const Common::String &name, const Common::String &domain, const ExtraGuiOptions &options) : + OptionsContainerWidget(containerBoss, name, dialogLayout(domain), false, domain), + _options(options) { + + // Note: up to 7 engine options can currently fit on screen (the most that + // can fit in a 320x200 screen with the classic theme). + // TODO: Increase this number by including the checkboxes inside a scroll + // widget. The appropriate number of checkboxes will need to be added to + // the theme files. + + uint i = 1; + ExtraGuiOptions::const_iterator iter; + for (iter = _options.begin(); iter != _options.end(); ++iter, ++i) { + Common::String id = Common::String::format("%d", i); + _checkboxes.push_back(new CheckboxWidget(widgetsBoss(), + _dialogLayout + ".customOption" + id + "Checkbox", _(iter->label), _(iter->tooltip))); + } +} + +ExtraGuiOptionsWidget::~ExtraGuiOptionsWidget() { +} + +Common::String ExtraGuiOptionsWidget::dialogLayout(const Common::String &domain) { + if (ConfMan.getActiveDomainName().equals(domain)) { + return "GlobalConfig_Engine_Container"; + } else { + return "GameOptions_Engine_Container"; + } +} + +void ExtraGuiOptionsWidget::load() { + // Set the state of engine-specific checkboxes + for (uint j = 0; j < _options.size(); ++j) { + // The default values for engine-specific checkboxes are not set when + // ScummVM starts, as this would require us to load and poll all of the + // engine plugins on startup. Thus, we set the state of each custom + // option checkbox to what is specified by the engine plugin, and + // update it only if a value has been set in the configuration of the + // currently selected game. + bool isChecked = _options[j].defaultState; + if (ConfMan.hasKey(_options[j].configOption, _domain)) + isChecked = ConfMan.getBool(_options[j].configOption, _domain); + _checkboxes[j]->setState(isChecked); + } +} + +bool ExtraGuiOptionsWidget::save() { + // Set the state of engine-specific checkboxes + for (uint i = 0; i < _options.size(); i++) { + ConfMan.setBool(_options[i].configOption, _checkboxes[i]->getState(), _domain); + } + + return true; +} + } // End of namespace GUI diff --git a/engines/dialogs.h b/engines/dialogs.h index cfe3349f28d..85105854f54 100644 --- a/engines/dialogs.h +++ b/engines/dialogs.h @@ -25,6 +25,7 @@ #include "gui/dialog.h" #include "gui/options.h" +#include "gui/widget.h" class Engine; @@ -95,6 +96,24 @@ public: void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override; }; +class ExtraGuiOptionsWidget : public OptionsContainerWidget { +public: + ExtraGuiOptionsWidget(GuiObject *widgetsBoss, const Common::String &name, const Common::String &domain, const ExtraGuiOptions &options); + ~ExtraGuiOptionsWidget() override; + + // OptionsContainerWidget API + void load() override; + bool save() override; + +private: + typedef Common::Array CheckboxWidgetList; + + static Common::String dialogLayout(const Common::String &domain); + + ExtraGuiOptions _options; + CheckboxWidgetList _checkboxes; +}; + } // End of namespace GUI #endif diff --git a/engines/metaengine.cpp b/engines/metaengine.cpp index 02275308e57..a46faf29e45 100644 --- a/engines/metaengine.cpp +++ b/engines/metaengine.cpp @@ -30,6 +30,8 @@ #include "common/system.h" #include "common/translation.h" +#include "engines/dialogs.h" + #include "graphics/palette.h" #include "graphics/scaler.h" #include "graphics/managed_surface.h" @@ -336,6 +338,21 @@ SaveStateList MetaEngine::listSaves(const char *target, bool saveMode) const { return saveList; } +void MetaEngine::registerDefaultSettings(const Common::String &target) const { + const ExtraGuiOptions engineOptions = getExtraGuiOptions(target); + for (uint i = 0; i < engineOptions.size(); i++) { + ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState); + } +} + +GUI::OptionsContainerWidget *MetaEngine::buildEngineOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const { + const ExtraGuiOptions engineOptions = getExtraGuiOptions(target); + if (engineOptions.empty()) { + return nullptr; + } + + return new GUI::ExtraGuiOptionsWidget(boss, name, target, engineOptions); +} void MetaEngine::removeSaveState(const char *target, int slot) const { if (!hasFeature(kSavesUseExtendedFormat)) diff --git a/engines/metaengine.h b/engines/metaengine.h index 5f5c2b8c1c9..5775a67c6ac 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -48,6 +48,11 @@ namespace Graphics { struct Surface; } +namespace GUI { +class GuiObject; +class OptionsContainerWidget; +} + /** * Per-game extra GUI options structure. * Currently, this can only be used for options with checkboxes. @@ -190,6 +195,30 @@ public: return ExtraGuiOptions(); } + /** + * Register the default values for the settings the engine uses into the + * configuration manager. + * + * @param target name of a config manager target + */ + virtual void registerDefaultSettings(const Common::String &target) const; + + /** + * Return a GUI widget container for configuring the specified target options. + * + * The returned widget is shown in the Engine tab in the edit game dialog. + * Engines can build custom options dialogs, but by default a simple widget + * allowing to configure the extra GUI options is used. + * + * Engines that don't want to have an Engine tab in the edit game dialog + * can return nullptr. + * + * @param boss the widget / dialog the returned widget is a child of + * @param name the name the returned widget must use + * @param target name of a config manager target + */ + virtual GUI::OptionsContainerWidget *buildEngineOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const; + /** * Return the maximum save slot that the engine supports. * diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index fd71734debf..a852bfcbe11 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -37,7 +37,7 @@ #include "graphics/pixelformat.h" -#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.35" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.36" class OSystem; diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 8ca61a676e9..1cea4a6f81c 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -358,6 +358,10 @@ void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { case kCloseCmd: close(); break; + case kCloseWithResultCmd: + setResult(data); + close(); + break; default: break; } diff --git a/gui/dialog.h b/gui/dialog.h index eac99746eea..bd9fb36f4e0 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -42,8 +42,9 @@ class Widget; // Some "common" commands sent to handleCommand() enum { - kCloseCmd = 'clos', - kOKCmd = 'ok ' + kCloseWithResultCmd = 'clsr', + kCloseCmd = 'clos', + kOKCmd = 'ok ' }; class Dialog : public GuiObject { diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp index a141fa105cc..2aa6ec3d86a 100644 --- a/gui/editgamedialog.cpp +++ b/gui/editgamedialog.cpp @@ -105,15 +105,13 @@ EditGameDialog::EditGameDialog(const String &domain) : OptionsDialog(domain, "GameOptions") { EngineMan.upgradeTargetIfNecessary(domain); - // Retrieve all game specific options. + _engineOptions = nullptr; // Retrieve the plugin, since we need to access the engine's MetaEngine // implementation. const Plugin *plugin = nullptr; QualifiedGameDescriptor qgd = EngineMan.findTarget(domain, &plugin); - if (plugin) { - _engineOptions = plugin->get().getExtraGuiOptions(domain); - } else { + if (!plugin) { warning("Plugin for target \"%s\" not found! Game specific settings might be missing", domain.c_str()); } @@ -175,12 +173,21 @@ EditGameDialog::EditGameDialog(const String &domain) } // - // 2) The engine tab (shown only if there are custom engine options) + // 2) The engine tab (shown only if the engine implements one or there are custom engine options) // - if (_engineOptions.size() > 0) { - tab->addTab(_("Engine"), "GameOptions_Engine"); - addEngineControls(tab, "GameOptions_Engine.", _engineOptions); + if (plugin) { + int tabId = tab->addTab(_("Engine"), "GameOptions_Engine"); + + const MetaEngine &metaEngine = plugin->get(); + metaEngine.registerDefaultSettings(_domain); + _engineOptions = metaEngine.buildEngineOptionsWidget(tab, "GameOptions_Engine.Container", _domain); + + if (_engineOptions) { + _engineOptions->setParentDialog(this); + } else { + tab->removeTab(tabId); + } } // @@ -404,18 +411,8 @@ void EditGameDialog::open() { _langPopUp->setEnabled(false); } - // Set the state of engine-specific checkboxes - for (uint j = 0; j < _engineOptions.size(); ++j) { - // The default values for engine-specific checkboxes are not set when - // ScummVM starts, as this would require us to load and poll all of the - // engine plugins on startup. Thus, we set the state of each custom - // option checkbox to what is specified by the engine plugin, and - // update it only if a value has been set in the configuration of the - // currently selected game. - bool isChecked = _engineOptions[j].defaultState; - if (ConfMan.hasKey(_engineOptions[j].configOption, _domain)) - isChecked = ConfMan.getBool(_engineOptions[j].configOption, _domain); - _engineCheckboxes[j]->setState(isChecked); + if (_engineOptions) { + _engineOptions->load(); } const Common::PlatformDescription *p = Common::g_platforms; @@ -459,9 +456,8 @@ void EditGameDialog::apply() { else ConfMan.set("platform", Common::getPlatformCode(platform), _domain); - // Set the state of engine-specific checkboxes - for (uint i = 0; i < _engineOptions.size(); i++) { - ConfMan.setBool(_engineOptions[i].configOption, _engineCheckboxes[i]->getState(), _domain); + if (_engineOptions) { + _engineOptions->save(); } OptionsDialog::apply(); diff --git a/gui/editgamedialog.h b/gui/editgamedialog.h index 8832865e512..47df4c64780 100644 --- a/gui/editgamedialog.h +++ b/gui/editgamedialog.h @@ -26,6 +26,7 @@ #include "engines/game.h" #include "gui/dialog.h" #include "gui/options.h" +#include "gui/widget.h" namespace GUI { @@ -90,7 +91,7 @@ protected: CheckboxWidget *_globalMT32Override; CheckboxWidget *_globalVolumeOverride; - ExtraGuiOptions _engineOptions; + OptionsContainerWidget *_engineOptions; }; } // End of namespace GUI diff --git a/gui/options.cpp b/gui/options.cpp index 8e62b71d06f..7ce11c557cf 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -269,7 +269,7 @@ void OptionsDialog::build() { // Keymapper options if (_keymapperWidget) { - _keymapperWidget->build(); + _keymapperWidget->load(); } // Graphic options @@ -1404,22 +1404,6 @@ void OptionsDialog::addVolumeControls(GuiObject *boss, const Common::String &pre _enableVolumeSettings = true; } -void OptionsDialog::addEngineControls(GuiObject *boss, const Common::String &prefix, const ExtraGuiOptions &engineOptions) { - // Note: up to 7 engine options can currently fit on screen (the most that - // can fit in a 320x200 screen with the classic theme). - // TODO: Increase this number by including the checkboxes inside a scroll - // widget. The appropriate number of checkboxes will need to be added to - // the theme files. - - uint i = 1; - ExtraGuiOptions::const_iterator iter; - for (iter = engineOptions.begin(); iter != engineOptions.end(); ++iter, ++i) { - Common::String id = Common::String::format("%d", i); - _engineCheckboxes.push_back(new CheckboxWidget(boss, - prefix + "customOption" + id + "Checkbox", _(iter->label), _(iter->tooltip))); - } -} - bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MusicType preferredType) { if (!popup || !popup->isEnabled()) return true; diff --git a/gui/options.h b/gui/options.h index 2ec441df3e8..0d97bd7a9dc 100644 --- a/gui/options.h +++ b/gui/options.h @@ -61,8 +61,6 @@ class RadiobuttonGroup; class RadiobuttonWidget; class OptionsDialog : public Dialog { - typedef Common::Array CheckboxWidgetList; - public: OptionsDialog(const Common::String &domain, int x, int y, int w, int h); OptionsDialog(const Common::String &domain, const Common::String &name); @@ -105,7 +103,6 @@ protected: // The default value is the launcher's non-scaled talkspeed value. When SCUMM uses the widget, // it uses its own scale void addSubtitleControls(GuiObject *boss, const Common::String &prefix, int maxSliderVal = 255); - void addEngineControls(GuiObject *boss, const Common::String &prefix, const ExtraGuiOptions &engineOptions); void setGraphicSettingsState(bool enabled); void setShaderSettingsState(bool enabled); @@ -243,11 +240,6 @@ protected: // Common::String _guioptions; Common::String _guioptionsString; - - // - // Engine-specific controls - // - CheckboxWidgetList _engineCheckboxes; }; diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 7e36996d45b..4f831dd7ae1 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1969,7 +1969,12 @@ const char *defaultXML1 = "" "" "" "" -"" +"" +"" +"" +"" +"" +"" "" "" "" "" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" "" "" "" @@ -3772,7 +3787,12 @@ const char *defaultXML1 = "" "" "" "" -"" +"" +"" +"" +"" +"" +"" "" "" "" "" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" "" "" "" diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip index 15040dfe639..f51df566aa2 100644 Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC index 2bea7c2a2a0..4b1ab88179d 100644 --- a/gui/themes/scummclassic/THEMERC +++ b/gui/themes/scummclassic/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.35:ScummVM Classic Theme:No Author] +[SCUMMVM_STX0.8.36:ScummVM Classic Theme:No Author] diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index ddd246e64e6..31193b6206d 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -1124,7 +1124,13 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 9b7aaca79c4..05161624490 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -1134,7 +1134,13 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip index 55845bb8515..b015aa9b901 100644 Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC index 0d3fa6cec0c..7de065a176e 100644 --- a/gui/themes/scummmodern/THEMERC +++ b/gui/themes/scummmodern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.35:ScummVM Modern Theme:No Author] +[SCUMMVM_STX0.8.36:ScummVM Modern Theme:No Author] diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 6b89f2c57a1..f1d18251f21 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -1137,7 +1137,13 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index f85df8647c1..854e673136f 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -1133,7 +1133,13 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip index 7907630550f..2e795a95780 100644 Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ diff --git a/gui/themes/scummremastered/THEMERC b/gui/themes/scummremastered/THEMERC index 20c006fb4e4..aab05190ef1 100644 --- a/gui/themes/scummremastered/THEMERC +++ b/gui/themes/scummremastered/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.35:ScummVM Modern Theme Remastered:No Author] +[SCUMMVM_STX0.8.36:ScummVM Modern Theme Remastered:No Author] diff --git a/gui/themes/scummremastered/remastered_layout.stx b/gui/themes/scummremastered/remastered_layout.stx index 5a98890188b..eff0392a634 100644 --- a/gui/themes/scummremastered/remastered_layout.stx +++ b/gui/themes/scummremastered/remastered_layout.stx @@ -1137,7 +1137,13 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummremastered/remastered_layout_lowres.stx b/gui/themes/scummremastered/remastered_layout_lowres.stx index 99b30636252..f1ab411db53 100644 --- a/gui/themes/scummremastered/remastered_layout_lowres.stx +++ b/gui/themes/scummremastered/remastered_layout_lowres.stx @@ -1133,7 +1133,13 @@ - + + + + + + + + + + + + + + + + + + +