GUI: Add per-engine and per-game options

This commit is contained in:
Filippos Karapetis 2012-02-27 22:50:01 +02:00 committed by Johannes Schickel
parent be8c557645
commit c84cd8dee8
17 changed files with 267 additions and 13 deletions

View File

@ -195,7 +195,7 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
}
// On creation the engine should have set up all debug levels so we can use
// the command line arugments here
// the command line arguments here
Common::StringTokenizer tokenizer(edebuglevels, " ,");
while (!tokenizer.empty()) {
Common::String token = tokenizer.nextToken();
@ -206,6 +206,12 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
// Initialize any game-specific keymaps
engine->initKeymap();
// Set default values to the custom engine options
const ExtraGuiOptions engineOptions = (*plugin)->getExtraGuiOptions(ConfMan.getActiveDomainName());
for (uint i = 0; i < engineOptions.size(); i++) {
ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState);
}
// Inform backend that the engine is about to be run
system.engineInit();

View File

@ -1 +1 @@
[SCUMMVM_STX0.8.3:ScummVM Mobile Theme:No Author]
[SCUMMVM_STX0.8.9:ScummVM Mobile Theme:No Author]

View File

@ -621,6 +621,32 @@
</layout>
</dialog>
<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
<layout type = 'vertical' padding = '16, 16, 16, 16'>
<widget name = 'customOption1Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption2Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption3Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption4Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption5Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption6Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption7Checkbox'
type = 'Checkbox'
/>
</layout>
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
<layout type = 'vertical' padding = '16, 16, 16, 16' center = 'true'>
<widget name = 'Logo'

View File

