COMMON: Add initial config file option.

This allows an initial/default configuration file to be specified via the command line.  This allows a default settings file to be bundled and loaded even if it's installed to a read-only location, such as Program Files on Windows, and allows the written config file to be deleted without losing the custom defaults.
This commit is contained in:
elasota 2023-01-02 19:19:00 -05:00 committed by Eugene Sandulenko
parent 6253391579
commit 3a07524b73
4 changed files with 35 additions and 10 deletions

View file

@ -94,7 +94,8 @@ static const char HELP_STRING1[] =
" --console Enable the console window (default:enabled)\n" " --console Enable the console window (default:enabled)\n"
#endif #endif
"\n" "\n"
" -c, --config=CONFIG Use alternate configuration file\n" " -c, --config=CONFIG Use alternate configuration file path\n"
" -i, --initial-cfg=CONFIG Load an initial configuration file if no configuration file has been saved yet\n"
#if defined(SDL_BACKEND) #if defined(SDL_BACKEND)
" -l, --logfile=PATH Use alternate path for log file\n" " -l, --logfile=PATH Use alternate path for log file\n"
" --screenshotpath=PATH Specify path where screenshot files are created\n" " --screenshotpath=PATH Specify path where screenshot files are created\n"
@ -633,6 +634,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_OPTION('c', "config") DO_OPTION('c', "config")
END_OPTION END_OPTION
DO_OPTION('i', "initial-cfg")
END_OPTION
#if defined(SDL_BACKEND) #if defined(SDL_BACKEND)
DO_OPTION('l', "logfile") DO_OPTION('l', "logfile")
END_OPTION END_OPTION
@ -1884,6 +1888,7 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
// Finally, store the command line settings into the config manager. // Finally, store the command line settings into the config manager.
static const char * const sessionSettings[] = { static const char * const sessionSettings[] = {
"config", "config",
"initial-cfg",
"fullscreen", "fullscreen",
"gfx-mode", "gfx-mode",
"stretch-mode", "stretch-mode",

View file

@ -493,10 +493,14 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
command = autoCommand; command = autoCommand;
// Load the config file (possibly overridden via command line): // Load the config file (possibly overridden via command line):
Common::String initConfigFilename;
if (settings.contains("initial-cfg"))
initConfigFilename = settings["initial-cfg"];
if (settings.contains("config")) { if (settings.contains("config")) {
ConfMan.loadConfigFile(settings["config"]); ConfMan.loadConfigFile(settings["config"], initConfigFilename);
} else { } else {
ConfMan.loadDefaultConfigFile(); ConfMan.loadDefaultConfigFile(initConfigFilename);
} }
// Update the config file // Update the config file

View file

@ -78,7 +78,7 @@ void ConfigManager::copyFrom(ConfigManager &source) {
} }
void ConfigManager::loadDefaultConfigFile() { void ConfigManager::loadDefaultConfigFile(const String &fallbackFilename) {
// Open the default config file // Open the default config file
assert(g_system); assert(g_system);
SeekableReadStream *stream = g_system->createConfigReadStream(); SeekableReadStream *stream = g_system->createConfigReadStream();
@ -92,19 +92,21 @@ void ConfigManager::loadDefaultConfigFile() {
delete stream; delete stream;
} else { } else {
// No config file -> create new one! // No config file -> try to load fallback, flush initial config to disk
if (!loadFallbackConfigFile(fallbackFilename))
debug("Default configuration file missing, creating a new one"); debug("Default configuration file missing, creating a new one");
flushToDisk(); flushToDisk();
} }
} }
void ConfigManager::loadConfigFile(const String &filename) { void ConfigManager::loadConfigFile(const String &filename, const String &fallbackFilename) {
_filename = filename; _filename = filename;
FSNode node(filename); FSNode node(filename);
File cfg_file; File cfg_file;
if (!cfg_file.open(node)) { if (!cfg_file.open(node)) {
if (!loadFallbackConfigFile(fallbackFilename))
debug("Creating configuration file: %s", filename.c_str()); debug("Creating configuration file: %s", filename.c_str());
} else { } else {
debug("Using configuration file: %s", _filename.c_str()); debug("Using configuration file: %s", _filename.c_str());
@ -112,6 +114,19 @@ void ConfigManager::loadConfigFile(const String &filename) {
} }
} }
bool ConfigManager::loadFallbackConfigFile(const String &filename) {
if (filename.empty())
return false;
File fallbackFile;
if (!fallbackFile.open(FSNode(filename)))
return false;
debug("Using initial configuration file: %s", filename.c_str());
loadFromStream(fallbackFile);
return true;
}
/** /**
* Add a ready-made domain based on its name and contents * Add a ready-made domain based on its name and contents
* The domain name should not already exist in the ConfigManager. * The domain name should not already exist in the ConfigManager.

View file

@ -125,8 +125,8 @@ public:
static char const *const kCloudDomain; static char const *const kCloudDomain;
#endif #endif
void loadDefaultConfigFile(); /*!< Load the default configuration file. */ void loadDefaultConfigFile(const String &fallbackFilename); /*!< Load the default configuration file. */
void loadConfigFile(const String &filename); /*!< Load a specific configuration file. */ void loadConfigFile(const String &filename, const String &fallbackFilename); /*!< Load a specific configuration file. */
/** /**
* Retrieve the config domain with the given name. * Retrieve the config domain with the given name.
@ -222,6 +222,7 @@ private:
friend class Singleton<SingletonBaseType>; friend class Singleton<SingletonBaseType>;
ConfigManager(); ConfigManager();
bool loadFallbackConfigFile(const String &filename);
void loadFromStream(SeekableReadStream &stream); void loadFromStream(SeekableReadStream &stream);
void addDomain(const String &domainName, const Domain &domain); void addDomain(const String &domainName, const Domain &domain);
void writeDomain(WriteStream &stream, const String &name, const Domain &domain); void writeDomain(WriteStream &stream, const String &name, const Domain &domain);