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
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
* 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?
* add iterators to List<> template and make use of them
* 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
===
@ -41,18 +39,7 @@ Audio
Config
======
* The config system could stand an overhaul
* 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
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
@ -61,6 +48,12 @@ Config
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
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
=====
@ -89,6 +82,8 @@ SCUMM
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)
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
==============

View file

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

View file

@ -27,7 +27,7 @@
#include "base/gameDetector.h"
#include "base/plugins.h"
#include "common/config-file.h"
#include "common/config-manager.h"
#include "common/scaler.h" // Only for gfx_modes
#include "sound/mididrv.h"
@ -69,20 +69,26 @@ static const char USAGE_STRING[] =
" -m<num> - Set music 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"
#ifndef DISABLE_SCUMM
" -t<num> - Set music tempo (50-200, default 100%%)\n"
#endif
"\n"
" -n - No subtitles for speech\n"
#ifndef DISABLE_SCUMM
" -y - Set text speed (default: 60)\n"
#endif
"\n"
/* FIXME / TODO: config rewrite
" -l<file> - Load config file instead of default\n"
#if defined(UNIX)
" -w[file] - Write to config file [~/.scummvmrc]\n"
#else
" -w[file] - Write to config file [scummvm.ini]\n"
#endif
*/
" -v - Show version info and exit\n"
" -h - Display this text and exit\n"
" -z - Display list of games\n"
" -z - Display list of supported games\n"
"\n"
" -b<num> - Pass number to the boot script (boot param)\n"
" -d[num] - Enable debug output (debug level [0])\n"
@ -143,13 +149,13 @@ static const struct GraphicsMode gfx_modes[] = {
{0, 0, 0}
};
struct Language {
struct LanguageDescription {
const char *name;
const char *description;
int id;
Language id;
};
static const struct Language languages[] = {
static const struct LanguageDescription languages[] = {
{"en", "English", EN_USA},
{"de", "German", DE_DEU},
{"fr", "French", FR_FRA},
@ -162,162 +168,105 @@ static const struct Language languages[] = {
{"gb", "English", EN_GRB},
{"se", "Swedish", SE_SWE},
{"hb", "Hebrew", HB_HEB},
{0, 0, 0}
{0, 0, UNK_LANG}
};
GameDetector::GameDetector() {
_fullScreen = false;
_aspectRatio = false;
_master_volume = kDefaultMasterVolume;
_music_volume = kDefaultMusicVolume;
_sfx_volume = kDefaultSFXVolume;
_amiga = false;
_platform = 0;
_language = 0;
// Graphics
ConfMan.registerDefault("fullscreen", false);
ConfMan.registerDefault("aspect_ratio", false);
#ifndef _WIN32_WCE
ConfMan.registerDefault("gfx_mode", "2x");
#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
_demo_mode = false;
ConfMan.registerDefault("demo_mode", false);
ConfMan.registerDefault("talkspeed", 60);
ConfMan.registerDefault("tempo", 0);
#endif
#ifndef DISABLE_SKY
_floppyIntro = false;
ConfMan.registerDefault("floppy_intro", false);
#endif
_talkSpeed = 60;
_debugMode = 0;
_debugLevel = 0;
_dumpScripts = 0;
_noSubtitles = false;
_bootParam = 0;
// Miscellaneous
ConfMan.registerDefault("debuglevel", 0);
ConfMan.registerDefault("joystick_num", -1);
ConfMan.registerDefault("confirm_exit", false);
_gameDataPath = 0;
_gameTempo = 0;
_debugMode = false;
_dumpScripts = false;
_midi_driver = MD_AUTO;
_saveconfig = false;
_game.features = 0;
_plugin = 0;
_multi_midi = false;
_native_mt32 = false;
_cdrom = 0;
_joystick_num = 0;
_save_slot = 0;
_saveconfig = false;
_confirmExit = false;
#ifndef _WIN32_WCE
_gfx_mode = GFX_DOUBLESIZE;
#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() {
// 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 TargetSettings *v;
const char *config;
printf("Game Full Title Config\n"
"---------------- ------------------------------------------------------ -------\n");
printf("Game Full Title \n"
"---------------- ------------------------------------------------------\n");
PluginList::ConstIterator iter = plugins.begin();
for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
v = (*iter)->getTargets();
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);
#endif
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
assert(targetName);
const TargetSettings *target;
const PluginList &plugins = g_pluginManager->getPlugins();
PluginList::ConstIterator iter = plugins.begin();
for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
target = (*iter)->findTarget(targetName);
target = (*iter)->findTarget(targetName.c_str());
if (target) {
if (plugin)
*plugin = *iter;
@ -334,12 +283,15 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
char *option = NULL;
char c;
bool long_option_value;
_save_slot = -1;
_joystick_num = -1;
// Parse the arguments
// into a transient "_COMMAND_LINE" config comain.
g_config->set_domain ("_COMMAND_LINE");
// Iterate over all comman line arguments, backwards.
// FIXME: Looping backwards has a major problem: Consider this example
// 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--) {
s = argv[i];
@ -349,20 +301,19 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
switch (tolower(c)) {
case 'b':
HANDLE_OPTION();
_bootParam = atoi(option);
ConfMan.set("boot_param", (int)strtol(option, 0, 10));
break;
case 'c':
HANDLE_OPTION();
_cdrom = atoi(option);
g_config->setInt("cdrom", _cdrom);
ConfMan.set("cdrom", (int)strtol(option, 0, 10));
break;
case 'd':
_debugMode = true;
HANDLE_OPT_OPTION();
if (option != NULL)
_debugLevel = atoi(option);
if (_debugLevel) {
printf("Debuglevel (from command line): %d\n", _debugLevel);
ConfMan.set("debuglevel", (int)strtol(option, 0, 10));
if (ConfMan.getInt("debuglevel")) {
printf("Debuglevel (from command line): %d\n", ConfMan.getInt("debuglevel"));
} else {
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:
// "'option' is not a supported music driver on this machine.
// Available driver: ..."
if (!parseMusicDriver(option))
if (parseMusicDriver(option) < 0)
goto ShowHelpAndExit;
g_config->set("music_driver", option);
ConfMan.set("music_driver", option);
break;
case 'f':
CHECK_OPTION();
_fullScreen = (c == 'f');
g_config->setBool("fullscreen", _fullScreen);
g_config->setBool("fullscreen", _fullScreen, "scummvm");
ConfMan.set("fullscreen", (c == 'f'));
break;
case 'g':
case 'g':{
HANDLE_OPTION();
_gfx_mode = parseGraphicsMode(option);
int _gfx_mode = parseGraphicsMode(option);
// TODO: Instead of just showing the generic help text,
// maybe print a message like:
// "'option' is not a supported graphic mode on this machine.
// Available graphic modes: ..."
if (_gfx_mode == -1)
goto ShowHelpAndExit;
g_config->set("gfx_mode", option);
g_config->set("gfx_mode", option, "scummvm");
break;
ConfMan.set("gfx_mode", option);
break;}
// case 'h': reserved for help
case 'j':
_joystick_num = 0;
HANDLE_OPT_OPTION();
if (option != NULL) {
_joystick_num = atoi(option);
g_config->setInt("joystick_num", _joystick_num);
}
ConfMan.set("joystick_num", (option != NULL) ? (int)strtol(option, 0, 10) : 0);
break;
/* FIXME / TODO: config rewrite
case 'l':
HANDLE_OPTION();
{
@ -414,47 +359,43 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
break;
}
break;
*/
case 'm':
HANDLE_OPTION();
_music_volume = atoi(option);
g_config->setInt("music_volume", _music_volume);
ConfMan.set("music_volume", (int)strtol(option, 0, 10));
break;
case 'n':
CHECK_OPTION();
_noSubtitles = (c == 'n');
g_config->setBool("nosubtitles", _noSubtitles ? true : false);
ConfMan.set("nosubtitles", (c == 'n'));
break;
case 'o':
HANDLE_OPTION();
_master_volume = atoi(option);
g_config->setInt("master_volume", _master_volume);
ConfMan.set("master_volume", (int)strtol(option, 0, 10));
break;
case 'p':
HANDLE_OPTION();
_gameDataPath = option;
g_config->set("path", _gameDataPath);
// TODO: Verify path is valid
ConfMan.set("path", option);
break;
case 'q':
HANDLE_OPTION();
_language = parseLanguage(option);
if (_language == -1)
if (parseLanguage(option) == UNK_LANG)
goto ShowHelpAndExit;
g_config->set("language", option);
break;
case 'r':
HANDLE_OPTION();
// Ignore -r for now, to ensure backward compatibility.
ConfMan.set("language", option);
break;
case 's':
HANDLE_OPTION();
_sfx_volume = atoi(option);
g_config->setInt("sfx_volume", _sfx_volume);
ConfMan.set("sfx_volume", (int)strtol(option, 0, 10));
break;
#ifndef DISABLE_SCUMM
case 't':
HANDLE_OPTION();
_gameTempo = strtol(option, 0, 0);
g_config->set("tempo", option);
// Use the special value '0' for the base in (int)strtol.
// 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;
#endif
case 'u':
CHECK_OPTION();
_dumpScripts = true;
@ -462,7 +403,9 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
case 'v':
CHECK_OPTION();
printf("%s\n", gScummVMFullVersion);
exit(1);
exit(0);
break;
/* FIXME / TODO: config rewrite
case 'w':
_saveconfig = true;
g_config->set_writing(true);
@ -470,19 +413,17 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
if (option != NULL)
g_config->set_filename(option);
break;
*/
case 'x':
_save_slot = 0;
HANDLE_OPT_OPTION();
if (option != NULL) {
_save_slot = atoi(option);
g_config->setInt("save_slot", _save_slot);
}
ConfMan.set("save_slot", (option != NULL) ? (int)strtol(option, 0, 10) : 0);
break;
#ifndef DISABLE_SCUMM
case 'y':
HANDLE_OPTION();
_talkSpeed = atoi(option);
g_config->setInt("talkspeed", _talkSpeed);
ConfMan.set("talkspeed", (int)strtol(option, 0, 10));
break;
#endif
case 'z':
CHECK_OPTION();
list_games();
@ -491,16 +432,11 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
// Long options. Let the fun begin!
if (!strncmp(s, "platform=", 9)) {
s += 9;
if (!strcmp (s, "amiga"))
_platform = 1;
else if (!strcmp (s, "atari-st"))
_platform = 2;
else if (!strcmp (s, "macintosh"))
_platform = 3;
else
int platform = parsePlatform(s);
if (platform == kPlatformUnknown)
goto ShowHelpAndExit;
g_config->setInt ("platform", _platform);
ConfMan.set("platform", platform);
break;
}
@ -511,28 +447,21 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
long_option_value = true;
if (!strcmp (s, "multi-midi")) {
_multi_midi = long_option_value;
g_config->setBool ("multi_midi", _multi_midi);
ConfMan.set("multi_midi", long_option_value);
} else if (!strcmp (s, "native-mt32")) {
_native_mt32 = long_option_value;
g_config->setBool ("native_mt32", _native_mt32);
ConfMan.set("native_mt32", long_option_value);
} else if (!strcmp (s, "aspect-ratio")) {
_aspectRatio = long_option_value;
g_config->setBool ("aspect_ratio", _aspectRatio);
ConfMan.set("aspect_ratio", long_option_value);
} else if (!strcmp (s, "fullscreen")) {
_fullScreen = long_option_value;
g_config->setBool("fullscreen", _fullScreen);
g_config->setBool("fullscreen", _fullScreen, "scummvm");
ConfMan.set("fullscreen", long_option_value);
#ifndef DISABLE_SCUMM
} else if (!strcmp (s, "demo-mode")) {
_demo_mode = long_option_value;
g_config->setBool ("demo_mode", _demo_mode);
ConfMan.set("demo_mode", long_option_value);
#endif
#ifndef DISABLE_SKY
} else if (!strcmp (s, "floppy-intro")) {
_floppyIntro = long_option_value;
g_config->setBool ("floppy_intro", _floppyIntro);
ConfMan.set("floppy_intro", long_option_value);
#endif
} else {
goto ShowHelpAndExit;
@ -553,8 +482,10 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
}
}
/* FIXME / TODO: config rewrite
if (!_gameFileName.isEmpty())
g_config->flush();
ConfMan.flushToDisk();
*/
return;
@ -565,29 +496,14 @@ ShowHelpAndExit:
void GameDetector::setGame(const String &name) {
_gameFileName = name;
g_config->set_domain(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);
ConfMan.setActiveDomain(name);
}
int GameDetector::parseGraphicsMode(const char *s) {
int GameDetector::parseGraphicsMode(const String &str) {
const char *s = str.c_str();
const GraphicsMode *gm = gfx_modes;
while(gm->name) {
while (gm->name) {
if (!scumm_stricmp(gm->name, s)) {
_default_gfx_mode = false;
return gm->id;
}
gm++;
@ -596,50 +512,65 @@ int GameDetector::parseGraphicsMode(const char *s) {
return -1;
}
int GameDetector::parseLanguage(const char *s) {
const Language *l = languages;
while(l->name) {
Language GameDetector::parseLanguage(const String &str) {
const char *s = str.c_str();
const LanguageDescription *l = languages;
while (l->name) {
if (!scumm_stricmp(l->name, s))
return l->id;
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();
while (md->name) {
if (!scumm_stricmp(md->name, s)) {
_midi_driver = md->id;
return true;
return md->id;
}
md++;
}
return false;
return -1;
}
bool GameDetector::detectGame() {
const TargetSettings *target;
const char *realGame, *basename;
_gameText.clear();
String realGame;
realGame = g_config->get("gameid");
if (!realGame)
realGame = _gameFileName.c_str();
printf("Looking for %s\n", realGame);
if (ConfMan.hasKey("gameid"))
realGame = ConfMan.get("gameid");
else
realGame = _gameFileName;
printf("Looking for %s\n", realGame.c_str());
target = findTarget(realGame, &_plugin);
if (target) {
_game = *target;
if ((basename = g_config->get("basename"))) {
if (ConfMan.hasKey("basename")) {
// 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);
return true;
} 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() {
if (_gameFileName.isEmpty()) {
warning("No game was specified...");
@ -672,7 +594,8 @@ bool GameDetector::detectMain() {
* and the game is one of those that want adlib as
* default, OR if the game is an older game that doesn't
* 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)
_midi_driver = getMidiDriverType();
else
@ -691,21 +614,17 @@ bool GameDetector::detectMain() {
if ((_midi_driver == MD_PCSPK || _midi_driver == MD_PCJR) && !(_game.midi & MDT_PCSPK))
_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");
_gameDataPath = strdup("");
#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__
&& _gameDataPath[strlen(_gameDataPath)-1] != ':'
&& gameDataPath.lastChar() != ':'
#endif
&& _gameDataPath[strlen(_gameDataPath)-1] != '\\') {
char slashless[1024]; /* Append slash to path */
strcpy(slashless, _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);
&& gameDataPath.lastChar() != '\\') {
gameDataPath += '/';
ConfMan.set("path", gameDataPath);
#endif
}
@ -713,6 +632,8 @@ bool GameDetector::detectMain() {
}
OSystem *GameDetector::createSystem() {
int _gfx_mode = parseGraphicsMode(ConfMan.get("gfx_mode")); // FIXME: Get rid of this again!
#if defined(USE_NULL_DRIVER)
return OSystem_NULL_create();
#elif defined(__DC__)
@ -720,18 +641,18 @@ OSystem *GameDetector::createSystem() {
#elif defined(X11_BACKEND)
return OSystem_X11_create();
#elif defined(__MORPHOS__)
return OSystem_MorphOS_create(_gfx_mode, _fullScreen);
return OSystem_MorphOS_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#elif defined(_WIN32_WCE)
return OSystem_WINCE3_create();
#elif defined(MACOS_CARBON)
return OSystem_MAC_create(_gfx_mode, _fullScreen);
return OSystem_MAC_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#elif defined(__GP32__) // ph0x
return OSystem_GP32_create(GFX_NORMAL, true);
#elif defined(__PALM_OS__) //chrilith
return OSystem_PALMOS_create(_gfx_mode, _fullScreen);
return OSystem_PALMOS_create(_gfx_mode, ConfMan.getBool("fullscreen"));
#else
/* 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
}

View file

@ -51,7 +51,8 @@ enum {
* @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.
*/
enum {
enum Language {
UNK_LANG = -1, // Use default language (i.e. none specified)
EN_USA = 0,
DE_DEU = 1,
FR_FRA = 2,
@ -66,6 +67,14 @@ enum {
HB_HEB = 20
};
enum Platform {
kPlatformUnknown = -1,
kPlatformPC = 0,
kPlatformAmiga = 1,
kPlatformAtariST = 2,
kPlatformMacintosh = 3
};
enum MidiDriverType {
MDT_NONE = 0,
MDT_PCSPK = 1, // MD_PCSPK and MD_PCJR
@ -92,49 +101,16 @@ public:
void parseCommandLine(int argc, char **argv);
bool detectMain();
void setGame(const String &name);
const String& getGameName(void);
String _gameFileName;
TargetSettings _game;
const Plugin *_plugin;
bool _fullScreen;
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 _debugMode;
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 _confirmExit;
int _midi_driver;
public:
OSystem *createSystem();
@ -142,19 +118,19 @@ public:
SoundMixer *createMixer();
MidiDriver *createMidi();
int getMidiDriverType();
int getMidiDriverType(); // FIXME: Try to get rid of this, only Sky frontend uses it
int parseGraphicsMode(const char *s);
void updateconfig();
void setGame(const String &name);
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 char *targetName, const Plugin **plugin = NULL) const;
const TargetSettings *findTarget(const String &targetName, const Plugin **plugin = NULL) const;
protected:
String _gameText;
bool detectGame(void);
bool parseMusicDriver(const char *s);
int parseLanguage(const char *s);
void list_games();
};

View file

@ -32,7 +32,7 @@
#include "base/engine.h"
#include "base/gameDetector.h"
#include "base/plugins.h"
#include "common/config-file.h"
#include "common/config-manager.h"
#include "common/scaler.h" // For GFX_NORMAL
#include "common/timer.h"
#include "gui/newgui.h"
@ -83,7 +83,6 @@ const char *gScummVMBuildDate = __DATE__ " " __TIME__;
const char *gScummVMFullVersion = "ScummVM 0.5.4cvs (" __DATE__ " " __TIME__ ")";
Config *g_config = 0;
NewGui *g_gui = 0;
OSystem *g_system = 0;
@ -108,20 +107,6 @@ extern "C" int main(int argc, char *argv[]);
#include "allegro.h"
#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)
#include <signal.h>
@ -211,23 +196,6 @@ int main(int argc, char *argv[]) {
#if defined(UNIX)
/* On Unix, do a quick endian / alignement check before starting */
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
// Code copied from SDL_main
@ -265,9 +233,8 @@ int main(int argc, char *argv[]) {
#endif //defined(WIN32) && defined(USE_CONSOLE)
// Read the config file
g_config = new Config(scummhome, "scummvm");
g_config->set("versioninfo", gScummVMVersion);
// Update the config file
ConfMan.set("versioninfo", gScummVMVersion, "scummvm");
// Load the plugins
g_pluginManager = new PluginManager();
@ -276,7 +243,6 @@ int main(int argc, char *argv[]) {
// Parse the command line information
GameDetector detector;
detector._saveconfig = false;
detector.updateconfig();
detector.parseCommandLine(argc, argv);
// Create the system object
@ -301,30 +267,30 @@ int main(int argc, char *argv[]) {
if (detector.detectMain()) {
// 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)
prop.caption = detector.getGameName().c_str();
system->property(OSystem::PROP_SET_WINDOW_CAPTION, &prop);
prop.caption = detector._gameFileName.c_str();
if (prop.caption != NULL)
system->property(OSystem::PROP_SET_WINDOW_CAPTION, &prop);
// FIXME: It seem not logical that we first might set the gfx mode to
// 1x, and then immediately after might override it again. We probably
// should combine both checks into one.
// 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)) {
prop.gfx_mode = GFX_NORMAL;
system->property(OSystem::PROP_SET_GFX_MODE, &prop);
}
} else
// Override global scaler with any game-specific define
if (g_config->get("gfx_mode")) {
prop.gfx_mode = detector.parseGraphicsMode(g_config->get("gfx_mode"));
if (ConfMan.hasKey("gfx_mode")) {
prop.gfx_mode = detector.parseGraphicsMode(ConfMan.get("gfx_mode"));
system->property(OSystem::PROP_SET_GFX_MODE, &prop);
}
// 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))
system->property(OSystem::PROP_TOGGLE_FULLSCREEN, 0);
}
@ -344,7 +310,6 @@ int main(int argc, char *argv[]) {
}
delete g_gui;
delete g_config;
// ...and quit (the return 0 should never be reached)
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_OBJS := \
common/config-file.o \
common/config-manager.o \
common/file.o \
common/scaler.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 "base/engine.h"
#include "base/gameDetector.h"
#include "base/plugins.h"
#include "common/config-file.h"
#include "base/engine.h"
#include "common/config-manager.h"
using Common::ConfigManager;
enum {
kStartCmd = 'STRT',
@ -83,7 +85,6 @@ public:
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
protected:
Config &_config;
const String &_domain;
EditTextWidget *_descriptionWidget;
EditTextWidget *_domainWidget;
@ -92,10 +93,11 @@ protected:
};
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
String description(_config.get("description", _domain));
String description(ConfMan.get("description", domain));
if (description.isEmpty()) {
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);
// 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, 50, 42, _w - 50 - 10, kLineHeight, path, kTextAlignLeft);
// Full screen checkbox
_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.
if (isScumm) {
_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 {
_amigaCheckbox = 0;
}
@ -142,17 +144,17 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// Write back changes made to config object
String newDomain(_domainWidget->getLabel());
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.");
alert.runModal();
return;
}
_config.rename_domain(_domain, newDomain);
ConfMan.renameGameDomain(_domain, newDomain);
}
_config.set("description", _descriptionWidget->getLabel(), newDomain);
ConfMan.set("description", _descriptionWidget->getLabel(), newDomain);
if (_amigaCheckbox)
_config.setBool("amiga", _amigaCheckbox->getState(), newDomain);
_config.setBool("fullscreen", _fullscreenCheckbox->getState(), newDomain);
ConfMan.set("amiga", _amigaCheckbox->getState(), newDomain);
ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), newDomain);
setResult(1);
close();
} else {
@ -218,12 +220,16 @@ LauncherDialog::~LauncherDialog() {
void LauncherDialog::open() {
Dialog::open();
/* FIXME / TODO: config rewrite
g_config->set_writing(true);
*/
}
void LauncherDialog::close() {
g_config->flush();
ConfMan.flushToDisk();
/* FIXME / TODO: config rewrite
g_config->set_writing(false);
*/
Dialog::close();
}
@ -232,16 +238,16 @@ void LauncherDialog::updateListing() {
// Retrieve a list of all games defined in the config file
_domains.clear();
StringList domains = g_config->get_domains();
StringList::ConstIterator iter = domains.begin();
const ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
ConfigManager::DomainMap::ConstIterator iter = domains.begin();
for (iter = domains.begin(); iter != domains.end(); ++iter) {
String name(g_config->get("gameid", *iter));
String description(g_config->get("description", *iter));
String name(iter->_value.get("gameid"));
String description(iter->_value.get("description"));
if (name.isEmpty())
name = *iter;
name = iter->_key;
if (description.isEmpty()) {
const TargetSettings *v = _detector.findTarget(name.c_str());
const TargetSettings *v = _detector.findTarget(name);
if (v && v->description)
description = v->description;
}
@ -253,7 +259,7 @@ void LauncherDialog::updateListing() {
while (pos < size && (description > l[pos]))
pos++;
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
// are *adding* a game to the config, not replacing).
String domain(v->targetName);
if (g_config->has_domain(domain)) {
if (ConfMan.hasGameDomain(domain)) {
char suffix = 'a';
domain += suffix;
while (g_config->has_domain(domain)) {
while (ConfMan.hasGameDomain(domain)) {
domain.deleteLastChar();
suffix++;
domain += suffix;
}
g_config->set("gameid", v->targetName, domain);
g_config->set("description", v->description, domain);
ConfMan.set("gameid", v->targetName, 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
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
// Write config to disk
g_config->flush();
ConfMan.flushToDisk();
// Update the ListWidget and force a redraw
updateListing();
draw();
} else {
// 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:
// Remove the currently selected game from the list
assert(item >= 0);
g_config->delete_domain(_domains[item]);
ConfMan.removeGameDomain(_domains[item]);
// Write config to disk
g_config->flush();
ConfMan.flushToDisk();
// Update the ListWidget and force a redraw
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
// music support etc.
assert(item >= 0);
const char *gameId = g_config->get("gameid", _domains[item]);
if (!gameId)
gameId = _domains[item].c_str();
String gameId(ConfMan.get("gameid", _domains[item]));
if (gameId.isEmpty())
gameId = _domains[item];
EditGameDialog editDialog(_gui, _domains[item], _detector.findTarget(gameId));
if (editDialog.runModal()) {
// User pressed OK, so make changes permanent
// Write config to disk
g_config->flush();
ConfMan.flushToDisk();
// Update the ListWidget and force a redraw
updateListing();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,7 @@
#include "base/gameDetector.h"
#include "base/plugins.h"
#include "common/config-file.h"
#include "common/config-manager.h"
#include "common/file.h"
#include "simon/simon.h"
@ -471,26 +471,26 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)
if (!_mixer->bindToSystem(syst))
warning("Sound initialization failed. "
"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
MidiDriver *driver = detector->createMidi();
if (!driver)
driver = MidiDriver_ADLIB_create(_mixer);
else if (detector->_native_mt32)
driver->property (MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
else if (ConfMan.getBool("native_mt32"))
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);
int ret = midi.open();
if (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;
_debugLevel = detector->_debugLevel;
_language = detector->_language;
_noSubtitles = detector->_noSubtitles;
_debugLevel = ConfMan.getInt("debuglevel");
_language = GameDetector::parseLanguage(ConfMan.get("language"));
_noSubtitles = ConfMan.getBool("nosubtitles");
_system->init_size(320, 200);

View file

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

View file

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