@ -24,6 +24,7 @@
#include "common/scummsys.h"
#include "common/error.h"
#include "common/array.h"
#include "engines/game.h"
#include "engines/savestate.h"
@ -38,6 +39,19 @@ class FSList;
class String;
}
/**
* Per-game extra GUI options structure.
* Currently, this can only be used for options with checkboxes.
*/
struct ExtraGuiOption {
const char *label; // option label, e.g. "Fullscreen mode"
const char *tooltip; // option tooltip (when the mouse hovers above it)
const char *configOption; // confMan key, e.g. "fullscreen"
bool defaultState; // the detault state of the checkbox (checked or not)
};
typedef Common::Array<ExtraGuiOption> ExtraGuiOptions;
/**
* A meta engine is essentially a factory for Engine instances with the
* added ability of listing and detecting supported games.
@ -97,6 +111,16 @@ public:
return SaveStateList();
}
/**
* Return a list of extra GUI options.
* Currently, this only supports options with checkboxes.
*
* The default implementation returns an empty list.
*/
virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const {
return ExtraGuiOptions();
}
/**
* Return the maximum save slot that the engine supports.
*

View File

@ -35,7 +35,7 @@
#include "graphics/pixelformat.h"
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.8"
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.9"
class OSystem;

View File

@ -145,11 +145,28 @@ protected:
CheckboxWidget *_globalMIDIOverride;
CheckboxWidget *_globalMT32Override;
CheckboxWidget *_globalVolumeOverride;
ExtraGuiOptions _engineOptions;
};
EditGameDialog::EditGameDialog(const String &domain, const String &desc)
: OptionsDialog(domain, "GameOptions") {
// Retrieve all game specific options.
const EnginePlugin *plugin = 0;
// To allow for game domains without a gameid.
// TODO: Is it intentional that this is still supported?
String gameId(ConfMan.get("gameid", domain));
if (gameId.empty())
gameId = domain;
// Retrieve the plugin, since we need to access the engine's MetaEngine
// implementation.
EngineMan.findGame(gameId, &plugin);
if (plugin) {
_engineOptions = (*plugin)->getExtraGuiOptions(domain);
} else {
warning("Plugin for target \"%s\" not found! Game specific settings might be missing", domain.c_str());
}
// GAME: Path to game data (r/o), extra data (r/o), and save data (r/w)
String gamePath(ConfMan.get("path", _domain));
String extraPath(ConfMan.get("extrapath", _domain));
@ -208,7 +225,16 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
}
//
// 2) The graphics tab
// 2) The engine tab (shown only if there are custom engine options)
//
if (_engineOptions.size() > 0) {
tab->addTab(_("Engine"));
addEngineControls(tab, "GameOptions_Engine.", _engineOptions);
}
//
// 3) The graphics tab
//
_graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX"));
@ -220,7 +246,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
addGraphicControls(tab, "GameOptions_Graphics.");
//
// 3) The audio tab
// 4) The audio tab
//
tab->addTab(_("Audio"));
@ -233,7 +259,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
addSubtitleControls(tab, "GameOptions_Audio.");
//
// 4) The volume tab
// 5) The volume tab
//
if (g_system->getOverlayWidth() > 320)
tab->addTab(_("Volume"));
@ -248,7 +274,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
addVolumeControls(tab, "GameOptions_Volume.");
//
// 5) The MIDI tab
// 6) The MIDI tab
//
if (!_guioptions.contains(GUIO_NOMIDI)) {
tab->addTab(_("MIDI"));
@ -262,7 +288,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
}
//
// 6) The MT-32 tab
// 7) The MT-32 tab
//
if (!_guioptions.contains(GUIO_NOMIDI)) {
tab->addTab(_("MT-32"));
@ -276,7 +302,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
}
//
// 7) The Paths tab
// 8) The Paths tab
//
if (g_system->getOverlayWidth() > 320)
tab->addTab(_("Paths"));
@ -311,7 +337,6 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
_savePathClearButton = addClearButton(tab, "GameOptions_Paths.SavePathClearButton", kCmdSavePathClear);
// Activate the first tab
tab->setActiveTab(0);
_tabWidget = tab;
@ -386,6 +411,19 @@ 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);
}
const Common::PlatformDescription *p = Common::g_platforms;
const Common::Platform platform = Common::parsePlatform(ConfMan.get("platform", _domain));
@ -429,6 +467,11 @@ void EditGameDialog::close() {
ConfMan.removeKey("platform", _domain);
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);
}
}
OptionsDialog::close();
}

View File

@ -997,6 +997,22 @@ 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;

View File

@ -22,6 +22,8 @@
#ifndef OPTIONS_DIALOG_H
#define OPTIONS_DIALOG_H
#include "engines/metaengine.h"
#include "gui/dialog.h"
#include "common/str.h"
#include "audio/mididrv.h"
@ -44,6 +46,8 @@ class RadiobuttonGroup;
class RadiobuttonWidget;
class OptionsDialog : public Dialog {
typedef Common::Array<CheckboxWidget *> CheckboxWidgetList;
public:
OptionsDialog(const Common::String &domain, int x, int y, int w, int h);
OptionsDialog(const Common::String &domain, const Common::String &name);
@ -74,6 +78,7 @@ 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 setAudioSettingsState(bool enabled);
@ -181,6 +186,11 @@ protected:
//Theme Options
//
Common::String _oldTheme;
//
// Engine-specific controls
//
CheckboxWidgetList _engineCheckboxes;
};

View File

@ -1187,6 +1187,31 @@
"</layout> "
"</layout> "
"</dialog> "
"<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'> "
"<layout type = 'vertical' padding = '16, 16, 16, 16'> "
"<widget name = 'customOption1Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption2Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption3Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption4Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption5Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption6Checkbox' "
"type = 'Checkbox' "
"/> "
"<widget name = 'customOption7Checkbox' "
"type = 'Checkbox' "
"/> "
"</layout> "
"</dialog> "
"<dialog name='GlobalMenu' overlays='screen_center'> "
"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
"<widget name='Title' "

Binary file not shown.

View File

@ -1 +1 @@
[SCUMMVM_STX0.8.8:ScummVM Classic Theme:No Author]
[SCUMMVM_STX0.8.9:ScummVM Classic Theme:No Author]

View File

@ -627,6 +627,32 @@
</layout>
</dialog>
<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
<layout type = 'vertical' padding = '16, 16, 16, 16'>
<widget name = 'customOption1Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption2Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption3Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption4Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption5Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption6Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption7Checkbox'
type = 'Checkbox'
/>
</layout>
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
<layout type = 'vertical' padding = '16, 16, 16, 16' center = 'true'>
<widget name = 'Title'

View File

@ -639,6 +639,32 @@
</layout>
</dialog>
<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 8, 8'>
<widget name = 'customOption1Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption2Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption3Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption4Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption5Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption6Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption7Checkbox'
type = 'Checkbox'
/>
</layout>
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
<layout type = 'vertical' padding = '2, 2, 4, 6' center = 'true' spacing='6'>
<widget name = 'Title'

Binary file not shown.

View File

@ -1 +1 @@
[SCUMMVM_STX0.8.8:ScummVM Modern Theme:No Author]
[SCUMMVM_STX0.8.9:ScummVM Modern Theme:No Author]

View File

@ -642,6 +642,32 @@
</layout>
</dialog>
<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
<layout type = 'vertical' padding = '16, 16, 16, 16'>
<widget name = 'customOption1Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption2Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption3Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption4Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption5Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption6Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption7Checkbox'
type = 'Checkbox'
/>
</layout>
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
<layout type = 'vertical' padding = '16, 16, 16, 16' center = 'true'>
<widget name = 'Logo'

View File

@ -637,6 +637,32 @@
</layout>
</dialog>
<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 8, 8'>
<widget name = 'customOption1Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption2Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption3Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption4Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption5Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption6Checkbox'
type = 'Checkbox'
/>
<widget name = 'customOption7Checkbox'
type = 'Checkbox'
/>
</layout>
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
<layout type = 'vertical' padding = '4, 4, 4, 4' center = 'true' spacing='2'>
<widget name = 'Title'