new config manager. not everything is completed, and some things will still be changed, but it seems to work well enough to put it into CVS

svn-id: r10687
This commit is contained in:
Max Horn 2003-10-08 21:59:23 +00:00
parent 3c78c0929c
commit d177364715
23 changed files with 910 additions and 805 deletions

35
TODO
View file

@ -6,18 +6,16 @@ General
* Revise the way "quit" is handled. Maybe add a global variable "g_quit" which * Revise the way "quit" is handled. Maybe add a global variable "g_quit" which
we set when the application should be quit (e.g. when an EVENT_QUIT is we set when the application should be quit (e.g. when an EVENT_QUIT is
received). This is useful if multiple levels of event loops have to be ended received). This is useful if multiple levels of event loops have to be ended
* gameDetector.cpp is quite messy. Also, it makes providing native GUI front
ends for ScummVM unnecessarily cumbersome (think of systems which don't
even have a command line, like classic MacOS). It would be nice to better
separate the command line parsing from any GUI and also from the storage
for the user settings (this ties into my proposed config system changes;
ideally, we should be able to drop almost all of the member variables
in the game detector, in favor of getting all these directly from the
config system).
* fix the Map<> template, make it more robust; maybe use a red-black tree? * fix the Map<> template, make it more robust; maybe use a red-black tree?
* add iterators to List<> template and make use of them * add iterators to List<> template and make use of them
* allow for return-to-launcher instead of a normal "quit" ? * allow for return-to-launcher instead of a normal "quit" ?
* turn g_pluginManager into a proper singleton
* improve the argv (command line args) parser
* extend the Plugin API to provide for "game detection": instead of the
TargetSettings::detectname "hack" to detect files, provide a callback
in each Plugin which given a FSList returns a list of candidate targets.
This way, a plugin can implement tests more elaborate than filename
checking, e.g. it could actually peek into the files.
GUI GUI
=== ===
@ -41,18 +39,7 @@ Audio
Config Config
====== ======
* The config system could stand an overhaul
* Preserve comments in config file somehow * Preserve comments in config file somehow
* Add two virtual domains (for command line settings and user overrides);
while we currently do something like this already, our implementation is
a big ugly hack (no offense meant) and has some cumbersome problems. For
example, currently to query a config value, one would have to search up to
four domains manually (user override, command line, game specific, global
application domain, in that order). Ideally all this should be hidden
inside the config system. If you are interested in this, I can elaborate
* Add a way to distinguish if a given key is present at all. That is, it
would be nice if one could distinguish between an explicit "fullscreen=false"
and the absence of any fullscreen config.
* Add a 'notification' system. E.g. the SoundMixer could request to be notified * Add a 'notification' system. E.g. the SoundMixer could request to be notified
whenever the value of the "volume" config option changes. In other words, whenever the value of the "volume" config option changes. In other words,
instead of a "pull" approach (where each subsystem has to check whether any instead of a "pull" approach (where each subsystem has to check whether any
@ -61,6 +48,12 @@ Config
setting is changed, the code doing so has to updated the SoundMixer etc. setting is changed, the code doing so has to updated the SoundMixer etc.
That's cumbersome, and error prone. Would be much nicer if updating the That's cumbersome, and error prone. Would be much nicer if updating the
volume config value automatically notifies the SoundMixer, iMuse etc. volume config value automatically notifies the SoundMixer, iMuse etc.
* Change backends to directly access the config manager
* During the config rewrite, some command line switches were disabled.
Gotta decide what to do about each of them: reimplement, remove, replace?
In particular: -w and -l (those were kind of oddball switches, IMHO);
also -z should be split into two seperate functions (see TODO comment in
GameDetector::list_games())
SCUMM SCUMM
===== =====
@ -89,6 +82,8 @@ SCUMM
2a) If 1) succeeded, file SF.net CVS file rename request 2a) If 1) succeeded, file SF.net CVS file rename request
2b) If 2) failed, do brute force file rename (cp && cvs add && cvs rm) 2b) If 2) failed, do brute force file rename (cp && cvs add && cvs rm)
3) Adjust Makefile and project files to use the new name 3) Adjust Makefile and project files to use the new name
* Possible implement a new resource manager, which then also could be shared
by ScummEX. [Jamieson has some ideas about this and might work on it|
Broken Sword 2 Broken Sword 2
============== ==============

View file

@ -24,7 +24,7 @@
#endif #endif
#include "base/engine.h" #include "base/engine.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "common/timer.h" #include "common/timer.h"
#include "sound/mixer.h" #include "sound/mixer.h"
@ -36,7 +36,7 @@ Engine::Engine(GameDetector *detector, OSystem *syst)
g_engine = this; g_engine = this;
_mixer = detector->createMixer(); _mixer = detector->createMixer();
_gameDataPath = detector->_gameDataPath; _gameDataPath = strdup(ConfMan.get("path").c_str()); // FIXME - leak. Just conver to a String?
_timer = g_timer; _timer = g_timer;
} }
@ -61,11 +61,7 @@ const char *Engine::getSavePath() const {
// If SCUMMVM_SAVEPATH was not specified, try to use game specific savepath from config // If SCUMMVM_SAVEPATH was not specified, try to use game specific savepath from config
if (!dir || dir[0] == 0) if (!dir || dir[0] == 0)
dir = g_config->get("savepath"); dir = ConfMan.get("savepath").c_str();
// If SCUMMVM_SAVEPATH was not specified, try to use general path from config
if (!dir || dir[0] == 0)
dir = g_config->get("savepath", "scummvm");
// If no save path was specified, use no directory prefix // If no save path was specified, use no directory prefix
if (dir == NULL) if (dir == NULL)

View file

@ -27,7 +27,7 @@
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "common/scaler.h" // Only for gfx_modes #include "common/scaler.h" // Only for gfx_modes
#include "sound/mididrv.h" #include "sound/mididrv.h"
@ -69,20 +69,26 @@ static const char USAGE_STRING[] =
" -m<num> - Set music volume to <num> (0-255)\n" " -m<num> - Set music volume to <num> (0-255)\n"
" -o<num> - Set master volume to <num> (0-255)\n" " -o<num> - Set master volume to <num> (0-255)\n"
" -s<num> - Set sfx volume to <num> (0-255)\n" " -s<num> - Set sfx volume to <num> (0-255)\n"
#ifndef DISABLE_SCUMM
" -t<num> - Set music tempo (50-200, default 100%%)\n" " -t<num> - Set music tempo (50-200, default 100%%)\n"
#endif
"\n" "\n"
" -n - No subtitles for speech\n" " -n - No subtitles for speech\n"
#ifndef DISABLE_SCUMM
" -y - Set text speed (default: 60)\n" " -y - Set text speed (default: 60)\n"
#endif
"\n" "\n"
/* FIXME / TODO: config rewrite
" -l<file> - Load config file instead of default\n" " -l<file> - Load config file instead of default\n"
#if defined(UNIX) #if defined(UNIX)
" -w[file] - Write to config file [~/.scummvmrc]\n" " -w[file] - Write to config file [~/.scummvmrc]\n"
#else #else
" -w[file] - Write to config file [scummvm.ini]\n" " -w[file] - Write to config file [scummvm.ini]\n"
#endif #endif
*/
" -v - Show version info and exit\n" " -v - Show version info and exit\n"
" -h - Display this text and exit\n" " -h - Display this text and exit\n"
" -z - Display list of games\n" " -z - Display list of supported games\n"
"\n" "\n"
" -b<num> - Pass number to the boot script (boot param)\n" " -b<num> - Pass number to the boot script (boot param)\n"
" -d[num] - Enable debug output (debug level [0])\n" " -d[num] - Enable debug output (debug level [0])\n"
@ -143,13 +149,13 @@ static const struct GraphicsMode gfx_modes[] = {
{0, 0, 0} {0, 0, 0}
}; };
struct Language { struct LanguageDescription {
const char *name; const char *name;
const char *description; const char *description;
int id; Language id;
}; };
static const struct Language languages[] = { static const struct LanguageDescription languages[] = {
{"en", "English", EN_USA}, {"en", "English", EN_USA},
{"de", "German", DE_DEU}, {"de", "German", DE_DEU},
{"fr", "French", FR_FRA}, {"fr", "French", FR_FRA},
@ -162,162 +168,105 @@ static const struct Language languages[] = {
{"gb", "English", EN_GRB}, {"gb", "English", EN_GRB},
{"se", "Swedish", SE_SWE}, {"se", "Swedish", SE_SWE},
{"hb", "Hebrew", HB_HEB}, {"hb", "Hebrew", HB_HEB},
{0, 0, 0} {0, 0, UNK_LANG}
}; };
GameDetector::GameDetector() { GameDetector::GameDetector() {
_fullScreen = false;
_aspectRatio = false;
_master_volume = kDefaultMasterVolume; // Graphics
_music_volume = kDefaultMusicVolume; ConfMan.registerDefault("fullscreen", false);
_sfx_volume = kDefaultSFXVolume; ConfMan.registerDefault("aspect_ratio", false);
_amiga = false; #ifndef _WIN32_WCE
_platform = 0; ConfMan.registerDefault("gfx_mode", "2x");
_language = 0; #else
ConfMan.registerDefault("gfx_mode", "normal");
#endif
// Sound & Music
ConfMan.registerDefault("master_volume", kDefaultMasterVolume);
ConfMan.registerDefault("music_volume", kDefaultMusicVolume);
ConfMan.registerDefault("sfx_volume", kDefaultSFXVolume);
ConfMan.registerDefault("multi_midi", false);
ConfMan.registerDefault("native_mt32", false);
// ConfMan.registerDefault("music_driver", ???);
ConfMan.registerDefault("cdrom", 0);
// Game specifc
ConfMan.registerDefault("path", "");
ConfMan.registerDefault("amiga", false);
ConfMan.registerDefault("platform", kPlatformPC);
ConfMan.registerDefault("language", "en");
ConfMan.registerDefault("nosubtitles", false);
ConfMan.registerDefault("boot_param", 0);
ConfMan.registerDefault("save_slot", -1);
#ifndef DISABLE_SCUMM #ifndef DISABLE_SCUMM
_demo_mode = false; ConfMan.registerDefault("demo_mode", false);
ConfMan.registerDefault("talkspeed", 60);
ConfMan.registerDefault("tempo", 0);
#endif #endif
#ifndef DISABLE_SKY #ifndef DISABLE_SKY
_floppyIntro = false; ConfMan.registerDefault("floppy_intro", false);
#endif #endif
_talkSpeed = 60; // Miscellaneous
_debugMode = 0; ConfMan.registerDefault("debuglevel", 0);
_debugLevel = 0; ConfMan.registerDefault("joystick_num", -1);
_dumpScripts = 0; ConfMan.registerDefault("confirm_exit", false);
_noSubtitles = false;
_bootParam = 0;
_gameDataPath = 0; _debugMode = false;
_gameTempo = 0; _dumpScripts = false;
_midi_driver = MD_AUTO; _midi_driver = MD_AUTO;
_game.features = 0;
_plugin = 0;
_multi_midi = false;
_native_mt32 = false;
_cdrom = 0;
_joystick_num = 0;
_save_slot = 0;
_saveconfig = false; _saveconfig = false;
_confirmExit = false;
#ifndef _WIN32_WCE _game.features = 0;
_gfx_mode = GFX_DOUBLESIZE; _plugin = 0;
#else
_gfx_mode = GFX_NORMAL;
#endif
_default_gfx_mode = true;
}
void GameDetector::updateconfig() {
const char *val;
_amiga = g_config->getBool("amiga", _amiga);
_platform = g_config->getInt("platform", _platform);
_save_slot = g_config->getInt("save_slot", _save_slot);
_joystick_num = g_config->getInt("joystick_num", _joystick_num);
_cdrom = g_config->getInt("cdrom", _cdrom);
_bootParam = g_config->getInt("boot_param", _bootParam);
if ((val = g_config->get("music_driver")))
if (!parseMusicDriver(val)) {
printf("Error in the config file: invalid music_driver.\n");
printf(USAGE_STRING);
exit(-1);
}
_fullScreen = g_config->getBool("fullscreen", _fullScreen);
_aspectRatio = g_config->getBool("aspect_ratio", _aspectRatio);
if ((val = g_config->get("gfx_mode")))
if ((_gfx_mode = parseGraphicsMode(val)) == -1) {
printf("Error in the config file: invalid gfx_mode.\n");
printf(USAGE_STRING);
exit(-1);
}
#ifndef DISABLE_SKY
_floppyIntro = g_config->getBool("floppy_intro", _floppyIntro);
#endif
#ifndef DISABLE_SCUMM
_demo_mode = g_config->getBool("demo_mode", _demo_mode);
#endif
if ((val = g_config->get("language")))
if ((_language = parseLanguage(val)) == -1) {
printf("Error in the config file: invalid language.\n");
printf(USAGE_STRING);
exit(-1);
}
_master_volume = g_config->getInt("master_volume", _master_volume);
_music_volume = g_config->getInt("music_volume", _music_volume);
_noSubtitles = g_config->getBool("nosubtitles", _noSubtitles ? true : false);
if ((val = g_config->get("path")))
_gameDataPath = strdup(val);
_sfx_volume = g_config->getInt("sfx_volume", _sfx_volume);
_debugLevel = g_config->getInt("debuglevel", _debugLevel);
if (_debugLevel)
_debugMode = true;
// We use strtol for the tempo to allow it to be specified in hex.
if ((val = g_config->get("tempo")))
_gameTempo = strtol(val, NULL, 0);
_talkSpeed = g_config->getInt("talkspeed", _talkSpeed);
_confirmExit = g_config->getBool("confirm_exit", _confirmExit ? true : false);
_multi_midi = g_config->getBool ("multi_midi", _multi_midi);
_native_mt32 = g_config->getBool ("native_mt32", _native_mt32);
} }
void GameDetector::list_games() { void GameDetector::list_games() {
// FIXME / TODO: config rewrite
// Right now this lists all known built-in targets; and also for each of
// those it tells the user if the target is "configured".
// To me this seems like an ill mix of two different functionalities.
// IMHO we should split this into two seperate commands/options:
// 1) List all built-in gameids (e.g. monkey, atlantis, ...) similiar to
// what this code does, but without the "Config" column.
// 2) List all available (configured) targets, including those with custom
// names, e.g. "monkey-mac", "skycd-demo", ...
const PluginList &plugins = g_pluginManager->getPlugins(); const PluginList &plugins = g_pluginManager->getPlugins();
const TargetSettings *v; const TargetSettings *v;
const char *config;
printf("Game Full Title Config\n" printf("Game Full Title \n"
"---------------- ------------------------------------------------------ -------\n"); "---------------- ------------------------------------------------------\n");
PluginList::ConstIterator iter = plugins.begin(); PluginList::ConstIterator iter = plugins.begin();
for (iter = plugins.begin(); iter != plugins.end(); ++iter) { for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
v = (*iter)->getTargets(); v = (*iter)->getTargets();
while (v->targetName && v->description) { while (v->targetName && v->description) {
config = (g_config->has_domain(v->targetName)) ? "Yes" : ""; #if 1
printf("%-17s%-56s\n", v->targetName, v->description);
#else
const char *config = (g_config->has_domain(v->targetName)) ? "Yes" : "";
printf("%-17s%-56s%s\n", v->targetName, v->description, config); printf("%-17s%-56s%s\n", v->targetName, v->description, config);
#endif
v++; v++;
} }
} }
} }
const TargetSettings *GameDetector::findTarget(const char *targetName, const Plugin **plugin) const { const TargetSettings *GameDetector::findTarget(const String &targetName, const Plugin **plugin) const {
// Find the TargetSettings for this target // Find the TargetSettings for this target
assert(targetName);
const TargetSettings *target; const TargetSettings *target;
const PluginList &plugins = g_pluginManager->getPlugins(); const PluginList &plugins = g_pluginManager->getPlugins();
PluginList::ConstIterator iter = plugins.begin(); PluginList::ConstIterator iter = plugins.begin();
for (iter = plugins.begin(); iter != plugins.end(); ++iter) { for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
target = (*iter)->findTarget(targetName); target = (*iter)->findTarget(targetName.c_str());
if (target) { if (target) {
if (plugin) if (plugin)
*plugin = *iter; *plugin = *iter;
@ -334,12 +283,15 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
char *option = NULL; char *option = NULL;
char c; char c;
bool long_option_value; bool long_option_value;
_save_slot = -1;
_joystick_num = -1;
// Parse the arguments // Iterate over all comman line arguments, backwards.
// into a transient "_COMMAND_LINE" config comain. // FIXME: Looping backwards has a major problem: Consider this example
g_config->set_domain ("_COMMAND_LINE"); // invocation: "scummvm -g 1x". It should work exactly like "scummvm -g1x"
// but it doesn't! Instead of starting the launcher with the 1x sacler
// in effect, it will give an error about target 1x being unknown.
// This can be fixed by forward iterating the args. Of course doing that
// essentially means we have to rewrite the whole command line parser,
// but that seems like a good idea anyway.
for (i = argc - 1; i >= 1; i--) { for (i = argc - 1; i >= 1; i--) {
s = argv[i]; s = argv[i];
@ -349,20 +301,19 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
switch (tolower(c)) { switch (tolower(c)) {
case 'b': case 'b':
HANDLE_OPTION(); HANDLE_OPTION();
_bootParam = atoi(option); ConfMan.set("boot_param", (int)strtol(option, 0, 10));
break; break;
case 'c': case 'c':
HANDLE_OPTION(); HANDLE_OPTION();
_cdrom = atoi(option); ConfMan.set("cdrom", (int)strtol(option, 0, 10));
g_config->setInt("cdrom", _cdrom);
break; break;
case 'd': case 'd':
_debugMode = true; _debugMode = true;
HANDLE_OPT_OPTION(); HANDLE_OPT_OPTION();
if (option != NULL) if (option != NULL)
_debugLevel = atoi(option); ConfMan.set("debuglevel", (int)strtol(option, 0, 10));
if (_debugLevel) { if (ConfMan.getInt("debuglevel")) {
printf("Debuglevel (from command line): %d\n", _debugLevel); printf("Debuglevel (from command line): %d\n", ConfMan.getInt("debuglevel"));
} else { } else {
printf("Debuglevel (from command line): 0 - Engine only\n"); printf("Debuglevel (from command line): 0 - Engine only\n");
} }
@ -373,37 +324,31 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
// maybe print a message like: // maybe print a message like:
// "'option' is not a supported music driver on this machine. // "'option' is not a supported music driver on this machine.
// Available driver: ..." // Available driver: ..."
if (!parseMusicDriver(option)) if (parseMusicDriver(option) < 0)
goto ShowHelpAndExit; goto ShowHelpAndExit;
g_config->set("music_driver", option); ConfMan.set("music_driver", option);
break; break;
case 'f': case 'f':
CHECK_OPTION(); CHECK_OPTION();
_fullScreen = (c == 'f'); ConfMan.set("fullscreen", (c == 'f'));
g_config->setBool("fullscreen", _fullScreen);
g_config->setBool("fullscreen", _fullScreen, "scummvm");
break; break;
case 'g': case 'g':{
HANDLE_OPTION(); HANDLE_OPTION();
_gfx_mode = parseGraphicsMode(option); int _gfx_mode = parseGraphicsMode(option);
// TODO: Instead of just showing the generic help text, // TODO: Instead of just showing the generic help text,
// maybe print a message like: // maybe print a message like:
// "'option' is not a supported graphic mode on this machine. // "'option' is not a supported graphic mode on this machine.
// Available graphic modes: ..." // Available graphic modes: ..."
if (_gfx_mode == -1) if (_gfx_mode == -1)
goto ShowHelpAndExit; goto ShowHelpAndExit;
g_config->set("gfx_mode", option); ConfMan.set("gfx_mode", option);
g_config->set("gfx_mode", option, "scummvm"); break;}
break;
// case 'h': reserved for help // case 'h': reserved for help
case 'j': case 'j':
_joystick_num = 0;
HANDLE_OPT_OPTION(); HANDLE_OPT_OPTION();
if (option != NULL) { ConfMan.set("joystick_num", (option != NULL) ? (int)strtol(option, 0, 10) : 0);
_joystick_num = atoi(option);
g_config->setInt("joystick_num", _joystick_num);
}
break; break;
/* FIXME / TODO: config rewrite
case 'l': case 'l':
HANDLE_OPTION(); HANDLE_OPTION();
{ {
@ -414,47 +359,43 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
break; break;
} }
break; break;
*/
case 'm': case 'm':
HANDLE_OPTION(); HANDLE_OPTION();
_music_volume = atoi(option); ConfMan.set("music_volume", (int)strtol(option, 0, 10));
g_config->setInt("music_volume", _music_volume);
break; break;
case 'n': case 'n':
CHECK_OPTION(); CHECK_OPTION();
_noSubtitles = (c == 'n'); ConfMan.set("nosubtitles", (c == 'n'));
g_config->setBool("nosubtitles", _noSubtitles ? true : false);
break; break;
case 'o': case 'o':
HANDLE_OPTION(); HANDLE_OPTION();
_master_volume = atoi(option); ConfMan.set("master_volume", (int)strtol(option, 0, 10));
g_config->setInt("master_volume", _master_volume);
break; break;
case 'p': case 'p':
HANDLE_OPTION(); HANDLE_OPTION();
_gameDataPath = option; // TODO: Verify path is valid
g_config->set("path", _gameDataPath); ConfMan.set("path", option);
break; break;
case 'q': case 'q':
HANDLE_OPTION(); HANDLE_OPTION();
_language = parseLanguage(option); if (parseLanguage(option) == UNK_LANG)
if (_language == -1)
goto ShowHelpAndExit; goto ShowHelpAndExit;
g_config->set("language", option); ConfMan.set("language", option);
break;
case 'r':
HANDLE_OPTION();
// Ignore -r for now, to ensure backward compatibility.
break; break;
case 's': case 's':
HANDLE_OPTION(); HANDLE_OPTION();
_sfx_volume = atoi(option); ConfMan.set("sfx_volume", (int)strtol(option, 0, 10));
g_config->setInt("sfx_volume", _sfx_volume);
break; break;
#ifndef DISABLE_SCUMM
case 't': case 't':
HANDLE_OPTION(); HANDLE_OPTION();
_gameTempo = strtol(option, 0, 0); // Use the special value '0' for the base in (int)strtol.
g_config->set("tempo", option); // Doing that makes it possible to enter hex values
// as "0x1234", but also decimal values ("123").
ConfMan.set("tempo", (int)strtol(option, 0, 0));
break; break;
#endif
case 'u': case 'u':
CHECK_OPTION(); CHECK_OPTION();
_dumpScripts = true; _dumpScripts = true;
@ -462,7 +403,9 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
case 'v': case 'v':
CHECK_OPTION(); CHECK_OPTION();
printf("%s\n", gScummVMFullVersion); printf("%s\n", gScummVMFullVersion);
exit(1); exit(0);
break;
/* FIXME / TODO: config rewrite
case 'w': case 'w':
_saveconfig = true; _saveconfig = true;
g_config->set_writing(true); g_config->set_writing(true);
@ -470,19 +413,17 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
if (option != NULL) if (option != NULL)
g_config->set_filename(option); g_config->set_filename(option);
break; break;
*/
case 'x': case 'x':
_save_slot = 0;
HANDLE_OPT_OPTION(); HANDLE_OPT_OPTION();
if (option != NULL) { ConfMan.set("save_slot", (option != NULL) ? (int)strtol(option, 0, 10) : 0);
_save_slot = atoi(option);
g_config->setInt("save_slot", _save_slot);
}
break; break;
#ifndef DISABLE_SCUMM
case 'y': case 'y':
HANDLE_OPTION(); HANDLE_OPTION();
_talkSpeed = atoi(option); ConfMan.set("talkspeed", (int)strtol(option, 0, 10));
g_config->setInt("talkspeed", _talkSpeed);
break; break;
#endif
case 'z': case 'z':
CHECK_OPTION(); CHECK_OPTION();
list_games(); list_games();
@ -491,16 +432,11 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
// Long options. Let the fun begin! // Long options. Let the fun begin!
if (!strncmp(s, "platform=", 9)) { if (!strncmp(s, "platform=", 9)) {
s += 9; s += 9;
if (!strcmp (s, "amiga")) int platform = parsePlatform(s);
_platform = 1; if (platform == kPlatformUnknown)
else if (!strcmp (s, "atari-st"))
_platform = 2;
else if (!strcmp (s, "macintosh"))
_platform = 3;
else
goto ShowHelpAndExit; goto ShowHelpAndExit;
g_config->setInt ("platform", _platform); ConfMan.set("platform", platform);
break; break;
} }
@ -511,28 +447,21 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
long_option_value = true; long_option_value = true;
if (!strcmp (s, "multi-midi")) { if (!strcmp (s, "multi-midi")) {
_multi_midi = long_option_value; ConfMan.set("multi_midi", long_option_value);
g_config->setBool ("multi_midi", _multi_midi);
} else if (!strcmp (s, "native-mt32")) { } else if (!strcmp (s, "native-mt32")) {
_native_mt32 = long_option_value; ConfMan.set("native_mt32", long_option_value);
g_config->setBool ("native_mt32", _native_mt32);
} else if (!strcmp (s, "aspect-ratio")) { } else if (!strcmp (s, "aspect-ratio")) {
_aspectRatio = long_option_value; ConfMan.set("aspect_ratio", long_option_value);
g_config->setBool ("aspect_ratio", _aspectRatio);
} else if (!strcmp (s, "fullscreen")) { } else if (!strcmp (s, "fullscreen")) {
_fullScreen = long_option_value; ConfMan.set("fullscreen", long_option_value);
g_config->setBool("fullscreen", _fullScreen);
g_config->setBool("fullscreen", _fullScreen, "scummvm");
#ifndef DISABLE_SCUMM #ifndef DISABLE_SCUMM
} else if (!strcmp (s, "demo-mode")) { } else if (!strcmp (s, "demo-mode")) {
_demo_mode = long_option_value; ConfMan.set("demo_mode", long_option_value);
g_config->setBool ("demo_mode", _demo_mode);
#endif #endif
#ifndef DISABLE_SKY #ifndef DISABLE_SKY
} else if (!strcmp (s, "floppy-intro")) { } else if (!strcmp (s, "floppy-intro")) {
_floppyIntro = long_option_value; ConfMan.set("floppy_intro", long_option_value);
g_config->setBool ("floppy_intro", _floppyIntro);
#endif #endif
} else { } else {
goto ShowHelpAndExit; goto ShowHelpAndExit;
@ -553,8 +482,10 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
} }
} }
/* FIXME / TODO: config rewrite
if (!_gameFileName.isEmpty()) if (!_gameFileName.isEmpty())
g_config->flush(); ConfMan.flushToDisk();
*/
return; return;
@ -565,29 +496,14 @@ ShowHelpAndExit:
void GameDetector::setGame(const String &name) { void GameDetector::setGame(const String &name) {
_gameFileName = name; _gameFileName = name;
g_config->set_domain(name); ConfMan.setActiveDomain(name);
g_config->rename_domain(name, "game-specific");
g_config->rename_domain("game-specific", name);
updateconfig();
// The command line and launcher options
// override config file global and game-specific options.
g_config->set_domain("_COMMAND_LINE");
updateconfig();
g_config->set_domain("_USER_OVERRIDES");
updateconfig();
g_config->delete_domain("_COMMAND_LINE");
g_config->delete_domain("_USER_OVERRIDES");
g_config->set_domain(name);
if (_debugMode)
printf("Debuglevel (from config): %d\n", _debugLevel);
} }
int GameDetector::parseGraphicsMode(const char *s) { int GameDetector::parseGraphicsMode(const String &str) {
const char *s = str.c_str();
const GraphicsMode *gm = gfx_modes; const GraphicsMode *gm = gfx_modes;
while (gm->name) { while (gm->name) {
if (!scumm_stricmp(gm->name, s)) { if (!scumm_stricmp(gm->name, s)) {
_default_gfx_mode = false;
return gm->id; return gm->id;
} }
gm++; gm++;
@ -596,50 +512,65 @@ int GameDetector::parseGraphicsMode(const char *s) {
return -1; return -1;
} }
int GameDetector::parseLanguage(const char *s) { Language GameDetector::parseLanguage(const String &str) {
const Language *l = languages; const char *s = str.c_str();
const LanguageDescription *l = languages;
while (l->name) { while (l->name) {
if (!scumm_stricmp(l->name, s)) if (!scumm_stricmp(l->name, s))
return l->id; return l->id;
l++; l++;
} }
return -1; return UNK_LANG;
} }
bool GameDetector::parseMusicDriver(const char *s) { Platform GameDetector::parsePlatform(const String &str) {
const char *s = str.c_str();
if (!scumm_stricmp(s, "pc"))
return kPlatformPC;
else if (!scumm_stricmp(s, "amiga") || !scumm_stricmp(s, "1"))
return kPlatformAmiga;
else if (!scumm_stricmp(s, "atari-st") || !scumm_stricmp(s, "atari") || !scumm_stricmp(s, "2"))
return kPlatformAtariST;
else if (!scumm_stricmp(s, "macintosh") || !scumm_stricmp(s, "mac") || !scumm_stricmp(s, "3"))
return kPlatformMacintosh;
else
return kPlatformUnknown;
}
int GameDetector::parseMusicDriver(const String &str) {
const char *s = str.c_str();
const MidiDriverDescription *md = getAvailableMidiDrivers(); const MidiDriverDescription *md = getAvailableMidiDrivers();
while (md->name) { while (md->name) {
if (!scumm_stricmp(md->name, s)) { if (!scumm_stricmp(md->name, s)) {
_midi_driver = md->id; return md->id;
return true;
} }
md++; md++;
} }
return false; return -1;
} }
bool GameDetector::detectGame() { bool GameDetector::detectGame() {
const TargetSettings *target; const TargetSettings *target;
const char *realGame, *basename; String realGame;
_gameText.clear();
realGame = g_config->get("gameid"); if (ConfMan.hasKey("gameid"))
if (!realGame) realGame = ConfMan.get("gameid");
realGame = _gameFileName.c_str(); else
printf("Looking for %s\n", realGame); realGame = _gameFileName;
printf("Looking for %s\n", realGame.c_str());
target = findTarget(realGame, &_plugin); target = findTarget(realGame, &_plugin);
if (target) { if (target) {
_game = *target; _game = *target;
if ((basename = g_config->get("basename"))) { if (ConfMan.hasKey("basename")) {
// FIXME: What is this good for? // FIXME: What is this good for?
_game.targetName = basename; // FIXME: This leaks now!
_game.targetName = strdup(ConfMan.get("basename").c_str());
} }
_gameText = _game.description;
printf("Trying to start game '%s'\n", _game.description); printf("Trying to start game '%s'\n", _game.description);
return true; return true;
} else { } else {
@ -648,15 +579,6 @@ bool GameDetector::detectGame() {
} }
} }
const Common::String& GameDetector::getGameName() {
if (_gameText.isEmpty()) {
_gameText = "Unknown game: \"";
_gameText += _gameFileName;
_gameText += "\"";
}
return _gameText;
}
bool GameDetector::detectMain() { bool GameDetector::detectMain() {
if (_gameFileName.isEmpty()) { if (_gameFileName.isEmpty()) {
warning("No game was specified..."); warning("No game was specified...");
@ -672,7 +594,8 @@ bool GameDetector::detectMain() {
* and the game is one of those that want adlib as * and the game is one of those that want adlib as
* default, OR if the game is an older game that doesn't * default, OR if the game is an older game that doesn't
* support anything else anyway. */ * support anything else anyway. */
if (_midi_driver == MD_AUTO) { _midi_driver = parseMusicDriver(ConfMan.get("music_driver"));
if (_midi_driver == MD_AUTO || _midi_driver < 0) {
if (_game.midi & MDT_PREFER_NATIVE) if (_game.midi & MDT_PREFER_NATIVE)
_midi_driver = getMidiDriverType(); _midi_driver = getMidiDriverType();
else else
@ -691,21 +614,17 @@ bool GameDetector::detectMain() {
if ((_midi_driver == MD_PCSPK || _midi_driver == MD_PCJR) && !(_game.midi & MDT_PCSPK)) if ((_midi_driver == MD_PCSPK || _midi_driver == MD_PCJR) && !(_game.midi & MDT_PCSPK))
_midi_driver = MD_NULL; _midi_driver = MD_NULL;
if (!_gameDataPath) { String gameDataPath(ConfMan.get("path"));
if (gameDataPath.isEmpty()) {
warning("No path was provided. Assuming the data files are in the current directory"); warning("No path was provided. Assuming the data files are in the current directory");
_gameDataPath = strdup("");
#ifndef __PALM_OS__ // add last slash also in File::fopenNoCase, so this is not needed #ifndef __PALM_OS__ // add last slash also in File::fopenNoCase, so this is not needed
} else if (_gameDataPath[strlen(_gameDataPath)-1] != '/' } else if (gameDataPath.lastChar() != '/'
#ifdef __MORPHOS__ #ifdef __MORPHOS__
&& _gameDataPath[strlen(_gameDataPath)-1] != ':' && gameDataPath.lastChar() != ':'
#endif #endif
&& _gameDataPath[strlen(_gameDataPath)-1] != '\\') { && gameDataPath.lastChar() != '\\') {
char slashless[1024]; /* Append slash to path */ gameDataPath += '/';
strcpy(slashless, _gameDataPath); ConfMan.set("path", gameDataPath);
// need to allocate 2 extra bytes, one for the "/" and one for the NULL terminator
_gameDataPath = (char *)malloc((strlen(slashless) + 2) * sizeof(char));
sprintf(_gameDataPath, "%s/", slashless);
#endif #endif
} }
@ -713,6 +632,8 @@ bool GameDetector::detectMain() {
} }
OSystem *GameDetector::createSystem() { OSystem *GameDetector::createSystem() {
int _gfx_mode = parseGraphicsMode(ConfMan.get("gfx_mode")); // FIXME: Get rid of this again!
#if defined(USE_NULL_DRIVER) #if defined(USE_NULL_DRIVER)
return OSystem_NULL_create(); return OSystem_NULL_create();
#elif defined(__DC__) #elif defined(__DC__)
@ -720,18 +641,18 @@ OSystem *GameDetector::createSystem() {
#elif defined(X11_BACKEND) #elif defined(X11_BACKEND)
return OSystem_X11_create(); return OSystem_X11_create();
#elif defined(__MORPHOS__) #elif defined(__MORPHOS__)
return OSystem_MorphOS_create(_gfx_mode, _fullScreen); return OSystem_MorphOS_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#elif defined(_WIN32_WCE) #elif defined(_WIN32_WCE)
return OSystem_WINCE3_create(); return OSystem_WINCE3_create();
#elif defined(MACOS_CARBON) #elif defined(MACOS_CARBON)
return OSystem_MAC_create(_gfx_mode, _fullScreen); return OSystem_MAC_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#elif defined(__GP32__) // ph0x #elif defined(__GP32__) // ph0x
return OSystem_GP32_create(GFX_NORMAL, true); return OSystem_GP32_create(GFX_NORMAL, true);
#elif defined(__PALM_OS__) //chrilith #elif defined(__PALM_OS__) //chrilith
return OSystem_PALMOS_create(_gfx_mode, _fullScreen); return OSystem_PALMOS_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#else #else
/* SDL is the default driver for now */ /* SDL is the default driver for now */
return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatio, _joystick_num); return OSystem_SDL_create(_gfx_mode, ConfMan.getBool("fullscreen"), ConfMan.getBool("aspect_ratio"), ConfMan.getBool("joystick_num"));
#endif #endif
} }

View file

@ -51,7 +51,8 @@ enum {
* @note The order and mappings of the values 0..8 are *required* to stay the * @note The order and mappings of the values 0..8 are *required* to stay the
* way they are now, as scripts in COMI rely on them. So don't touch them. * way they are now, as scripts in COMI rely on them. So don't touch them.
*/ */
enum { enum Language {
UNK_LANG = -1, // Use default language (i.e. none specified)
EN_USA = 0, EN_USA = 0,
DE_DEU = 1, DE_DEU = 1,
FR_FRA = 2, FR_FRA = 2,
@ -66,6 +67,14 @@ enum {
HB_HEB = 20 HB_HEB = 20
}; };
enum Platform {
kPlatformUnknown = -1,
kPlatformPC = 0,
kPlatformAmiga = 1,
kPlatformAtariST = 2,
kPlatformMacintosh = 3
};
enum MidiDriverType { enum MidiDriverType {
MDT_NONE = 0, MDT_NONE = 0,
MDT_PCSPK = 1, // MD_PCSPK and MD_PCJR MDT_PCSPK = 1, // MD_PCSPK and MD_PCJR
@ -92,49 +101,16 @@ public:
void parseCommandLine(int argc, char **argv); void parseCommandLine(int argc, char **argv);
bool detectMain(); bool detectMain();
void setGame(const String &name);
const String& getGameName(void);
String _gameFileName; String _gameFileName;
TargetSettings _game; TargetSettings _game;
const Plugin *_plugin; const Plugin *_plugin;
bool _fullScreen; bool _debugMode;
bool _aspectRatio;
int _master_volume;
int _music_volume;
int _sfx_volume;
bool _amiga;
int _platform;
int _language;
bool _demo_mode;
bool _floppyIntro;
uint16 _talkSpeed;
uint16 _debugMode;
uint16 _debugLevel;
bool _dumpScripts; bool _dumpScripts;
bool _noSubtitles;
uint16 _bootParam;
char *_gameDataPath;
int _gameTempo;
int _midi_driver;
int _gfx_mode;
bool _default_gfx_mode;
bool _multi_midi;
bool _native_mt32;
int _cdrom;
int _joystick_num;
int _save_slot;
bool _saveconfig; bool _saveconfig;
bool _confirmExit;
int _midi_driver;
public: public:
OSystem *createSystem(); OSystem *createSystem();
@ -142,19 +118,19 @@ public:
SoundMixer *createMixer(); SoundMixer *createMixer();
MidiDriver *createMidi(); MidiDriver *createMidi();
int getMidiDriverType(); int getMidiDriverType(); // FIXME: Try to get rid of this, only Sky frontend uses it
int parseGraphicsMode(const char *s); void setGame(const String &name);
void updateconfig();
const TargetSettings *findTarget(const char *targetName, const Plugin **plugin = NULL) const; static int parseGraphicsMode(const String &s); // Used in main()
static int parseMusicDriver(const String &s);
static Language parseLanguage(const String &s);
static Platform parsePlatform(const String &s);
const TargetSettings *findTarget(const String &targetName, const Plugin **plugin = NULL) const;
protected: protected:
String _gameText;
bool detectGame(void); bool detectGame(void);
bool parseMusicDriver(const char *s);
int parseLanguage(const char *s);
void list_games(); void list_games();
}; };

View file

@ -32,7 +32,7 @@
#include "base/engine.h" #include "base/engine.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "common/scaler.h" // For GFX_NORMAL #include "common/scaler.h" // For GFX_NORMAL
#include "common/timer.h" #include "common/timer.h"
#include "gui/newgui.h" #include "gui/newgui.h"
@ -83,7 +83,6 @@ const char *gScummVMBuildDate = __DATE__ " " __TIME__;
const char *gScummVMFullVersion = "ScummVM 0.5.4cvs (" __DATE__ " " __TIME__ ")"; const char *gScummVMFullVersion = "ScummVM 0.5.4cvs (" __DATE__ " " __TIME__ ")";
Config *g_config = 0;
NewGui *g_gui = 0; NewGui *g_gui = 0;
OSystem *g_system = 0; OSystem *g_system = 0;
@ -108,20 +107,6 @@ extern "C" int main(int argc, char *argv[]);
#include "allegro.h" #include "allegro.h"
#endif #endif
#if defined(UNIX)
#include <sys/param.h>
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#ifdef MACOSX
#define DEFAULT_CONFIG_FILE "Library/Preferences/ScummVM Preferences"
#else
#define DEFAULT_CONFIG_FILE ".scummvmrc"
#endif
#else
#define DEFAULT_CONFIG_FILE "scummvm.ini"
#endif
#if defined(UNIX) #if defined(UNIX)
#include <signal.h> #include <signal.h>
@ -211,23 +196,6 @@ int main(int argc, char *argv[]) {
#if defined(UNIX) #if defined(UNIX)
/* On Unix, do a quick endian / alignement check before starting */ /* On Unix, do a quick endian / alignement check before starting */
do_memory_test(); do_memory_test();
char scummhome[MAXPATHLEN];
if(getenv("HOME") != NULL)
sprintf(scummhome,"%s/%s", getenv("HOME"), DEFAULT_CONFIG_FILE);
else strcpy(scummhome,DEFAULT_CONFIG_FILE);
#else
char scummhome[256];
#if defined (WIN32) && !defined(_WIN32_WCE)
GetWindowsDirectory(scummhome, 256);
strcat(scummhome, "\\");
strcat(scummhome, DEFAULT_CONFIG_FILE);
#elif defined(__PALM_OS__)
strcpy(scummhome,"/PALM/Programs/ScummVM/");
strcat(scummhome, DEFAULT_CONFIG_FILE);
#else
strcpy(scummhome, DEFAULT_CONFIG_FILE);
#endif
#endif #endif
// Code copied from SDL_main // Code copied from SDL_main
@ -265,9 +233,8 @@ int main(int argc, char *argv[]) {
#endif //defined(WIN32) && defined(USE_CONSOLE) #endif //defined(WIN32) && defined(USE_CONSOLE)
// Read the config file // Update the config file
g_config = new Config(scummhome, "scummvm"); ConfMan.set("versioninfo", gScummVMVersion, "scummvm");
g_config->set("versioninfo", gScummVMVersion);
// Load the plugins // Load the plugins
g_pluginManager = new PluginManager(); g_pluginManager = new PluginManager();
@ -276,7 +243,6 @@ int main(int argc, char *argv[]) {
// Parse the command line information // Parse the command line information
GameDetector detector; GameDetector detector;
detector._saveconfig = false; detector._saveconfig = false;
detector.updateconfig();
detector.parseCommandLine(argc, argv); detector.parseCommandLine(argc, argv);
// Create the system object // Create the system object
@ -301,9 +267,10 @@ int main(int argc, char *argv[]) {
if (detector.detectMain()) { if (detector.detectMain()) {
// Set the window caption to the game name // Set the window caption to the game name
prop.caption = g_config->get("description", detector._gameFileName); prop.caption = ConfMan.get("description", detector._gameFileName).c_str();
if (prop.caption == NULL) if (prop.caption == NULL)
prop.caption = detector.getGameName().c_str(); prop.caption = detector._gameFileName.c_str();
if (prop.caption != NULL)
system->property(OSystem::PROP_SET_WINDOW_CAPTION, &prop); system->property(OSystem::PROP_SET_WINDOW_CAPTION, &prop);
// FIXME: It seem not logical that we first might set the gfx mode to // FIXME: It seem not logical that we first might set the gfx mode to
@ -311,20 +278,19 @@ int main(int argc, char *argv[]) {
// should combine both checks into one. // should combine both checks into one.
// See if the game should default to 1x scaler // See if the game should default to 1x scaler
if ((detector._default_gfx_mode) && if (!ConfMan.hasKey("gfx_mode", detector._gameFileName) &&
(detector._game.features & GF_DEFAULT_TO_1X_SCALER)) { (detector._game.features & GF_DEFAULT_TO_1X_SCALER)) {
prop.gfx_mode = GFX_NORMAL; prop.gfx_mode = GFX_NORMAL;
system->property(OSystem::PROP_SET_GFX_MODE, &prop); system->property(OSystem::PROP_SET_GFX_MODE, &prop);
} } else
// Override global scaler with any game-specific define // Override global scaler with any game-specific define
if (g_config->get("gfx_mode")) { if (ConfMan.hasKey("gfx_mode")) {
prop.gfx_mode = detector.parseGraphicsMode(g_config->get("gfx_mode")); prop.gfx_mode = detector.parseGraphicsMode(ConfMan.get("gfx_mode"));
system->property(OSystem::PROP_SET_GFX_MODE, &prop); system->property(OSystem::PROP_SET_GFX_MODE, &prop);
} }
// Override global fullscreen setting with any game-specific define // Override global fullscreen setting with any game-specific define
if (g_config->getBool("fullscreen", false)) { if (ConfMan.getBool("fullscreen")) {
if (!system->property(OSystem::PROP_GET_FULLSCREEN, 0)) if (!system->property(OSystem::PROP_GET_FULLSCREEN, 0))
system->property(OSystem::PROP_TOGGLE_FULLSCREEN, 0); system->property(OSystem::PROP_TOGGLE_FULLSCREEN, 0);
} }
@ -344,7 +310,6 @@ int main(int argc, char *argv[]) {
} }
delete g_gui; delete g_gui;
delete g_config;
// ...and quit (the return 0 should never be reached) // ...and quit (the return 0 should never be reached)
system->quit(); system->quit();

View file

@ -1,240 +0,0 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "stdafx.h"
#include "common/config-file.h"
#include "base/engine.h" // for debug()
#define MAXLINELEN 256
static char *ltrim(char *t) {
while (*t == ' ')
t++;
return t;
}
static char *rtrim(char *t) {
int l = strlen(t) - 1;
while (l >= 0 && t[l] == ' ')
t[l--] = 0;
return t;
}
// The config-class itself.
Config::Config (const String &cfg, const String &d)
: filename(cfg), defaultDomain(d), willwrite(false) {
FILE *cfg_file;
char t[MAXLINELEN];
if (!(cfg_file = fopen(filename.c_str(), "r"))) {
debug(1, "Unable to open configuration file: %s.\n", filename.c_str());
} else {
while (!feof(cfg_file)) {
if (!fgets(t, MAXLINELEN, cfg_file))
continue;
if (t[0] != '#') {
if (t[0] == '[') {
// It's a new domain which begins here.
char *p = strchr(t, ']');
if (!p) {
debug(1, "Config file buggy: no ] at the end of the domain name.\n");
} else {
*p = 0;
set_domain(t + 1);
}
} else {
// It's a new key in the domain.
if (defaultDomain.isEmpty()) {
debug(1, "Config file buggy: we have a key without a domain first.\n");
}
char *p = strchr(t, '\n');
if (p)
*p = 0;
p = strchr(t, '\r');
if (p)
*p = 0;
if (!(p = strchr(t, '='))) {
if (strlen(t))
debug(1, "Config file buggy: there is junk: %s\n", t);
} else {
char *key, *value;
*p = 0;
key = ltrim(rtrim(t));
value = ltrim(p + 1);
set(key, value);
}
}
}
}
set_domain(d);
fclose(cfg_file);
}
}
const char *Config::get(const String &key, const String &d) const {
String domain;
if (d.isEmpty())
domain = defaultDomain;
else
domain = d;
domain.toLowercase();
if (domains.contains(domain) && domains[domain].contains(key))
return domains[domain][key].c_str();
return 0;
}
const int Config::getInt(const String &key, int def, const String &d) const {
const char *value = get(key, d);
if (value)
return atoi(value);
return def;
}
const bool Config::getBool(const String &key, bool def, const String &d) const {
const char *value = get(key, d);
if (value)
return !scumm_stricmp(value, "true");
return def;
}
void Config::set(const String &key, const String &value, const String &d) {
String domain(d);
if (domain.isEmpty())
domain = defaultDomain;
domain.toLowercase();
domains[domain][key] = value;
}
void Config::setInt(const String &key, int value_i, const String &d) {
char value[MAXLINELEN];
sprintf(value, "%i", value_i);
set(key, String(value), d);
}
void Config::setBool(const String &key, bool value_b, const String &d) {
String value(value_b ? "true" : "false");
set(key, value, d);
}
void Config::set_domain(const String &d) {
defaultDomain = d;
defaultDomain.toLowercase();
}
bool Config::has_domain(const String &d) const {
String temp(d);
temp.toLowercase();
return domains.contains(temp);
}
void Config::flush() const {
FILE *cfg_file;
if (!willwrite)
return;
if (!(cfg_file = fopen(filename.c_str(), "w"))) {
debug(1, "Unable to write configuration file: %s.\n", filename.c_str());
} else {
DomainMap::ConstIterator d;
for (d = domains.begin(); d != domains.end(); ++d) {
fprintf(cfg_file, "[%s]\n", d->_key.c_str());
const StringMap &data = d->_value;
StringMap::ConstIterator x;
for (x = data.begin(); x != data.end(); ++x) {
const String &value = x->_value;
if (!value.isEmpty())
fprintf(cfg_file, "%s=%s\n", x->_key.c_str(), value.c_str());
}
fprintf(cfg_file, "\n");
}
fclose(cfg_file);
}
}
void Config::rename_domain(const String &oldD, const String &newD) {
String oldDomain(oldD);
String newDomain(newD);
oldDomain.toLowercase();
newDomain.toLowercase();
if (oldDomain == newDomain)
return;
StringMap &oldHash = domains[oldDomain];
StringMap &newHash = domains[newDomain];
newHash.merge(oldHash);
domains.remove(oldDomain);
}
void Config::delete_domain(const String &d) {
String domain(d);
domain.toLowercase();
domains.remove(d);
}
void Config::set_filename(const String &f) {
filename = f;
}
void Config::merge_config(const Config &c) {
DomainMap::ConstIterator d, end(c.domains.end());
for (d = c.domains.begin(); d != end; ++d) {
domains[d->_key].merge(d->_value);
}
}
void Config::set_writing(bool w) {
willwrite = w;
}
const int Config::count_domains() {
int count = 0;
DomainMap::ConstIterator d, end(domains.end());
for (d = domains.begin(); d != end; ++d)
count++;
return count;
}
Common::StringList Config::get_domains() {
StringList domainNames;
DomainMap::ConstIterator d, end(domains.end());
for (d = domains.begin(); d != end; ++d) {
domainNames.push_back(d->_key);
}
return domainNames;
}

View file

@ -1,70 +0,0 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef CONFIG_FILE_H
#define CONFIG_FILE_H
#include "common/list.h"
#include "common/map.h"
#include "common/str.h"
#include "common/util.h"
class Config {
public:
typedef Common::String String;
typedef Common::StringList StringList;
typedef Common::StringMap StringMap;
typedef Common::Map<String, StringMap> DomainMap;
Config (const String & = String("config.cfg"), const String & = String("default"));
const char *get(const String &key, const String &dom = String()) const;
const int getInt(const String &key, int def = 0, const String &dom = String()) const;
const bool getBool(const String &key, bool def = false, const String &dom = String()) const;
void set(const String &key, const String &value, const String &dom = String());
void setInt(const String &key, int value, const String &dom = String());
void setBool(const String &key, bool value, const String &dom = String());
void set_domain(const String &d);
void flush() const;
void rename_domain(const String &oldD, const String &newD);
void delete_domain(const String &d);
bool has_domain(const String &d) const;
void set_filename(const String &);
void merge_config(const Config &);
void set_writing(bool);
const int count_domains();
StringList get_domains();
protected:
DomainMap domains;
String filename;
String defaultDomain;
bool willwrite;
};
// The global config object
extern Config *g_config;
#endif

370
common/config-manager.cpp Normal file
View file

@ -0,0 +1,370 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "common/config-manager.h"
#if defined(UNIX)
#include <sys/param.h>
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#ifdef MACOSX
#define DEFAULT_CONFIG_FILE "Library/Preferences/ScummVM Preferences"
#else
#define DEFAULT_CONFIG_FILE ".scummvmrc"
#endif
#else
#define DEFAULT_CONFIG_FILE "scummvm.ini"
#endif
#define MAXLINELEN 256
static char *ltrim(char *t) {
while (*t == ' ')
t++;
return t;
}
static char *rtrim(char *t) {
int l = strlen(t) - 1;
while (l >= 0 && t[l] == ' ')
t[l--] = 0;
return t;
}
namespace Common {
const String ConfigManager::kApplicationDomain("scummvm");
const String trueStr("true");
const String falseStr("false");
#pragma mark -
ConfigManager::ConfigManager() {
#if defined(UNIX)
char configFile[MAXPATHLEN];
if(getenv("HOME") != NULL)
sprintf(configFile,"%s/%s", getenv("HOME"), DEFAULT_CONFIG_FILE);
else strcpy(configFile,DEFAULT_CONFIG_FILE);
#else
char configFile[256];
#if defined (WIN32) && !defined(_WIN32_WCE)
GetWindowsDirectory(configFile, 256);
strcat(configFile, "\\");
strcat(configFile, DEFAULT_CONFIG_FILE);
#elif defined(__PALM_OS__)
strcpy(configFile,"/PALM/Programs/ScummVM/");
strcat(configFile, DEFAULT_CONFIG_FILE);
#else
strcpy(configFile, DEFAULT_CONFIG_FILE);
#endif
#endif
// Ensure the global domain(s) are setup.
_globalDomains.addKey(kApplicationDomain);
#ifdef _WIN32_WCE
// WinCE for some reasons uses additional global domains.
_globalDomains.addKey("wince");
_globalDomains.addKey("smartfon-keys");
#endif
_filename = configFile;
loadFile(_filename);
}
void ConfigManager::loadFile(const String &filename) {
FILE *cfg_file;
char t[MAXLINELEN];
String domain;
if (!(cfg_file = fopen(filename.c_str(), "r"))) {
debug(1, "Unable to open configuration file: %s.\n", filename.c_str());
} else {
while (!feof(cfg_file)) {
if (!fgets(t, MAXLINELEN, cfg_file))
continue;
if (t[0] != '#') {
if (t[0] == '[') {
// It's a new domain which begins here.
char *p = strchr(t, ']');
if (!p) {
error("Config file buggy: no ] at the end of the domain name.\n");
} else {
*p = 0;
// TODO: Some kind of domain name verification might be nice.
// E.g. restrict to only a-zA-Z0-9 and maybe -_ or so...
domain = t + 1;
}
} else {
// It's a new key in the domain.
if (domain.isEmpty()) {
error("Config file buggy: we have a key without a domain first.\n");
}
char *p = strchr(t, '\n');
if (p)
*p = 0;
p = strchr(t, '\r');
if (p)
*p = 0;
if (!(p = strchr(t, '='))) {
if (strlen(t))
warning("Config file buggy: there is junk: %s\n", t);
} else {
*p = 0;
String key = ltrim(rtrim(t));
String value = ltrim(p + 1);
set(key, value, domain);
}
}
}
}
fclose(cfg_file);
}
}
void ConfigManager::flushToDisk() {
FILE *cfg_file;
// TODO
// if (!willwrite)
// return;
if (!(cfg_file = fopen(_filename.c_str(), "w"))) {
warning("Unable to write configuration file: %s.\n", _filename.c_str());
} else {
DomainMap::ConstIterator d;
// First write the global domains
for (d = _globalDomains.begin(); d != _globalDomains.end(); ++d) {
writeDomain(cfg_file, d->_key, d->_value);
}
// Second, write the game domains
for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) {
writeDomain(cfg_file, d->_key, d->_value);
}
fclose(cfg_file);
}
}
void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &domain) {
if (domain.isEmpty())
return; // Don't bother writing empty domains.
fprintf(file, "[%s]\n", name.c_str());
StringMap::ConstIterator x;
for (x = domain.begin(); x != domain.end(); ++x) {
const String &value = x->_value;
if (!value.isEmpty())
fprintf(file, "%s=%s\n", x->_key.c_str(), value.c_str());
}
fprintf(file, "\n");
}
#pragma mark -
bool ConfigManager::hasKey(const String &key) const {
// Search the domains in the following order:
// 1) Run time domain
// 2) Active game domain (if any)
// 3) All global domains
// The defaults domain is explicitly *not* checked.
// if (_runtimeDomain.contain(key))
// return true;
if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
return true;
DomainMap::ConstIterator iter;
for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
if (iter->_value.contains(key))
return true;
}
return false;
}
bool ConfigManager::hasKey(const String &key, const String &dom) const {
assert(!dom.isEmpty());
if (_gameDomains.contains(dom))
return _gameDomains[dom].contains(key);
if (_globalDomains.contains(dom))
return _globalDomains[dom].contains(key);
return false;
}
#pragma mark -
const String & ConfigManager::get(const String &key) const {
// Search the domains in the following order:
// 1) Run time domain
// 2) Active game domain (if any)
// 3) All global domains
// 4) The defaults
// if (_runtimeDomain.contain(key))
// return true;
if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
return _gameDomains[_activeDomain][key];
DomainMap::ConstIterator iter;
for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
if (iter->_value.contains(key))
return iter->_value[key];
}
return _defaultsDomain.get(key);
}
const String & ConfigManager::get(const String &key, const String &dom) const {
if (dom.isEmpty())
return get(key);
// TODO: How exactly should we handle the case were the domain 'dom'
// is not found, or were dom is found, but doesn't contain 'key' ?
// Right now we just return an empty string. But might want to print
// out a warning, or even error out?
if (_gameDomains.contains(dom))
return _gameDomains[dom].get(key);
if (_globalDomains.contains(dom))
return _globalDomains[dom].get(key);
return String::emptyString;
}
int ConfigManager::getInt(const String &key, const String &dom) const {
String value(get(key, dom));
// Convert the string to an integer.
// TODO: We should perform some error checking.
long v = strtol(value.c_str(), 0, 10);
return (int)v;
}
bool ConfigManager::getBool(const String &key, const String &dom) const {
String value(get(key, dom));
// '1', 'true' and 'yes' are accepted as true values; everything else
// maps to value 'false'.
return (value == "true") || (value == "yes") || (value == "1");
}
#pragma mark -
void ConfigManager::set(const String &key, const String &value) {
#if 0
// TODO ?!?
// _runtimeDomain[key] = value;
#else
if (_activeDomain.isEmpty())
_globalDomains[kApplicationDomain][key] = value;
else
_gameDomains[_activeDomain][key] = value;
#endif
}
void ConfigManager::set(const String &key, const String &value, const String &dom) {
if (_globalDomains.contains(dom))
_globalDomains[dom][key] = value;
else
_gameDomains[dom][key] = value;
}
void ConfigManager::set(const String &key, const char *value, const String &dom) {
set(key, String(value), dom);
}
void ConfigManager::set(const String &key, int value, const String &dom) {
char tmp[128];
snprintf(tmp, sizeof(tmp), "%i", value);
set(key, String(tmp), dom);
}
void ConfigManager::set(const String &key, bool value, const String &dom) {
set(key, value ? trueStr : falseStr, dom);
}
#pragma mark -
void ConfigManager::registerDefault(const String &key, const String &value) {
_defaultsDomain[key] = value;
}
void ConfigManager::registerDefault(const String &key, const char *value) {
registerDefault(key, String(value));
}
void ConfigManager::registerDefault(const String &key, int value) {
char tmp[128];
snprintf(tmp, sizeof(tmp), "%i", value);
registerDefault(key, tmp);
}
void ConfigManager::registerDefault(const String &key, bool value) {
registerDefault(key, value ? trueStr : falseStr);
}
#pragma mark -
void ConfigManager::setActiveDomain(const String &domain) {
_activeDomain = domain;
_gameDomains.addKey(domain);
}
void ConfigManager::removeGameDomain(const String &name) {
_gameDomains.remove(name);
}
void ConfigManager::renameGameDomain(const String &oldName, const String &newName) {
if (oldName == newName)
return;
_gameDomains[newName].merge(_gameDomains[oldName]);
_gameDomains.remove(oldName);
}
bool ConfigManager::hasGameDomain(const String &domain) const {
return _gameDomains.contains(domain);
}
} // End of namespace Common

127
common/config-manager.h Normal file
View file

@ -0,0 +1,127 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef COMMON_CONFIG_H
#define COMMON_CONFIG_H
#include "common/list.h"
#include "common/map.h"
#include "common/singleton.h"
#include "common/str.h"
#include "common/util.h"
namespace Common {
class File;
/**
* The (singleton) configuration manager, used to query & set configuration
* values using string keys.
*
* @todo Implement the callback based notification system (outline below)
* which sends out notifications to interested parties whenever the value
* of some specific (or any) configuration key changes.
*/
class ConfigManager : public Singleton<ConfigManager> {
public:
class Domain : public StringMap {
// friend class ConfigManager;
public:
const String &get(const String &key) const {
Node *node = findNode(_root, key);
return node ? node->_value : String::emptyString;
}
/*
void set(const String &key, const String &value);
void set(const String &key, int value);
void set(const String &key, bool value);
*/
};
typedef Map<String, Domain> DomainMap;
/** The name of the application domain (normally 'scummvm'). */
static const String kApplicationDomain;
bool hasKey(const String &key) const;
bool hasKey(const String &key, const String &dom) const;
const String & get(const String &key) const;
const String & get(const String &key, const String &dom) const;
int getInt(const String &key, const String &dom = String::emptyString) const;
bool getBool(const String &key, const String &dom = String::emptyString) const;
void set(const String &key, const String &value);
void set(const String &key, const String &value, const String &dom);
void set(const String &key, const char *value, const String &dom = String::emptyString);
void set(const String &key, int value, const String &dom = String::emptyString);
void set(const String &key, bool value, const String &dom = String::emptyString);
void registerDefault(const String &key, const String &value);
void registerDefault(const String &key, const char *value);
void registerDefault(const String &key, int value);
void registerDefault(const String &key, bool value);
// ...
void flushToDisk();
void setActiveDomain(const String &domain);
// void addDomain(const String &name);
void removeGameDomain(const String &name);
void renameGameDomain(const String &oldName, const String &newName);
bool hasGameDomain(const String &domain) const;
const DomainMap & getGameDomains() const { return _gameDomains; }
/*
TODO: Callback/change notification system
typedef void (*ConfigCallback)(const ConstString &key, void *refCon);
void registerCallback(const ConstString &key, ConfigCallback cfgc, void *refCon)
void unregisterCallback(const ConstString &key, ConfigCallback cfgc)
*/
private:
friend class Singleton<ConfigManager>;
ConfigManager();
void loadFile(const String &filename);
void writeDomain(FILE *file, const String &name, const Domain &domain);
// Domain _runtimeDomain;
DomainMap _gameDomains;
DomainMap _globalDomains;
Domain _defaultsDomain;
List<Domain *> _searchOrder;
String _activeDomain;
String _filename;
};
} // End of namespace Common
/** Shortcut for accessing the configuration manager. */
#define ConfMan Common::ConfigManager::instance()
#endif

View file

@ -1,7 +1,7 @@
MODULE := common MODULE := common
MODULE_OBJS := \ MODULE_OBJS := \
common/config-file.o \ common/config-manager.o \
common/file.o \ common/file.o \
common/scaler.o \ common/scaler.o \
common/str.o \ common/str.o \

57
common/singleton.h Normal file
View file

@ -0,0 +1,57 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef COMMON_SINGLETON_H
#define COMMON_SINGLETON_H
namespace Common {
/**
* Generic template base class for implementing the singleton design pattern.
*/
template <class T>
class Singleton
{
public:
static T& instance() {
// TODO: We aren't thread safe. For now we ignore it since the
// only thing using this singleton template is the config manager,
// and that is first instantiated long before any threads.
// TODO: We don't leak, but the destruction order is nevertheless
// semi-random. If we use multiple singletons, the destruction
// order might become an issue. There are various approaches
// to solve that problem, but for now this is sufficient
static T singleton;
return singleton;
}
protected:
Singleton<T>() { }
~Singleton<T>() { }
private:
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
};
} // End of namespace Common
#endif

View file

@ -32,11 +32,13 @@
#include "backends/fs/fs.h" #include "backends/fs/fs.h"
#include "base/engine.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "base/engine.h"
using Common::ConfigManager;
enum { enum {
kStartCmd = 'STRT', kStartCmd = 'STRT',
@ -83,7 +85,6 @@ public:
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
protected: protected:
Config &_config;
const String &_domain; const String &_domain;
EditTextWidget *_descriptionWidget; EditTextWidget *_descriptionWidget;
EditTextWidget *_domainWidget; EditTextWidget *_domainWidget;
@ -92,10 +93,11 @@ protected:
}; };
EditGameDialog::EditGameDialog(NewGui *gui, const String &domain, const TargetSettings *target) EditGameDialog::EditGameDialog(NewGui *gui, const String &domain, const TargetSettings *target)
: Dialog(gui, 8, 50, 320 - 2 * 8, 200 - 2 * 40), _config(*g_config), _domain(domain) { : Dialog(gui, 8, 50, 320 - 2 * 8, 200 - 2 * 40),
_domain(domain) {
// Determine the description string // Determine the description string
String description(_config.get("description", _domain)); String description(ConfMan.get("description", domain));
if (description.isEmpty()) { if (description.isEmpty()) {
description = target->description; description = target->description;
} }
@ -116,18 +118,18 @@ EditGameDialog::EditGameDialog(NewGui *gui, const String &domain, const TargetSe
new EditTextWidget(this, 50, 26, _w - 50 - 10, kLineHeight, description); new EditTextWidget(this, 50, 26, _w - 50 - 10, kLineHeight, description);
// Path to game data (view only) // Path to game data (view only)
String path(_config.get("path", _domain)); String path(ConfMan.get("path", _domain));
new StaticTextWidget(this, 10, 42, 40, kLineHeight, "Path: ", kTextAlignRight); new StaticTextWidget(this, 10, 42, 40, kLineHeight, "Path: ", kTextAlignRight);
new StaticTextWidget(this, 50, 42, _w - 50 - 10, kLineHeight, path, kTextAlignLeft); new StaticTextWidget(this, 50, 42, _w - 50 - 10, kLineHeight, path, kTextAlignLeft);
// Full screen checkbox // Full screen checkbox
_fullscreenCheckbox = new CheckboxWidget(this, 15, 62, 200, 16, "Use Fullscreen Mode", 0, 'F'); _fullscreenCheckbox = new CheckboxWidget(this, 15, 62, 200, 16, "Use Fullscreen Mode", 0, 'F');
_fullscreenCheckbox->setState(_config.getBool("fullscreen", false, _domain)); _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain));
// Display 'Amiga' checkbox, but only for Scumm games. // Display 'Amiga' checkbox, but only for Scumm games.
if (isScumm) { if (isScumm) {
_amigaCheckbox = new CheckboxWidget(this, 15, 82, 200, 16, "Amiga Version", 0, 'A'); _amigaCheckbox = new CheckboxWidget(this, 15, 82, 200, 16, "Amiga Version", 0, 'A');
_amigaCheckbox->setState(_config.getBool("amiga", false, _domain)); _amigaCheckbox->setState(ConfMan.getBool("amiga", _domain));
} else { } else {
_amigaCheckbox = 0; _amigaCheckbox = 0;
} }
@ -142,17 +144,17 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// Write back changes made to config object // Write back changes made to config object
String newDomain(_domainWidget->getLabel()); String newDomain(_domainWidget->getLabel());
if (newDomain != _domain) { if (newDomain != _domain) {
if (newDomain.isEmpty() || _config.has_domain(newDomain)) { if (newDomain.isEmpty() || ConfMan.hasGameDomain(newDomain)) {
MessageDialog alert(_gui, "This game ID is already taken. Please choose another one."); MessageDialog alert(_gui, "This game ID is already taken. Please choose another one.");
alert.runModal(); alert.runModal();
return; return;
} }
_config.rename_domain(_domain, newDomain); ConfMan.renameGameDomain(_domain, newDomain);
} }
_config.set("description", _descriptionWidget->getLabel(), newDomain); ConfMan.set("description", _descriptionWidget->getLabel(), newDomain);
if (_amigaCheckbox) if (_amigaCheckbox)
_config.setBool("amiga", _amigaCheckbox->getState(), newDomain); ConfMan.set("amiga", _amigaCheckbox->getState(), newDomain);
_config.setBool("fullscreen", _fullscreenCheckbox->getState(), newDomain); ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), newDomain);
setResult(1); setResult(1);
close(); close();
} else { } else {
@ -218,12 +220,16 @@ LauncherDialog::~LauncherDialog() {
void LauncherDialog::open() { void LauncherDialog::open() {
Dialog::open(); Dialog::open();
/* FIXME / TODO: config rewrite
g_config->set_writing(true); g_config->set_writing(true);
*/
} }
void LauncherDialog::close() { void LauncherDialog::close() {
g_config->flush(); ConfMan.flushToDisk();
/* FIXME / TODO: config rewrite
g_config->set_writing(false); g_config->set_writing(false);
*/
Dialog::close(); Dialog::close();
} }
@ -232,16 +238,16 @@ void LauncherDialog::updateListing() {
// Retrieve a list of all games defined in the config file // Retrieve a list of all games defined in the config file
_domains.clear(); _domains.clear();
StringList domains = g_config->get_domains(); const ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
StringList::ConstIterator iter = domains.begin(); ConfigManager::DomainMap::ConstIterator iter = domains.begin();
for (iter = domains.begin(); iter != domains.end(); ++iter) { for (iter = domains.begin(); iter != domains.end(); ++iter) {
String name(g_config->get("gameid", *iter)); String name(iter->_value.get("gameid"));
String description(g_config->get("description", *iter)); String description(iter->_value.get("description"));
if (name.isEmpty()) if (name.isEmpty())
name = *iter; name = iter->_key;
if (description.isEmpty()) { if (description.isEmpty()) {
const TargetSettings *v = _detector.findTarget(name.c_str()); const TargetSettings *v = _detector.findTarget(name);
if (v && v->description) if (v && v->description)
description = v->description; description = v->description;
} }
@ -253,7 +259,7 @@ void LauncherDialog::updateListing() {
while (pos < size && (description > l[pos])) while (pos < size && (description > l[pos]))
pos++; pos++;
l.insert_at(pos, description); l.insert_at(pos, description);
_domains.insert_at(pos, *iter); _domains.insert_at(pos, iter->_key);
} }
} }
@ -372,18 +378,18 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// Pick a domain name which does not yet exist (after all, we // Pick a domain name which does not yet exist (after all, we
// are *adding* a game to the config, not replacing). // are *adding* a game to the config, not replacing).
String domain(v->targetName); String domain(v->targetName);
if (g_config->has_domain(domain)) { if (ConfMan.hasGameDomain(domain)) {
char suffix = 'a'; char suffix = 'a';
domain += suffix; domain += suffix;
while (g_config->has_domain(domain)) { while (ConfMan.hasGameDomain(domain)) {
domain.deleteLastChar(); domain.deleteLastChar();
suffix++; suffix++;
domain += suffix; domain += suffix;
} }
g_config->set("gameid", v->targetName, domain); ConfMan.set("gameid", v->targetName, domain);
g_config->set("description", v->description, domain); ConfMan.set("description", v->description, domain);
} }
g_config->set("path", dir->path(), domain); ConfMan.set("path", dir->path(), domain);
// Display edit dialog for the new entry // Display edit dialog for the new entry
EditGameDialog editDialog(_gui, domain, v); EditGameDialog editDialog(_gui, domain, v);
@ -391,14 +397,14 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// User pressed OK, so make changes permanent // User pressed OK, so make changes permanent
// Write config to disk // Write config to disk
g_config->flush(); ConfMan.flushToDisk();
// Update the ListWidget and force a redraw // Update the ListWidget and force a redraw
updateListing(); updateListing();
draw(); draw();
} else { } else {
// User aborted, remove the the new domain again // User aborted, remove the the new domain again
g_config->delete_domain(domain); ConfMan.removeGameDomain(domain);
} }
} }
} }
@ -406,10 +412,10 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
case kRemoveGameCmd: case kRemoveGameCmd:
// Remove the currently selected game from the list // Remove the currently selected game from the list
assert(item >= 0); assert(item >= 0);
g_config->delete_domain(_domains[item]); ConfMan.removeGameDomain(_domains[item]);
// Write config to disk // Write config to disk
g_config->flush(); ConfMan.flushToDisk();
// Update the ListWidget and force a redraw // Update the ListWidget and force a redraw
updateListing(); updateListing();
@ -423,15 +429,15 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// This is useful because e.g. MonkeyVGA needs Adlib music to have decent // This is useful because e.g. MonkeyVGA needs Adlib music to have decent
// music support etc. // music support etc.
assert(item >= 0); assert(item >= 0);
const char *gameId = g_config->get("gameid", _domains[item]); String gameId(ConfMan.get("gameid", _domains[item]));
if (!gameId) if (gameId.isEmpty())
gameId = _domains[item].c_str(); gameId = _domains[item];
EditGameDialog editDialog(_gui, _domains[item], _detector.findTarget(gameId)); EditGameDialog editDialog(_gui, _domains[item], _detector.findTarget(gameId));
if (editDialog.runModal()) { if (editDialog.runModal()) {
// User pressed OK, so make changes permanent // User pressed OK, so make changes permanent
// Write config to disk // Write config to disk
g_config->flush(); ConfMan.flushToDisk();
// Update the ListWidget and force a redraw // Update the ListWidget and force a redraw
updateListing(); updateListing();

View file

@ -27,7 +27,7 @@
#include "backends/fs/fs.h" #include "backends/fs/fs.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "sound/mididrv.h" #include "sound/mididrv.h"
#if (!( defined(__DC__) || defined(__GP32__)) && !defined(_MSC_VER)) #if (!( defined(__DC__) || defined(__GP32__)) && !defined(_MSC_VER))
@ -61,7 +61,7 @@ enum {
}; };
GlobalOptionsDialog::GlobalOptionsDialog(NewGui *gui, GameDetector &detector) GlobalOptionsDialog::GlobalOptionsDialog(NewGui *gui, GameDetector &detector)
: Dialog(gui, 10, 15, 320 - 2 * 10, 200 - 2 * 15), _detector(detector) { : Dialog(gui, 10, 15, 320 - 2 * 10, 200 - 2 * 15) {
// The GFX mode popup & a label // The GFX mode popup & a label
// TODO - add an API to query the list of available GFX modes, and to get/set the mode // TODO - add an API to query the list of available GFX modes, and to get/set the mode
new StaticTextWidget(this, 5, 10+1, 100, kLineHeight, "Graphics mode: ", kTextAlignRight); new StaticTextWidget(this, 5, 10+1, 100, kLineHeight, "Graphics mode: ", kTextAlignRight);
@ -94,7 +94,7 @@ GlobalOptionsDialog::GlobalOptionsDialog(NewGui *gui, GameDetector &detector)
const MidiDriverDescription *md = getAvailableMidiDrivers(); const MidiDriverDescription *md = getAvailableMidiDrivers();
while (md->name) { while (md->name) {
_midiPopUp->appendEntry(md->description, md->id); _midiPopUp->appendEntry(md->description, md->id);
if (md->id == _detector._midi_driver) if (md->id == detector._midi_driver)
midiSelected = i; midiSelected = i;
i++; i++;
md++; md++;
@ -134,10 +134,9 @@ GlobalOptionsDialog::GlobalOptionsDialog(NewGui *gui, GameDetector &detector)
_savePath = new StaticTextWidget(this, 105, 106, 180, kLineHeight, "/foo/bar", kTextAlignLeft); _savePath = new StaticTextWidget(this, 105, 106, 180, kLineHeight, "/foo/bar", kTextAlignLeft);
new ButtonWidget(this, 105, 120, 64, 16, "Choose...", kChooseSaveDirCmd, 0); new ButtonWidget(this, 105, 120, 64, 16, "Choose...", kChooseSaveDirCmd, 0);
// TODO: set _savePath to the current save path, i.e. as obtained via // TODO: set _savePath to the current save path
const char *dir = NULL; Common::String dir(ConfMan.get("savepath"));
dir = g_config->get("savepath", "scummvm"); if (!dir.isEmpty()) {
if (dir) {
_savePath->setLabel(dir); _savePath->setLabel(dir);
} else { } else {
// Default to the current directory... // Default to the current directory...
@ -164,9 +163,9 @@ GlobalOptionsDialog::~GlobalOptionsDialog() {
void GlobalOptionsDialog::open() { void GlobalOptionsDialog::open() {
Dialog::open(); Dialog::open();
_soundVolumeMaster = _detector._master_volume; _soundVolumeMaster = ConfMan.getInt("master_volume");
_soundVolumeMusic = _detector._music_volume; _soundVolumeMusic = ConfMan.getInt("music_volume");
_soundVolumeSfx = _detector._sfx_volume; _soundVolumeSfx = ConfMan.getInt("sfx_volume");
_masterVolumeSlider->setValue(_soundVolumeMaster); _masterVolumeSlider->setValue(_soundVolumeMaster);
_musicVolumeSlider->setValue(_soundVolumeMusic); _musicVolumeSlider->setValue(_soundVolumeMusic);
@ -184,7 +183,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
// User made his choice... // User made his choice...
FilesystemNode *dir = _browser->getResult(); FilesystemNode *dir = _browser->getResult();
_savePath->setLabel(dir->path()); _savePath->setLabel(dir->path());
// TODO - we should check if the director is writeable before accepting it // TODO - we should check if the directory is writeable before accepting it
} }
break; break;
case kMasterVolumeChanged: case kMasterVolumeChanged:
@ -207,18 +206,17 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
const MidiDriverDescription *md = getAvailableMidiDrivers(); const MidiDriverDescription *md = getAvailableMidiDrivers();
for (; md->name; md++) { for (; md->name; md++) {
if (md->id == (int) data) { if (md->id == (int) data) {
g_config->set ("music_driver", md->name, "_USER_OVERRIDES"); ConfMan.set("music_driver", md->name);
break; break;
} }
} }
} }
break; break;
case kOKCmd: case kOKCmd:
// TODO Write back changes made to config object
setResult(1); setResult(1);
_detector._master_volume = _soundVolumeMaster; ConfMan.set("master_volume", _soundVolumeMaster);
_detector._music_volume = _soundVolumeMusic; ConfMan.set("music_volume", _soundVolumeMusic);
_detector._sfx_volume = _soundVolumeSfx; ConfMan.set("sfx_volume", _soundVolumeSfx);
close(); close();
break; break;
default: default:

View file

@ -40,8 +40,6 @@ public:
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
protected: protected:
GameDetector &_detector;
BrowserDialog *_browser; BrowserDialog *_browser;
StaticTextWidget*_savePath; StaticTextWidget*_savePath;

View file

@ -21,6 +21,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "queen/queen.h" #include "queen/queen.h"
#include "common/config-manager.h"
#include "common/file.h" #include "common/file.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
@ -60,10 +61,10 @@ QueenEngine::QueenEngine(GameDetector *detector, OSystem *syst)
if (!_mixer->bindToSystem(syst)) if (!_mixer->bindToSystem(syst))
warning("Sound initialisation failed."); warning("Sound initialisation failed.");
_mixer->setVolume(detector->_sfx_volume); _mixer->setVolume(ConfMan.getInt("sfx_volume"));
_debugMode = detector->_debugMode; _debugMode = detector->_debugMode;
_debugLevel = detector->_debugLevel; _debugLevel = ConfMan.getInt("debuglevel");
_detector = detector; _detector = detector;
_fastMode = 0; _fastMode = 0;

View file

@ -29,7 +29,6 @@
#include "sound/mixer.h" #include "sound/mixer.h"
#include "queen/resource.h" #include "queen/resource.h"
#include "queen/logic.h" #include "queen/logic.h"
#include "common/config-file.h"
namespace Queen { namespace Queen {

View file

@ -34,7 +34,7 @@
#include "gui/newgui.h" #include "gui/newgui.h"
#include "gui/ListWidget.h" #include "gui/ListWidget.h"
#include "common/config-file.h" #include "common/config-manager.h"
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
#include "gapi_keys.h" #include "gapi_keys.h"
@ -546,13 +546,13 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
_scumm->_mixer->setVolume(_soundVolumeSfx * _soundVolumeMaster / 255); _scumm->_mixer->setVolume(_soundVolumeSfx * _soundVolumeMaster / 255);
_scumm->_mixer->setMusicVolume(_soundVolumeMusic); _scumm->_mixer->setMusicVolume(_soundVolumeMusic);
g_config->setInt("master_volume", _soundVolumeMaster); ConfMan.set("master_volume", _soundVolumeMaster);
g_config->setInt("music_volume", _soundVolumeMusic); ConfMan.set("music_volume", _soundVolumeMusic);
g_config->setInt("sfx_volume", _soundVolumeSfx); ConfMan.set("sfx_volume", _soundVolumeSfx);
// Subtitles? // Subtitles?
_scumm->_noSubtitles = !subtitlesCheckbox->getState(); _scumm->_noSubtitles = !subtitlesCheckbox->getState();
g_config->setBool("nosubtitles", _scumm->_noSubtitles); ConfMan.set("nosubtitles", _scumm->_noSubtitles);
// Amiga version? // Amiga version?
if (amigaCheckbox->getState()) if (amigaCheckbox->getState())
@ -560,10 +560,10 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
else else
_scumm->setFeatures (_scumm->_features & (~GF_AMIGA)); _scumm->setFeatures (_scumm->_features & (~GF_AMIGA));
g_config->setBool("amiga", amigaCheckbox->getState()); ConfMan.set("amiga", amigaCheckbox->getState());
// Finally flush the modified config // Finally flush the modified config
g_config->flush(); ConfMan.flushToDisk();
} }
case kCancelCmd: case kCancelCmd:
close(); close();

View file

@ -22,7 +22,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "scumm/actor.h" #include "scumm/actor.h"
#include "scumm/charset.h" #include "scumm/charset.h"

View file

@ -25,7 +25,7 @@
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "gui/console.h" #include "gui/console.h"
#include "gui/message.h" #include "gui/message.h"
@ -595,22 +595,22 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst)
g_debugger = new ScummDebugger; g_debugger = new ScummDebugger;
_debugMode = detector->_debugMode; _debugMode = detector->_debugMode;
_debugLevel = detector->_debugLevel; _debugLevel = ConfMan.getInt("debuglevel");
_dumpScripts = detector->_dumpScripts; _dumpScripts = detector->_dumpScripts;
_bootParam = detector->_bootParam; _bootParam = ConfMan.getInt("boot_param");
_exe_name = strdup(detector->_game.targetName); _exe_name = strdup(detector->_game.targetName);
_game_name = strdup(detector->_gameFileName.c_str()); _game_name = strdup(detector->_gameFileName.c_str());
_gameId = detector->_game.id; _gameId = detector->_game.id;
_version = detector->_game.version; _version = detector->_game.version;
setFeatures(detector->_game.features); setFeatures(detector->_game.features);
_demoMode = detector->_demo_mode; _demoMode = ConfMan.getBool("demo_mode");
_noSubtitles = detector->_noSubtitles; _noSubtitles = ConfMan.getBool("nosubtitles");
_confirmExit = detector->_confirmExit; _confirmExit = ConfMan.getBool("confirm_exit");
_defaultTalkDelay = detector->_talkSpeed; _defaultTalkDelay = ConfMan.getInt("talkspeed");
_midiDriver = detector->_midi_driver; _midiDriver = detector->_midi_driver;
_native_mt32 = detector->_native_mt32; _native_mt32 = ConfMan.getBool("native_mt32");
_language = detector->_language; _language = GameDetector::parseLanguage(ConfMan.get("language"));
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
_hexdumpScripts = false; _hexdumpScripts = false;
_showStack = false; _showStack = false;
@ -634,13 +634,13 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst)
_newgui = g_gui; _newgui = g_gui;
_sound = new Sound(this); _sound = new Sound(this);
_sound->_sound_volume_master = detector->_master_volume; _sound->_sound_volume_master = ConfMan.getInt("master_volume");
_sound->_sound_volume_sfx = detector->_sfx_volume; _sound->_sound_volume_sfx = ConfMan.getInt("music_volume");
_sound->_sound_volume_music = detector->_music_volume; _sound->_sound_volume_music = ConfMan.getInt("sfx_volume");
/* Initialize backend */ /* Initialize backend */
syst->init_size(_screenWidth, _screenHeight); syst->init_size(_screenWidth, _screenHeight);
prop.cd_num = detector->_cdrom; prop.cd_num = ConfMan.getInt("cdrom");
if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS)) if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
syst->property(OSystem::PROP_OPEN_CD, &prop); syst->property(OSystem::PROP_OPEN_CD, &prop);
@ -681,16 +681,16 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst)
_musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK); _musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK);
} else if (_version > 2) { } else if (_version > 2) {
MidiDriver *driver = detector->createMidi(); MidiDriver *driver = detector->createMidi();
if (driver && detector->_native_mt32) if (driver && _native_mt32)
driver->property (MidiDriver::PROP_CHANNEL_MASK, 0x03FE); driver->property (MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_musicEngine = _imuse = IMuse::create(syst, _mixer, driver); _musicEngine = _imuse = IMuse::create(syst, _mixer, driver);
if (_imuse) { if (_imuse) {
if (detector->_gameTempo != 0) if (ConfMan.hasKey("tempo"))
_imuse->property(IMuse::PROP_TEMPO_BASE, detector->_gameTempo); _imuse->property(IMuse::PROP_TEMPO_BASE, ConfMan.getInt("tempo"));
_imuse->property(IMuse::PROP_OLD_ADLIB_INSTRUMENTS, (_features & GF_SMALL_HEADER) ? 1 : 0); _imuse->property(IMuse::PROP_OLD_ADLIB_INSTRUMENTS, (_features & GF_SMALL_HEADER) ? 1 : 0);
_imuse->property(IMuse::PROP_MULTI_MIDI, detector->_multi_midi && _imuse->property(IMuse::PROP_MULTI_MIDI, ConfMan.getBool("multi_midi") &&
_midiDriver != MD_NULL && (detector->_game.midi & MDT_ADLIB)); _midiDriver != MD_NULL && (detector->_game.midi & MDT_ADLIB));
_imuse->property(IMuse::PROP_NATIVE_MT32, detector->_native_mt32); _imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32);
if (_features & GF_HUMONGOUS || _features & GF_FMTOWNS) { if (_features & GF_HUMONGOUS || _features & GF_FMTOWNS) {
_imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1); _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);
_imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1); _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1);
@ -703,8 +703,8 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst)
#endif // ph0x-hack #endif // ph0x-hack
// Load game from specified slot, if any // Load game from specified slot, if any
if (detector->_save_slot != -1) { if (ConfMan.hasKey("save_slot")) {
_saveLoadSlot = detector->_save_slot; _saveLoadSlot = ConfMan.getInt("save_slot");
_saveLoadFlag = 2; _saveLoadFlag = 2;
_saveLoadCompatible = false; _saveLoadCompatible = false;
} }
@ -2647,20 +2647,24 @@ const TargetSettings *Engine_SCUMM_targetList() {
Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) {
Engine *engine; Engine *engine;
if (detector->_amiga) if (ConfMan.hasKey("amiga")) {
warning("Configuration key 'amiga' is deprecated. Use 'platform=amiga' instead");
if (ConfMan.getBool("amiga"))
detector->_game.features |= GF_AMIGA; detector->_game.features |= GF_AMIGA;
}
switch (detector->_platform) { switch (GameDetector::parsePlatform(ConfMan.get("platform"))) {
case 1: case kPlatformAmiga:
if (!(detector->_game.features & GF_AMIGA))
detector->_game.features |= GF_AMIGA; detector->_game.features |= GF_AMIGA;
break; break;
case 2: case kPlatformAtariST:
detector->_game.features |= GF_ATARI_ST; detector->_game.features |= GF_ATARI_ST;
break; break;
case 3: case kPlatformMacintosh:
detector->_game.features |= GF_MACINTOSH; detector->_game.features |= GF_MACINTOSH;
break; break;
default:
break;
} }
switch (detector->_game.version) { switch (detector->_game.version) {

View file

@ -28,7 +28,7 @@
#include "scumm/scumm.h" #include "scumm/scumm.h"
#include "scumm/sound.h" #include "scumm/sound.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "common/timer.h" #include "common/timer.h"
#include "common/util.h" #include "common/util.h"

View file

@ -24,7 +24,7 @@
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "common/file.h" #include "common/file.h"
#include "simon/simon.h" #include "simon/simon.h"
@ -471,26 +471,26 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)
if (!_mixer->bindToSystem(syst)) if (!_mixer->bindToSystem(syst))
warning("Sound initialization failed. " warning("Sound initialization failed. "
"Features of the game that depend on sound synchronization will most likely break"); "Features of the game that depend on sound synchronization will most likely break");
set_volume(detector->_sfx_volume); set_volume(ConfMan.getInt("sfx_volume"));
// Setup midi driver // Setup midi driver
MidiDriver *driver = detector->createMidi(); MidiDriver *driver = detector->createMidi();
if (!driver) if (!driver)
driver = MidiDriver_ADLIB_create(_mixer); driver = MidiDriver_ADLIB_create(_mixer);
else if (detector->_native_mt32) else if (ConfMan.getBool("native_mt32"))
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
midi.mapMT32toGM (!(_game & GF_SIMON2) && !detector->_native_mt32); midi.mapMT32toGM (!(_game & GF_SIMON2) && !ConfMan.getBool("native_mt32"));
midi.set_driver(driver); midi.set_driver(driver);
int ret = midi.open(); int ret = midi.open();
if (ret) if (ret)
warning ("MIDI Player init failed: \"%s\"", midi.getErrorName (ret)); warning ("MIDI Player init failed: \"%s\"", midi.getErrorName (ret));
midi.set_volume(detector->_music_volume); midi.set_volume(ConfMan.getInt("music_volume"));
_debugMode = detector->_debugMode; _debugMode = detector->_debugMode;
_debugLevel = detector->_debugLevel; _debugLevel = ConfMan.getInt("debuglevel");
_language = detector->_language; _language = GameDetector::parseLanguage(ConfMan.get("language"));
_noSubtitles = detector->_noSubtitles; _noSubtitles = ConfMan.getBool("nosubtitles");
_system->init_size(320, 200); _system->init_size(320, 200);

View file

@ -24,6 +24,7 @@
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-manager.h"
#include "common/file.h" #include "common/file.h"
#include "common/timer.h" #include "common/timer.h"
@ -103,13 +104,13 @@ SkyEngine::SkyEngine(GameDetector *detector, OSystem *syst)
if (!_mixer->bindToSystem(syst)) if (!_mixer->bindToSystem(syst))
warning("Sound initialisation failed."); warning("Sound initialisation failed.");
_mixer->setVolume(detector->_sfx_volume); //unnecessary? _mixer->setVolume(ConfMan.getInt("sfx_volume")); //unnecessary?
_debugMode = detector->_debugMode; _debugMode = detector->_debugMode;
_debugLevel = detector->_debugLevel; _debugLevel = ConfMan.getInt("debuglevel");
_detector = detector; _detector = detector;
_floppyIntro = detector->_floppyIntro; _floppyIntro = ConfMan.getBool("floppy_intro");
_fastMode = 0; _fastMode = 0;
@ -251,7 +252,7 @@ void SkyEngine::go() {
void SkyEngine::initialise(void) { void SkyEngine::initialise(void) {
_skyDisk = new SkyDisk(_gameDataPath); _skyDisk = new SkyDisk(_gameDataPath);
_skySound = new SkySound(_mixer, _skyDisk, _detector->_sfx_volume); _skySound = new SkySound(_mixer, _skyDisk, ConfMan.getInt("sfx_volume"));
_systemVars.gameVersion = _skyDisk->determineGameVersion(); _systemVars.gameVersion = _skyDisk->determineGameVersion();
@ -260,14 +261,14 @@ void SkyEngine::initialise(void) {
_skyMusic = new SkyAdlibMusic(_mixer, _skyDisk, _system); _skyMusic = new SkyAdlibMusic(_mixer, _skyDisk, _system);
} else { } else {
_systemVars.systemFlags |= SF_ROLAND; _systemVars.systemFlags |= SF_ROLAND;
if (_detector->_native_mt32) if (ConfMan.getBool("native_mt32"))
_skyMusic = new SkyMT32Music(_detector->createMidi(), _skyDisk, _system); _skyMusic = new SkyMT32Music(_detector->createMidi(), _skyDisk, _system);
else else
_skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk, _system); _skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk, _system);
} }
if (isCDVersion()) { if (isCDVersion()) {
if (_detector->_noSubtitles) if (ConfMan.getBool("nosubtitles"))
_systemVars.systemFlags |= SF_ALLOW_SPEECH; _systemVars.systemFlags |= SF_ALLOW_SPEECH;
else else
_systemVars.systemFlags |= SF_ALLOW_SPEECH | SF_ALLOW_TEXT; _systemVars.systemFlags |= SF_ALLOW_SPEECH | SF_ALLOW_TEXT;
@ -296,10 +297,11 @@ void SkyEngine::initialise(void) {
if (_systemVars.gameVersion == 288) if (_systemVars.gameVersion == 288)
SkyCompact::patchFor288(); SkyCompact::patchFor288();
if (_detector->_language > 10) int language = GameDetector::parseLanguage(ConfMan.get("language"));
if (language < 0 || language > 10)
_systemVars.language = SKY_USA; _systemVars.language = SKY_USA;
else else
_systemVars.language = _languageTable[_detector->_language]; _systemVars.language = _languageTable[language];
if (!_skyDisk->fileExists(60600 + SkyEngine::_systemVars.language * 8)) { if (!_skyDisk->fileExists(60600 + SkyEngine::_systemVars.language * 8)) {
warning("The language you selected does not exist in your BASS version."); warning("The language you selected does not exist in your BASS version.");
@ -316,15 +318,15 @@ void SkyEngine::initialise(void) {
} }
uint16 result = 0; uint16 result = 0;
if (_detector->_save_slot >= 0) if (ConfMan.hasKey("save_slot") && ConfMan.getInt("save_slot") >= 0)
result = _skyControl->quickXRestore(_detector->_save_slot); result = _skyControl->quickXRestore(ConfMan.getInt("save_slot"));
if (result == GAME_RESTORED) if (result == GAME_RESTORED)
_quickLaunch = true; _quickLaunch = true;
else else
_quickLaunch = false; _quickLaunch = false;
_skyMusic->setVolume(_detector->_music_volume >> 1); _skyMusic->setVolume(ConfMan.getInt("music_volume") >> 1);
} }
void SkyEngine::initItemList() { void SkyEngine::initItemList() {

View file

@ -20,7 +20,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "base/gameDetector.h" #include "base/gameDetector.h"
#include "base/plugins.h" #include "base/plugins.h"
#include "common/config-file.h" #include "common/config-manager.h"
#include "bs2/build_display.h" #include "bs2/build_display.h"
#include "bs2/console.h" #include "bs2/console.h"
#include "bs2/controls.h" #include "bs2/controls.h"
@ -105,9 +105,9 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst)
_features = detector->_game.features; _features = detector->_game.features;
_gameId = detector->_game.id; _gameId = detector->_game.id;
_game_name = strdup(detector->_gameFileName.c_str()); _game_name = strdup(detector->_gameFileName.c_str());
_bootParam = detector->_bootParam; _bootParam = ConfMan.getInt("boot_param");
_saveSlot = detector->_save_slot; _saveSlot = ConfMan.getInt("save_slot");
_debugLevel = detector->_debugLevel; _debugLevel = ConfMan.getInt("debuglevel");
// Setup mixer // Setup mixer
if (!_mixer->bindToSystem(syst)) if (!_mixer->bindToSystem(syst))