diff options
-rw-r--r-- | gui/launcher.cpp | 458 | ||||
-rw-r--r-- | gui/launcher.h | 6 | ||||
-rw-r--r-- | gui/options.cpp | 367 | ||||
-rw-r--r-- | gui/options.h | 58 |
4 files changed, 476 insertions, 413 deletions
diff --git a/gui/launcher.cpp b/gui/launcher.cpp index e6e3ba0a40..adf84729b7 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -41,6 +41,9 @@ #include "gui/TabWidget.h" #include "gui/PopUpWidget.h" +#include "sound/mididrv.h" + + using Common::ConfigManager; enum { @@ -73,40 +76,32 @@ enum { * - Maybe SFX/Master/Music volumes? */ -enum { - kOKCmd = 'OK ' -}; - -class EditGameDialog : public Dialog { +class EditGameDialog : public OptionsDialog { typedef Common::String String; typedef Common::StringList StringList; public: EditGameDialog(const String &domain, GameSettings target); + void open(); + void close(); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); protected: - const String &_domain; EditTextWidget *_descriptionWidget; EditTextWidget *_domainWidget; + PopUpWidget *_langPopUp; PopUpWidget *_platformPopUp; - - PopUpWidget *_gfxPopUp; - CheckboxWidget *_fullscreenCheckbox; - CheckboxWidget *_aspectCheckbox; - - CheckboxWidget *_multiMidiCheckbox; - CheckboxWidget *_mt32Checkbox; }; EditGameDialog::EditGameDialog(const String &domain, GameSettings target) - : Dialog(8, 50, 320 - 2 * 8, 140), - _domain(domain) { + : OptionsDialog(domain, 10, 50, 320 - 2 * 10, 140) { + const int x = 5; + const int w = _w - 15; + const int labelWidth = 65; const int vBorder = 5; // Tab border int yoffset; - int sel; // GAME: Path to game data (r/o) String path(ConfMan.get("path", _domain)); @@ -127,37 +122,32 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target) yoffset = vBorder; // GUI: Label & edit widget for the game ID - new StaticTextWidget(tab, 10, yoffset+2, 40, kLineHeight, "ID: ", kTextAlignRight); - _domainWidget = new EditTextWidget(tab, 50, yoffset, _w - 50 - 10, kLineHeight, _domain); + new StaticTextWidget(tab, x, yoffset+2, labelWidth, kLineHeight, "ID: ", kTextAlignRight); + _domainWidget = new EditTextWidget(tab, x+labelWidth, yoffset, _w - labelWidth - 10, kLineHeight, _domain); yoffset += 16; // GUI: Label & edit widget for the description - new StaticTextWidget(tab, 10, yoffset+2, 40, kLineHeight, "Name: ", kTextAlignRight); - _descriptionWidget = new EditTextWidget(tab, 50, yoffset, _w - 50 - 10, kLineHeight, description); + new StaticTextWidget(tab, x, yoffset+2, labelWidth, kLineHeight, "Name: ", kTextAlignRight); + _descriptionWidget = new EditTextWidget(tab, x+labelWidth, yoffset, _w - labelWidth - 10, kLineHeight, description); yoffset += 16; // GUI: Label for the game path - new StaticTextWidget(tab, 10, yoffset, 40, kLineHeight, "Path: ", kTextAlignRight); - new StaticTextWidget(tab, 50, yoffset, _w - 50 - 10, kLineHeight, path, kTextAlignLeft); + new StaticTextWidget(tab, x, yoffset, labelWidth, kLineHeight, "Path: ", kTextAlignRight); + new StaticTextWidget(tab, x+labelWidth, yoffset, _w - labelWidth - 10, kLineHeight, path, kTextAlignLeft); yoffset += 16; // Languag popup - _langPopUp = new PopUpWidget(tab, 5, yoffset, 280, kLineHeight, "Language: ", 100); + _langPopUp = new PopUpWidget(tab, x, yoffset, w, kLineHeight, "Language: ", labelWidth); yoffset += 16; _langPopUp->appendEntry("<default>"); _langPopUp->appendEntry(""); const Common::LanguageDescription *l = Common::g_languages; - int lang = Common::parseLanguage(ConfMan.get("language", _domain)); - sel = 0; - for (int i = 0; l->name; ++l, ++i) { + for (; l->name; ++l) { _langPopUp->appendEntry(l->description, l->id); - if (lang == l->id) - sel = i + 2; } - _langPopUp->setSelected(sel); // Platform popup - _platformPopUp = new PopUpWidget(tab, 5, yoffset, 280, kLineHeight, "Platform: ", 100); + _platformPopUp = new PopUpWidget(tab, x, yoffset, w, kLineHeight, "Platform: ", labelWidth); yoffset += 16; _platformPopUp->appendEntry("<default>"); _platformPopUp->appendEntry(""); @@ -165,82 +155,83 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target) _platformPopUp->appendEntry("Atari ST", Common::kPlatformAtariST); _platformPopUp->appendEntry("Macintosh", Common::kPlatformMacintosh); _platformPopUp->appendEntry("PC", Common::kPlatformPC); - switch (Common::parsePlatform(ConfMan.get("platform", _domain))) { - case Common::kPlatformPC: sel = 5; break; - case Common::kPlatformAmiga: sel = 2; break; - case Common::kPlatformAtariST: sel = 3; break; - case Common::kPlatformMacintosh: sel = 4; break; - default: sel = 0; break; - } - _platformPopUp->setSelected(sel); // // 2) The graphics tab // tab->addTab("Graphics"); yoffset = vBorder; - - // The GFX mode popup & a label - // TODO - add an API to query the list of available GFX modes, and to get/set the mode - _gfxPopUp = new PopUpWidget(tab, 5, yoffset, 280, kLineHeight, "Graphics mode: ", 100); - yoffset += 16; - _gfxPopUp->appendEntry("<global default>"); - _gfxPopUp->appendEntry(""); - _gfxPopUp->appendEntry("Normal (no scaling)"); - _gfxPopUp->appendEntry("2x"); - _gfxPopUp->appendEntry("3x"); - _gfxPopUp->appendEntry("2xSAI"); - _gfxPopUp->appendEntry("Super2xSAI"); - _gfxPopUp->appendEntry("SuperEagle"); - _gfxPopUp->appendEntry("AdvMAME2x"); - _gfxPopUp->appendEntry("AdvMAME3x"); - _gfxPopUp->appendEntry("hq2x"); - _gfxPopUp->appendEntry("hq3x"); - _gfxPopUp->appendEntry("TV2x"); - _gfxPopUp->appendEntry("DotMatrix"); - _gfxPopUp->setSelected(0); - - // FIXME - disable GFX popup for now - _gfxPopUp->setEnabled(false); - - // GUI: Full screen checkbox - _fullscreenCheckbox = new CheckboxWidget(tab, 15, yoffset, 200, 16, "Fullscreen mode", 0, 'F'); - _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); - yoffset += 16; - - _aspectCheckbox = new CheckboxWidget(tab, 15, yoffset, 200, 16, "Aspect ratio correction"); - _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio", _domain)); - yoffset += 16; + yoffset = addGraphicControls(tab, yoffset); // // 3) The audio tab // tab->addTab("Audio"); yoffset = vBorder; - - // Multi midi setting - _multiMidiCheckbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "Mixed Adlib/MIDI mode"); - _multiMidiCheckbox->setState(ConfMan.getBool("multi_midi", _domain)); - yoffset += 16; - - // Native mt32 setting - _mt32Checkbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "True Roland MT-32 (disable GM emulation)"); - _mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain)); - yoffset += 16; - - - // TODO: Volume/driver/midi/... settings + yoffset = addMIDIControls(tab, yoffset); + // + // 3) The volume tab + // + tab->addTab("Volume"); + yoffset = vBorder; + yoffset = addVolumeControls(tab, yoffset); // Activate the first tab tab->setActiveTab(0); - // GUI: Add OK & Cancel buttons + // Add OK & Cancel buttons addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0); addButton(_w - (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0); } +void EditGameDialog::open() { + OptionsDialog::open(); + + int sel = 0; + + // TODO: game path + + const Common::LanguageDescription *l = Common::g_languages; + int lang = Common::parseLanguage(ConfMan.get("language", _domain)); + for (int i = 0; l->name; ++l, ++i) { + if (lang == l->id) + sel = i + 2; + } + _langPopUp->setSelected(sel); + + + switch (Common::parsePlatform(ConfMan.get("platform", _domain))) { + case Common::kPlatformPC: sel = 5; break; + case Common::kPlatformAmiga: sel = 2; break; + case Common::kPlatformAtariST: sel = 3; break; + case Common::kPlatformMacintosh: sel = 4; break; + default: sel = 0; break; + } + _platformPopUp->setSelected(sel); +} + + +void EditGameDialog::close() { + if (getResult()) { + ConfMan.set("description", _descriptionWidget->getLabel(), _domain); + + Common::Language lang = (Common::Language)_langPopUp->getSelectedTag(); + if (lang < 0) + ConfMan.removeKey("language", _domain); + else + ConfMan.set("language", Common::getLanguageString(lang), _domain); + + Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag(); + if (platform < 0) + ConfMan.removeKey("platform", _domain); + else + ConfMan.set("platform", Common::getPlatformString(platform), _domain); + } + OptionsDialog::close(); +} + void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { if (cmd == kOKCmd) { // Write back changes made to config object @@ -252,31 +243,15 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat return; } ConfMan.renameGameDomain(_domain, newDomain); + _domain = newDomain; } - ConfMan.set("description", _descriptionWidget->getLabel(), newDomain); - ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), newDomain); - ConfMan.set("aspect_ratio", _aspectCheckbox->getState(), newDomain); - ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), newDomain); - ConfMan.set("native_mt32", _mt32Checkbox->getState(), newDomain); + } + OptionsDialog::handleCommand(sender, cmd, data); +} - Common::Language lang = (Common::Language)_langPopUp->getSelectedTag(); - if (lang < 0) - ConfMan.removeKey("language", newDomain); - else - ConfMan.set("language", Common::getLanguageString(lang), newDomain); - Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag(); - if (platform < 0) - ConfMan.removeKey("platform", newDomain); - else - ConfMan.set("platform", Common::getPlatformString(platform), newDomain); +#pragma mark - - setResult(1); - close(); - } else { - Dialog::handleCommand(sender, cmd, data); - } -} LauncherDialog::LauncherDialog(GameDetector &detector) : Dialog(0, 0, 320, 200), _detector(detector) { @@ -323,21 +298,6 @@ LauncherDialog::~LauncherDialog() { delete _browser; } -void LauncherDialog::open() { - Dialog::open(); -/* FIXME / TODO: config rewrite - g_config->set_writing(true); -*/ -} - -void LauncherDialog::close() { - ConfMan.flushToDisk(); -/* FIXME / TODO: config rewrite - g_config->set_writing(false); -*/ - Dialog::close(); -} - void LauncherDialog::updateListing() { Common::StringList l; @@ -372,144 +332,148 @@ void LauncherDialog::updateListing() { updateButtons(); } -void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - int item = _list->getSelected(); - - switch (cmd) { - case kAddGameCmd: - // Allow user to add a new game to the list. - // 1) show a dir selection dialog which lets the user pick the directory - // the game data resides in. - // 2) try to auto detect which game is in the directory, if we cannot - // determine it uniquely preent a list of candidates to the user - // to pick from - // 3) Display the 'Edit' dialog for that item, letting the user specify - // an alternate description (to distinguish multiple versions of the - // game, e.g. 'Monkey German' and 'Monkey English') and set default - // options for that game. - - if (_browser->runModal()) { - // User made his choice... - FilesystemNode *dir = _browser->getResult(); - FSList *files = dir->listDir(FilesystemNode::kListFilesOnly); - - // ...so let's determine a list of candidates, games that - // could be contained in the specified directory. - GameList candidates; - - // Iterate over all known games and for each check if it might be - // the game in the presented directory. - const PluginList &plugins = PluginManager::instance().getPlugins(); - PluginList::ConstIterator iter = plugins.begin(); - for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - candidates.push_back((*iter)->detectGames(*files)); - } +void LauncherDialog::addGame() { + // Allow user to add a new game to the list. + // 1) show a dir selection dialog which lets the user pick the directory + // the game data resides in. + // 2) try to auto detect which game is in the directory, if we cannot + // determine it uniquely preent a list of candidates to the user + // to pick from + // 3) Display the 'Edit' dialog for that item, letting the user specify + // an alternate description (to distinguish multiple versions of the + // game, e.g. 'Monkey German' and 'Monkey English') and set default + // options for that game. + + if (_browser->runModal()) { + // User made his choice... + FilesystemNode *dir = _browser->getResult(); + FSList *files = dir->listDir(FilesystemNode::kListFilesOnly); + + // ...so let's determine a list of candidates, games that + // could be contained in the specified directory. + GameList candidates; + + // Iterate over all known games and for each check if it might be + // the game in the presented directory. + const PluginList &plugins = PluginManager::instance().getPlugins(); + PluginList::ConstIterator iter = plugins.begin(); + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { + candidates.push_back((*iter)->detectGames(*files)); + } - int idx; - if (candidates.isEmpty()) { - // No game was found in the specified directory - MessageDialog alert("ScummVM could not find any game in the specified directory!"); - alert.runModal(); - idx = -1; - } else if (candidates.size() == 1) { - // Exact match - idx = 0; - } else { - // Display the candidates to the user and let her/him pick one - StringList list; - for (idx = 0; idx < candidates.size(); idx++) - list.push_back(candidates[idx].description); - - ChooserDialog dialog("Pick the game:", list); - idx = dialog.runModal(); - } - if (0 <= idx && idx < candidates.size()) { - GameSettings result = candidates[idx]; - - // The auto detector or the user made a choice. - // Pick a domain name which does not yet exist (after all, we - // are *adding* a game to the config, not replacing). - String domain(result.gameName); - if (ConfMan.hasGameDomain(domain)) { - char suffix = 'a'; + int idx; + if (candidates.isEmpty()) { + // No game was found in the specified directory + MessageDialog alert("ScummVM could not find any game in the specified directory!"); + alert.runModal(); + idx = -1; + } else if (candidates.size() == 1) { + // Exact match + idx = 0; + } else { + // Display the candidates to the user and let her/him pick one + StringList list; + for (idx = 0; idx < candidates.size(); idx++) + list.push_back(candidates[idx].description); + + ChooserDialog dialog("Pick the game:", list); + idx = dialog.runModal(); + } + if (0 <= idx && idx < candidates.size()) { + GameSettings result = candidates[idx]; + + // The auto detector or the user made a choice. + // Pick a domain name which does not yet exist (after all, we + // are *adding* a game to the config, not replacing). + String domain(result.gameName); + if (ConfMan.hasGameDomain(domain)) { + char suffix = 'a'; + domain += suffix; + while (ConfMan.hasGameDomain(domain)) { + assert(suffix < 'z'); + domain.deleteLastChar(); + suffix++; domain += suffix; - while (ConfMan.hasGameDomain(domain)) { - assert(suffix < 'z'); - domain.deleteLastChar(); - suffix++; - domain += suffix; - } - ConfMan.set("gameid", result.gameName, domain); - ConfMan.set("description", result.description, domain); } - ConfMan.set("path", dir->path(), domain); + ConfMan.set("gameid", result.gameName, domain); + ConfMan.set("description", result.description, domain); + } + ConfMan.set("path", dir->path(), domain); + + // Display edit dialog for the new entry + EditGameDialog editDialog(domain, result); + if (editDialog.runModal()) { + // User pressed OK, so make changes permanent + + // Write config to disk + ConfMan.flushToDisk(); - // Display edit dialog for the new entry - EditGameDialog editDialog(domain, result); - if (editDialog.runModal()) { - // User pressed OK, so make changes permanent - - // Write config to disk - ConfMan.flushToDisk(); - - // Update the ListWidget and force a redraw - updateListing(); - draw(); - } else { - // User aborted, remove the the new domain again - ConfMan.removeGameDomain(domain); - } + // Update the ListWidget and force a redraw + updateListing(); + draw(); + } else { + // User aborted, remove the the new domain again + ConfMan.removeGameDomain(domain); } } - break; - case kRemoveGameCmd: { + } +} + +void LauncherDialog::removeGame(int item) { + MessageDialog alert("Do you really want to remove this game configuration?", "Yes", "No"); - MessageDialog alert("Do you really want to remove this game configuration?", "Yes", "No"); + if (alert.runModal() == 1) { + // Remove the currently selected game from the list + assert(item >= 0); + ConfMan.removeGameDomain(_domains[item]); + + // Write config to disk + ConfMan.flushToDisk(); - if (alert.runModal() == 1) { - // Remove the currently selected game from the list - assert(item >= 0); - ConfMan.removeGameDomain(_domains[item]); - - // Write config to disk - ConfMan.flushToDisk(); - - // Update the ListWidget and force a redraw - updateListing(); - draw(); - } - } + // Update the ListWidget and force a redraw + updateListing(); + draw(); + } +} + +void LauncherDialog::editGame(int item) { + // Set game specifc options. Most of these should be "optional", i.e. by + // default set nothing and use the global ScummVM settings. E.g. the user + // can set here an optional alternate music volume, or for specific games + // a different music driver etc. + // This is useful because e.g. MonkeyVGA needs Adlib music to have decent + // music support etc. + assert(item >= 0); + String gameId(ConfMan.get("gameid", _domains[item])); + if (gameId.isEmpty()) + gameId = _domains[item]; + EditGameDialog editDialog(_domains[item], GameDetector::findGame(gameId)); + if (editDialog.runModal()) { + // User pressed OK, so make changes permanent + + // Write config to disk + ConfMan.flushToDisk(); + + // Update the ListWidget and force a redraw + updateListing(); + draw(); + } +} + +void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + int item = _list->getSelected(); + + switch (cmd) { + case kAddGameCmd: + addGame(); break; - case kEditGameCmd: { - // Set game specifc options. Most of these should be "optional", i.e. by - // default set nothing and use the global ScummVM settings. E.g. the user - // can set here an optional alternate music volume, or for specific games - // a different music driver etc. - // This is useful because e.g. MonkeyVGA needs Adlib music to have decent - // music support etc. - assert(item >= 0); - String gameId(ConfMan.get("gameid", _domains[item])); - if (gameId.isEmpty()) - gameId = _domains[item]; - EditGameDialog editDialog(_domains[item], GameDetector::findGame(gameId)); - if (editDialog.runModal()) { - // User pressed OK, so make changes permanent - - // Write config to disk - ConfMan.flushToDisk(); - - // Update the ListWidget and force a redraw - updateListing(); - draw(); - } - } + case kRemoveGameCmd: + removeGame(item); + break; + case kEditGameCmd: + editGame(item); break; case kOptionsCmd: { - // TODO - show up a generic options dialog with global options, including: - // - the save path (use _browser!) - // - music & graphics driver (but see also the comments on EditGameDialog - // for some techincal difficulties with this) - // - default volumes (sfx/master/music) GlobalOptionsDialog options(_detector); options.runModal(); } diff --git a/gui/launcher.h b/gui/launcher.h index d7f7b6dc81..fa74186b2b 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -36,8 +36,6 @@ public: LauncherDialog(GameDetector &detector); ~LauncherDialog(); - virtual void open(); - virtual void close(); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); protected: @@ -51,6 +49,10 @@ protected: void updateListing(); void updateButtons(); + + void addGame(); + void removeGame(int item); + void editGame(int item); }; #endif diff --git a/gui/options.cpp b/gui/options.cpp index 0ab7d5fc0e..80e82844bb 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -29,24 +29,13 @@ #include "backends/fs/fs.h" #include "base/gameDetector.h" #include "common/config-manager.h" +#include "common/scaler.h" #include "sound/mididrv.h" #if (!( defined(__DC__) || defined(__GP32__)) && !defined(_MSC_VER)) #include <unistd.h> #endif -/* - _____ _ _ _ _ _ -|_ _| |__ (_)___ (_)___ __ _ __| |_ _ _ __ ___ _ __ ___ _ _| | - | | | '_ \| / __| | / __| / _` | / _` | | | | '_ ` _ \| '_ ` _ \| | | | | - | | | | | | \__ \ | \__ \ | (_| | | (_| | |_| | | | | | | | | | | | |_| |_| - |_| |_| |_|_|___/ |_|___/ \__,_| \__,_|\__,_|_| |_| |_|_| |_| |_|\__, (_) - |___/ - -This just looks like an option dialog, but it doesn't change any actual settings currently! - -*/ - // TODO - allow changing options for: // - the save path (use _browser!) // - music & graphics driver (but see also the comments on EditGameDialog @@ -55,119 +44,241 @@ This just looks like an option dialog, but it doesn't change any actual settings // - aspect ratio, language, platform, subtitles, debug mode/level, cd drive, joystick, multi midi, native mt32 enum { - kMasterVolumeChanged = 'mavc', + kMasterVolumeChanged = 'mavc', kMusicVolumeChanged = 'muvc', kSfxVolumeChanged = 'sfvc', - kChooseSaveDirCmd = 'chos', - kOKCmd = 'ok ' + kChooseSaveDirCmd = 'chos' }; -GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector) - : Dialog(10, 20, 320 - 2 * 10, 200 - 2 * 20) { +OptionsDialog::OptionsDialog(const String &domain, int x, int y, int w, int h) + : Dialog(x, y, w, h), + _domain(domain), + _gfxPopUp(0), _fullscreenCheckbox(0), _aspectCheckbox(0), + _multiMidiCheckbox(0), _mt32Checkbox(0), + _masterVolumeSlider(0), _masterVolumeLabel(0), + _musicVolumeSlider(0), _musicVolumeLabel(0), + _sfxVolumeSlider(0), _sfxVolumeLabel(0) { - const int vBorder = 5; - int yoffset; +} - // The tab widget - TabWidget *tab = new TabWidget(this, 0, vBorder, _w, _h - 24 - 2*vBorder); +void OptionsDialog::open() { + Dialog::open(); + + // Reset result value + setResult(0); + + // FIXME - disable GFX popup for now + _gfxPopUp->setSelected(0); + _gfxPopUp->setEnabled(false); - // - // 1) The graphics tab - // - tab->addTab("Graphics"); - yoffset = vBorder; + // Fullscreen setting + _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); + + // Aspect ratio setting + _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio", _domain)); + + // Music driver + const MidiDriverDescription *md = getAvailableMidiDrivers(); + const int midiDriver = parseMusicDriver(ConfMan.get("music_driver", _domain)); + int i = 0; + while (md->name && md->id != midiDriver) { + i++; + md++; + } + _midiPopUp->setSelected(md->name ? i : 0); + + // Multi midi setting + _multiMidiCheckbox->setState(ConfMan.getBool("multi_midi", _domain)); + + // Native mt32 setting + _mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain)); + + int vol; + + vol = ConfMan.getInt("master_volume", _domain); + _masterVolumeSlider->setValue(vol); + _masterVolumeLabel->setValue(vol); + + vol = ConfMan.getInt("music_volume", _domain); + _musicVolumeSlider->setValue(vol); + _musicVolumeLabel->setValue(vol); + + vol = ConfMan.getInt("sfx_volume", _domain); + _sfxVolumeSlider->setValue(vol); + _sfxVolumeLabel->setValue(vol); +} + +void OptionsDialog::close() { + if (getResult()) { + if (_fullscreenCheckbox) { + ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), _domain); + ConfMan.set("aspect_ratio", _aspectCheckbox->getState(), _domain); + } + + if (_masterVolumeSlider) { + ConfMan.set("master_volume", _masterVolumeSlider->getValue(), _domain); + ConfMan.set("music_volume", _musicVolumeSlider->getValue(), _domain); + ConfMan.set("sfx_volume", _sfxVolumeSlider->getValue(), _domain); + } - // The GFX mode popup & a label + if (_multiMidiCheckbox) { + ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), _domain); + ConfMan.set("native_mt32", _mt32Checkbox->getState(), _domain); + + const MidiDriverDescription *md = getAvailableMidiDrivers(); + while (md->name && md->id != (int)_midiPopUp->getSelectedTag()) + md++; + if (md->name) + ConfMan.set("music_driver", md->name, _domain); + else + ConfMan.removeKey("music_driver", _domain); + } + + // Save config file + ConfMan.flushToDisk(); + } + + Dialog::close(); +} + +void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + switch (cmd) { + case kMasterVolumeChanged: + _masterVolumeLabel->setValue(_masterVolumeSlider->getValue()); + _masterVolumeLabel->draw(); + break; + case kMusicVolumeChanged: + _musicVolumeLabel->setValue(_musicVolumeSlider->getValue()); + _musicVolumeLabel->draw(); + break; + case kSfxVolumeChanged: + _sfxVolumeLabel->setValue(_sfxVolumeSlider->getValue()); + _sfxVolumeLabel->draw(); + break; + case kOKCmd: + setResult(1); + close(); + break; + default: + Dialog::handleCommand(sender, cmd, data); + } +} + +int OptionsDialog::addGraphicControls(GuiObject *boss, int yoffset) { + const int x = 10; + const int w = _w - 2 * 10; + + // The GFX mode popup // TODO - add an API to query the list of available GFX modes, and to get/set the mode - _gfxPopUp = new PopUpWidget(tab, 5, yoffset, 280, kLineHeight, "Graphics mode: ", 100); + _gfxPopUp = new PopUpWidget(boss, x-5, yoffset, w+5, kLineHeight, "Graphics mode: ", 100); yoffset += 16; - // Ender: We don't really want a <default> here at all, we want to setSelected to the current global + // FIXME: For the GlobalOptionsDialog, we don't want a <default> here; + // rather, we want to setSelected to the current global _gfxPopUp->appendEntry("<default>"); _gfxPopUp->appendEntry(""); - _gfxPopUp->appendEntry("Normal (no scaling)"); - _gfxPopUp->appendEntry("2x"); - _gfxPopUp->appendEntry("3x"); - _gfxPopUp->appendEntry("2xSAI"); - _gfxPopUp->appendEntry("Super2xSAI"); - _gfxPopUp->appendEntry("SuperEagle"); - _gfxPopUp->appendEntry("AdvMAME2x"); - _gfxPopUp->appendEntry("AdvMAME3x"); - _gfxPopUp->appendEntry("hq2x"); - _gfxPopUp->appendEntry("hq3x"); - _gfxPopUp->appendEntry("TV2x"); - _gfxPopUp->appendEntry("DotMatrix"); - _gfxPopUp->setSelected(0); - - // FIXME - disable GFX popup for now - _gfxPopUp->setEnabled(false); - -#if 1 - // TODO: Aspect ratio setting - // TODO: Fullscreen setting - _fullscreenCheckbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "Fullscreen mode"); - _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen")); + _gfxPopUp->appendEntry("Normal (no scaling)", GFX_NORMAL); + _gfxPopUp->appendEntry("2x", GFX_DOUBLESIZE); + _gfxPopUp->appendEntry("3x", GFX_TRIPLESIZE); + _gfxPopUp->appendEntry("2xSAI", GFX_2XSAI); + _gfxPopUp->appendEntry("Super2xSAI", GFX_SUPER2XSAI); + _gfxPopUp->appendEntry("SuperEagle", GFX_SUPEREAGLE); + _gfxPopUp->appendEntry("AdvMAME2x", GFX_ADVMAME2X); + _gfxPopUp->appendEntry("AdvMAME3x", GFX_ADVMAME3X); + _gfxPopUp->appendEntry("hq2x", GFX_HQ2X); + _gfxPopUp->appendEntry("hq3x", GFX_HQ3X); + _gfxPopUp->appendEntry("TV2x", GFX_TV2X); + _gfxPopUp->appendEntry("DotMatrix", GFX_DOTMATRIX); + + // Fullscreen checkbox + _fullscreenCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Fullscreen mode"); yoffset += 16; - _aspectCheckbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "Aspect ratio correction"); - _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio")); + // Aspect ratio checkbox + _aspectCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Aspect ratio correction"); yoffset += 16; -#endif + return yoffset; +} - // - // 2) The audio tab - // - tab->addTab("Audio"); - yoffset = vBorder; +int OptionsDialog::addMIDIControls(GuiObject *boss, int yoffset) { + const int x = 10; + const int w = _w - 20; // The MIDI mode popup & a label - _midiPopUp = new PopUpWidget(tab, 5, yoffset, 280, kLineHeight, "Music driver: ", 100); + _midiPopUp = new PopUpWidget(boss, x-5, yoffset, w+5, kLineHeight, "Music driver: ", 100); yoffset += 16; // Populate it const MidiDriverDescription *md = getAvailableMidiDrivers(); - const int midiDriver = parseMusicDriver(ConfMan.get("music_driver")); - int midiSelected = 0, i = 0; while (md->name) { _midiPopUp->appendEntry(md->description, md->id); - if (md->id == midiDriver) - midiSelected = i; - i++; md++; } - _midiPopUp->setSelected(midiSelected); + // Multi midi setting + _multiMidiCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Mixed Adlib/MIDI mode"); + yoffset += 16; + + // Native mt32 setting + _mt32Checkbox = new CheckboxWidget(boss, x, yoffset, w, 16, "True Roland MT-32 (disable GM emulation)"); + yoffset += 16; + + return yoffset; +} + +int OptionsDialog::addVolumeControls(GuiObject *boss, int yoffset) { // Volume controllers - _masterVolumeSlider = new SliderWidget(tab, 5, yoffset, 185, 12, "Master volume: ", 100, kMasterVolumeChanged); - _masterVolumeLabel = new StaticTextWidget(tab, 200, yoffset+2, 24, 16, "100%", kTextAlignLeft); + _masterVolumeSlider = new SliderWidget(boss, 5, yoffset, 185, 12, "Master volume: ", 100, kMasterVolumeChanged); + _masterVolumeLabel = new StaticTextWidget(boss, 200, yoffset+2, 24, kLineHeight, "100%", kTextAlignLeft); _masterVolumeSlider->setMinValue(0); _masterVolumeSlider->setMaxValue(255); _masterVolumeLabel->setFlags(WIDGET_CLEARBG); yoffset += 16; - _musicVolumeSlider = new SliderWidget(tab, 5, yoffset, 185, 12, "Music volume: ", 100, kMusicVolumeChanged); - _musicVolumeLabel = new StaticTextWidget(tab, 200, yoffset+2, 24, 16, "100%", kTextAlignLeft); + _musicVolumeSlider = new SliderWidget(boss, 5, yoffset, 185, 12, "Music volume: ", 100, kMusicVolumeChanged); + _musicVolumeLabel = new StaticTextWidget(boss, 200, yoffset+2, 24, kLineHeight, "100%", kTextAlignLeft); _musicVolumeSlider->setMinValue(0); _musicVolumeSlider->setMaxValue(255); _musicVolumeLabel->setFlags(WIDGET_CLEARBG); yoffset += 16; - _sfxVolumeSlider = new SliderWidget(tab, 5, yoffset, 185, 12, "SFX volume: ", 100, kSfxVolumeChanged); - _sfxVolumeLabel = new StaticTextWidget(tab, 200, yoffset+2, 24, 16, "100%", kTextAlignLeft); + _sfxVolumeSlider = new SliderWidget(boss, 5, yoffset, 185, 12, "SFX volume: ", 100, kSfxVolumeChanged); + _sfxVolumeLabel = new StaticTextWidget(boss, 200, yoffset+2, 24, kLineHeight, "100%", kTextAlignLeft); _sfxVolumeSlider->setMinValue(0); _sfxVolumeSlider->setMaxValue(255); _sfxVolumeLabel->setFlags(WIDGET_CLEARBG); yoffset += 16; - - // Multi midi setting - _multiMidiCheckbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "Mixed Adlib/MIDI mode"); - _multiMidiCheckbox->setState(ConfMan.getBool("multi_midi")); - yoffset += 16; - // Native mt32 setting - _mt32Checkbox = new CheckboxWidget(tab, 10, yoffset, 280, 16, "True Roland MT-32 (disable GM emulation)"); - _mt32Checkbox->setState(ConfMan.getBool("native_mt32")); - yoffset += 16; + return yoffset; +} + +#pragma mark - + +GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector) + : OptionsDialog(Common::ConfigManager::kApplicationDomain, 10, 20, 320 - 2 * 10, 200 - 2 * 20) { + + const int vBorder = 5; + int yoffset; + + // The tab widget + TabWidget *tab = new TabWidget(this, 0, vBorder, _w, _h - 24 - 2*vBorder); + + // + // 1) The graphics tab + // + tab->addTab("Graphics"); + yoffset = vBorder; + yoffset = addGraphicControls(tab, yoffset); + + + // + // 2) The audio tab + // + tab->addTab("Audio"); + yoffset = vBorder; + yoffset = addMIDIControls(tab, yoffset); + yoffset = addVolumeControls(tab, yoffset); // TODO: cd drive setting + // // 3) The miscellaneous tab @@ -180,33 +291,19 @@ GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector) new StaticTextWidget(tab, 5, yoffset+2, 100, kLineHeight, "Savegame path: ", kTextAlignRight); _savePath = new StaticTextWidget(tab, 105, yoffset+2, 180, kLineHeight, "/foo/bar", kTextAlignLeft); new ButtonWidget(tab, 105, yoffset+14, 64, 16, "Choose...", kChooseSaveDirCmd, 0); - -// TODO: set _savePath to the current save path - Common::String dir(ConfMan.get("savepath")); - if (!dir.isEmpty()) { - _savePath->setLabel(dir); - } else { - // Default to the current directory... - char buf[256]; - getcwd(buf, sizeof(buf)); - _savePath->setLabel(buf); - } #endif // TODO: joystick setting + + // Activate the first tab + tab->setActiveTab(0); - // // Add OK & Cancel buttons - // addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0); addButton(_w - (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0); // Create file browser dialog _browser = new BrowserDialog("Select directory for savegames"); - - - // Activate the first tab - tab->setActiveTab(0); } GlobalOptionsDialog::~GlobalOptionsDialog() { @@ -214,21 +311,27 @@ GlobalOptionsDialog::~GlobalOptionsDialog() { } void GlobalOptionsDialog::open() { - Dialog::open(); - - int vol; - - vol = ConfMan.getInt("master_volume"); - _masterVolumeSlider->setValue(vol); - _masterVolumeLabel->setValue(vol); + OptionsDialog::open(); - vol = ConfMan.getInt("music_volume"); - _musicVolumeSlider->setValue(vol); - _musicVolumeLabel->setValue(vol); +#if !( defined(__DC__) || defined(__GP32__) ) + // Set _savePath to the current save path + Common::String dir(ConfMan.get("savepath", _domain)); + if (!dir.isEmpty()) { + _savePath->setLabel(dir); + } else { + // Default to the current directory... + char buf[256]; + getcwd(buf, sizeof(buf)); + _savePath->setLabel(buf); + } +#endif +} - vol = ConfMan.getInt("sfx_volume"); - _sfxVolumeSlider->setValue(vol); - _sfxVolumeLabel->setValue(vol); +void GlobalOptionsDialog::close() { + if (getResult()) { + // TODO: Savepath + } + OptionsDialog::close(); } void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { @@ -241,47 +344,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 // TODO - we should check if the directory is writeable before accepting it } break; - case kMasterVolumeChanged: - _masterVolumeLabel->setValue(_masterVolumeSlider->getValue()); - _masterVolumeLabel->draw(); - break; - case kMusicVolumeChanged: - _musicVolumeLabel->setValue(_musicVolumeSlider->getValue()); - _musicVolumeLabel->draw(); - break; - case kSfxVolumeChanged: - _sfxVolumeLabel->setValue(_sfxVolumeSlider->getValue()); - _sfxVolumeLabel->draw(); - break; - case kOKCmd: { - setResult(1); - // TODO: All these settings should take effect immediately. - // There are two ways to ensure that: - // 1) Add code here which pushes the changes on to the mixer/backend - // 2) Implement the ConfigManager callback API; then, let the mixer/backend - // and any other interested parties register for notifications sent - // whenever these config values change. - ConfMan.set("master_volume", _masterVolumeSlider->getValue()); - ConfMan.set("music_volume", _musicVolumeSlider->getValue()); - ConfMan.set("sfx_volume", _sfxVolumeSlider->getValue()); - ConfMan.set("fullscreen", _fullscreenCheckbox->getState()); - ConfMan.set("aspect_ratio", _aspectCheckbox->getState()); - ConfMan.set("multi_midi", _multiMidiCheckbox->getState()); - ConfMan.set("native_mt32", _mt32Checkbox->getState()); - - const MidiDriverDescription *md = getAvailableMidiDrivers(); - for (; md->name; md++) { - if (md->id == (int)_midiPopUp->getSelectedTag()) { - ConfMan.set("music_driver", md->name); - break; - } - } - if (!md->name) - ConfMan.removeKey("music_driver", Common::ConfigManager::kApplicationDomain); - - close(); - break; } default: - Dialog::handleCommand(sender, cmd, data); + OptionsDialog::handleCommand(sender, cmd, data); } } diff --git a/gui/options.h b/gui/options.h index 0f6052439e..ead93b545a 100644 --- a/gui/options.h +++ b/gui/options.h @@ -21,7 +21,7 @@ #ifndef OPTIONS_DIALOG_H #define OPTIONS_DIALOG_H -#include "dialog.h" +#include "gui/dialog.h" #include "common/str.h" #include "common/list.h" @@ -32,36 +32,70 @@ class PopUpWidget; class SliderWidget; class StaticTextWidget; -class GlobalOptionsDialog : public Dialog { +class OptionsDialog : public Dialog { typedef Common::String String; public: - GlobalOptionsDialog(GameDetector &detector); - ~GlobalOptionsDialog(); + OptionsDialog(const String &domain, int x, int y, int w, int h); void open(); -// void close(); + void close(); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + enum { + kOKCmd = 'ok ' + }; + protected: - BrowserDialog *_browser; - StaticTextWidget *_savePath; + /** Config domain this dialog is used to edit. */ + String _domain; + + int addGraphicControls(GuiObject *boss, int yoffset); + int addMIDIControls(GuiObject *boss, int yoffset); + int addVolumeControls(GuiObject *boss, int yoffset); +private: + // + // Graphics controls + // PopUpWidget *_gfxPopUp; CheckboxWidget *_fullscreenCheckbox; CheckboxWidget *_aspectCheckbox; + // + // MIDI controls + // PopUpWidget *_midiPopUp; - SliderWidget *_masterVolumeSlider; - SliderWidget *_musicVolumeSlider; - SliderWidget *_sfxVolumeSlider; + CheckboxWidget *_multiMidiCheckbox; + CheckboxWidget *_mt32Checkbox; + // + // Volume controls + // + SliderWidget *_masterVolumeSlider; StaticTextWidget *_masterVolumeLabel; + + SliderWidget *_musicVolumeSlider; StaticTextWidget *_musicVolumeLabel; + + SliderWidget *_sfxVolumeSlider; StaticTextWidget *_sfxVolumeLabel; +}; - CheckboxWidget *_multiMidiCheckbox; - CheckboxWidget *_mt32Checkbox; + +class GlobalOptionsDialog : public OptionsDialog { + typedef Common::String String; +public: + GlobalOptionsDialog(GameDetector &detector); + ~GlobalOptionsDialog(); + + void open(); + void close(); + void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + +protected: + BrowserDialog *_browser; + StaticTextWidget *_savePath; }; #endif |