From 9034ce2a7c5034d4864e1ae79e4cb28eeb602400 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 2 Aug 2008 22:32:32 +0000 Subject: Fix for bug #1972625 'ALL: On-the-fly targets are written to the config file' svn-id: r33550 --- common/advancedDetector.cpp | 2 ++ common/config-manager.cpp | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'common') diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp index 8bd019018a..522b24163e 100644 --- a/common/advancedDetector.cpp +++ b/common/advancedDetector.cpp @@ -94,6 +94,8 @@ static void upgradeTargetIfNecessary(const Common::ADParams ¶ms) { warning("Target upgraded from %s to %s", o->from, o->to); + // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching + // undefined target adds launcher entry" if (ConfMan.hasKey("id_came_from_command_line")) { warning("Target came from command line. Skipping save"); } else { diff --git a/common/config-manager.cpp b/common/config-manager.cpp index 044474a927..40fef1a622 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -324,6 +324,12 @@ void ConfigManager::writeDomain(WriteStream &stream, const String &name, const D if (domain.empty()) return; // Don't bother writing empty domains. + // WORKAROUND: Fix for bug #1972625 "ALL: On-the-fly targets are + // written to the config file": Do not save domains that came from + // the command line + if (domain.contains("id_came_from_command_line")) + return; + String comment; // Write domain comment (if any) -- cgit v1.2.3 From 6377b8bdd570d3c23dbdc9239b844492f7e09b9d Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 3 Aug 2008 16:54:18 +0000 Subject: New OSystem API for loading/storing default config file svn-id: r33584 --- common/config-manager.cpp | 375 ++++++++++++++++++---------------------------- common/config-manager.h | 12 +- common/system.cpp | 132 ++++++++++++++++ common/system.h | 19 ++- 4 files changed, 298 insertions(+), 240 deletions(-) (limited to 'common') diff --git a/common/config-manager.cpp b/common/config-manager.cpp index 40fef1a622..a424c4f6c7 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -23,38 +23,13 @@ * */ -#if defined(WIN32) -#include -// winnt.h defines ARRAYSIZE, but we want our own one... -#undef ARRAYSIZE -#endif - #include "common/config-manager.h" #include "common/file.h" #include "common/util.h" +#include "common/system.h" DECLARE_SINGLETON(Common::ConfigManager); -#ifdef __PLAYSTATION2__ -#include "backends/platform/ps2/systemps2.h" -#endif - -#ifdef IPHONE -#include "backends/platform/iphone/osys_iphone.h" -#endif - -#if defined(UNIX) -#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 bool isValidDomainName(const Common::String &domName) { const char *p = domName.c_str(); while (*p && (isalnum(*p) || *p == '-' || *p == '_')) @@ -85,238 +60,180 @@ ConfigManager::ConfigManager() void ConfigManager::loadDefaultConfigFile() { - char configFile[MAXPATHLEN]; - // GP2X is Linux based but Home dir can be read only so do not use it and put the config in the executable dir. - // On the iPhone, the home dir of the user when you launch the app from the Springboard, is /. Which we don't want. -#if defined(UNIX) && !defined(GP2X) && !defined(IPHONE) - const char *home = getenv("HOME"); - if (home != NULL && strlen(home) < MAXPATHLEN) - snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE); - else - strcpy(configFile, DEFAULT_CONFIG_FILE); -#else - #if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - OSVERSIONINFO win32OsVersion; - ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); - win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&win32OsVersion); - // Check for non-9X version of Windows. - if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { - // Use the Application Data directory of the user profile. - if (win32OsVersion.dwMajorVersion >= 5) { - if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile))) - error("Unable to access application data directory"); - } else { - if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile))) - error("Unable to access user profile directory"); - - strcat(configFile, "\\Application Data"); - CreateDirectory(configFile, NULL); - } - - strcat(configFile, "\\ScummVM"); - CreateDirectory(configFile, NULL); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - - if (fopen(configFile, "r") == NULL) { - // Check windows directory - char oldConfigFile[MAXPATHLEN]; - GetWindowsDirectory(oldConfigFile, MAXPATHLEN); - strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE); - if (fopen(oldConfigFile, "r")) { - printf("The default location of the config file (scummvm.ini) in ScummVM has changed,\n"); - printf("under Windows NT4/2000/XP/Vista. You may want to consider moving your config\n"); - printf("file from the old default location:\n"); - printf("%s\n", oldConfigFile); - printf("to the new default location:\n"); - printf("%s\n\n", configFile); - strcpy(configFile, oldConfigFile); - } - } - } else { - // Check windows directory - GetWindowsDirectory(configFile, MAXPATHLEN); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - } + // Open the default config file + SeekableReadStream *stream = g_system->openConfigFileForReading(); + _filename.clear(); // clear the filename to indicate that we are using the default config file - #elif defined(PALMOS_MODE) - strcpy(configFile,"/PALM/Programs/ScummVM/" DEFAULT_CONFIG_FILE); - #elif defined(IPHONE) - strcpy(configFile, OSystem_IPHONE::getConfigPath()); - #elif defined(__PLAYSTATION2__) - ((OSystem_PS2*)g_system)->makeConfigPath(configFile); - #elif defined(__PSP__) - strcpy(configFile, "ms0:/" DEFAULT_CONFIG_FILE); - #elif defined (__SYMBIAN32__) - strcpy(configFile, Symbian::GetExecutablePath()); - strcat(configFile, DEFAULT_CONFIG_FILE); - #else - strcpy(configFile, DEFAULT_CONFIG_FILE); - #endif -#endif + // ... load it ... + assert(stream); + loadFromStream(*stream); + + // ... and close it again. + delete stream; - loadConfigFile(configFile); flushToDisk(); } void ConfigManager::loadConfigFile(const String &filename) { - _appDomain.clear(); - _gameDomains.clear(); - _transientDomain.clear(); - _filename = filename; - _domainSaveOrder.clear(); - loadFile(_filename); - printf("Using configuration file: %s\n", _filename.c_str()); -} -void ConfigManager::loadFile(const String &filename) { File cfg_file; - if (!cfg_file.open(filename)) { printf("Creating configuration file: %s\n", filename.c_str()); } else { - String domain; - String comment; - int lineno = 0; - - // TODO: Detect if a domain occurs multiple times (or likewise, if - // a key occurs multiple times inside one domain). - - while (!cfg_file.eof() && !cfg_file.ioFailed()) { - lineno++; - - // Read a line - String line; - while (line.lastChar() != '\n') { - char buf[MAXLINELEN]; - if (!cfg_file.readLine_NEW(buf, MAXLINELEN)) - break; - line += buf; + printf("Using configuration file: %s\n", _filename.c_str()); + loadFromStream(cfg_file); + } +} + +void ConfigManager::loadFromStream(SeekableReadStream &stream) { + String domain; + String comment; + int lineno = 0; + + _appDomain.clear(); + _gameDomains.clear(); + _transientDomain.clear(); + _domainSaveOrder.clear(); + + // TODO: Detect if a domain occurs multiple times (or likewise, if + // a key occurs multiple times inside one domain). + + while (!stream.eos() && !stream.ioFailed()) { + lineno++; + + // Read a line + String line; + while (line.lastChar() != '\n') { + char buf[256]; + if (!stream.readLine_NEW(buf, 256)) + break; + line += buf; + } + + if (line.size() == 0) { + // Do nothing + } else if (line[0] == '#') { + // Accumulate comments here. Once we encounter either the start + // of a new domain, or a key-value-pair, we associate the value + // of the 'comment' variable with that entity. + comment += line; + } else if (line[0] == '[') { + // It's a new domain which begins here. + const char *p = line.c_str() + 1; + // Get the domain name, and check whether it's valid (that + // is, verify that it only consists of alphanumerics, + // dashes and underscores). + while (*p && (isalnum(*p) || *p == '-' || *p == '_')) + p++; + + if (*p == '\0') + error("Config file buggy: missing ] in line %d", lineno); + else if (*p != ']') + error("Config file buggy: Invalid character '%c' occured in section name in line %d", *p, lineno); + + domain = String(line.c_str() + 1, p); + + // Store domain comment + if (domain == kApplicationDomain) { + _appDomain.setDomainComment(comment); + } else { + _gameDomains[domain].setDomainComment(comment); } + comment.clear(); - if (line.size() == 0) { - // Do nothing - } else if (line[0] == '#') { - // Accumulate comments here. Once we encounter either the start - // of a new domain, or a key-value-pair, we associate the value - // of the 'comment' variable with that entity. - comment += line; - } else if (line[0] == '[') { - // It's a new domain which begins here. - const char *p = line.c_str() + 1; - // Get the domain name, and check whether it's valid (that - // is, verify that it only consists of alphanumerics, - // dashes and underscores). - while (*p && (isalnum(*p) || *p == '-' || *p == '_')) - p++; - - switch (*p) { - case '\0': - error("Config file buggy: missing ] in line %d", lineno); - break; - case ']': - domain = String(line.c_str() + 1, p - (line.c_str() + 1)); - //domain = String(line.c_str() + 1, p); // TODO: Pending Common::String changes - break; - default: - error("Config file buggy: Invalid character '%c' occured in domain name in line %d", *p, lineno); - } - - // Store domain comment - if (domain == kApplicationDomain) { - _appDomain.setDomainComment(comment); - } else { - _gameDomains[domain].setDomainComment(comment); - } - comment.clear(); - - _domainSaveOrder.push_back(domain); + _domainSaveOrder.push_back(domain); + } else { + // This line should be a line with a 'key=value' pair, or an empty one. + + // Skip leading whitespaces + const char *t = line.c_str(); + while (isspace(*t)) + t++; + + // Skip empty lines / lines with only whitespace + if (*t == 0) + continue; + + // If no domain has been set, this config file is invalid! + if (domain.empty()) { + error("Config file buggy: Key/value pair found outside a domain in line %d", lineno); + } + + // Split string at '=' into 'key' and 'value'. First, find the "=" delimeter. + const char *p = strchr(t, '='); + if (!p) + error("Config file buggy: Junk found in line line %d: '%s'", lineno, t); + + // Extract the key/value pair + String key(t, p); + String value(p + 1); + + // Trim of spaces + key.trim(); + value.trim(); + + // Finally, store the key/value pair in the active domain + set(key, value, domain); + + // Store comment + if (domain == kApplicationDomain) { + _appDomain.setKVComment(key, comment); } else { - // This line should be a line with a 'key=value' pair, or an empty one. - - // Skip leading whitespaces - const char *t = line.c_str(); - while (isspace(*t)) - t++; - - // Skip empty lines / lines with only whitespace - if (*t == 0) - continue; - - // If no domain has been set, this config file is invalid! - if (domain.empty()) { - error("Config file buggy: Key/value pair found outside a domain in line %d", lineno); - } - - // Split string at '=' into 'key' and 'value'. First, find the "=" delimeter. - const char *p = strchr(t, '='); - if (!p) - error("Config file buggy: Junk found in line line %d: '%s'", lineno, t); - - // Trim spaces before the '=' to obtain the key - const char *p2 = p; - while (p2 > t && isspace(*(p2-1))) - p2--; - String key(t, p2 - t); - - // Skip spaces after the '=' - t = p + 1; - while (isspace(*t)) - t++; - - // Trim trailing spaces - p2 = t + strlen(t); - while (p2 > t && isspace(*(p2-1))) - p2--; - - String value(t, p2 - t); - - // Finally, store the key/value pair in the active domain - set(key, value, domain); - - // Store comment - if (domain == kApplicationDomain) { - _appDomain.setKVComment(key, comment); - } else { - _gameDomains[domain].setKVComment(key, comment); - } - comment.clear(); + _gameDomains[domain].setKVComment(key, comment); } + comment.clear(); } } } void ConfigManager::flushToDisk() { #ifndef __DC__ - DumpFile cfg_file; + WriteStream *stream; - if (!cfg_file.open(_filename)) { - warning("Unable to write configuration file: %s", _filename.c_str()); + if (_filename.empty()) { + // Write to the default config file + stream = g_system->openConfigFileForWriting(); + if (!stream) // If writing to the config file is not possible, do nothing + return; } else { - // First write the domains in _domainSaveOrder, in that order. - // Note: It's possible for _domainSaveOrder to list domains which - // are not present anymore. - StringList::const_iterator i; - for (i = _domainSaveOrder.begin(); i != _domainSaveOrder.end(); ++i) { - if (kApplicationDomain == *i) { - writeDomain(cfg_file, *i, _appDomain); - } else if (_gameDomains.contains(*i)) { - writeDomain(cfg_file, *i, _gameDomains[*i]); - } + DumpFile *dump = new DumpFile(); + assert(dump); + + if (!dump->open(_filename)) { + warning("Unable to write configuration file: %s", _filename.c_str()); + delete dump; + return; } + + stream = dump; + } - DomainMap::const_iterator d; + // First write the domains in _domainSaveOrder, in that order. + // Note: It's possible for _domainSaveOrder to list domains which + // are not present anymore. + StringList::const_iterator i; + for (i = _domainSaveOrder.begin(); i != _domainSaveOrder.end(); ++i) { + if (kApplicationDomain == *i) { + writeDomain(*stream, *i, _appDomain); + } else if (_gameDomains.contains(*i)) { + writeDomain(*stream, *i, _gameDomains[*i]); + } + } + DomainMap::const_iterator d; - // Now write the domains which haven't been written yet - if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), kApplicationDomain) == _domainSaveOrder.end()) - writeDomain(cfg_file, kApplicationDomain, _appDomain); - for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) { - if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), d->_key) == _domainSaveOrder.end()) - writeDomain(cfg_file, d->_key, d->_value); - } + + // Now write the domains which haven't been written yet + if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), kApplicationDomain) == _domainSaveOrder.end()) + writeDomain(*stream, kApplicationDomain, _appDomain); + for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) { + if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), d->_key) == _domainSaveOrder.end()) + writeDomain(*stream, d->_key, d->_value); } + + delete stream; + #endif // !__DC__ } diff --git a/common/config-manager.h b/common/config-manager.h index bebb59b539..9e5b88a073 100644 --- a/common/config-manager.h +++ b/common/config-manager.h @@ -36,7 +36,7 @@ namespace Common { class WriteStream; - +class SeekableReadStream; /** * The (singleton) configuration manager, used to query & set configuration @@ -144,19 +144,11 @@ public: bool hasGameDomain(const String &domName) const; const DomainMap & getGameDomains() const { return _gameDomains; } -/* - TODO: Callback/change notification system - typedef void (*ConfigCallback)(const ConstString &key, void *refCon); - - void registerCallback(ConfigCallback cfgc, void *refCon, const ConstString &key = String::emptyString) - void unregisterCallback(ConfigCallback cfgc, const ConstString &key = String::emptyString) -*/ - private: friend class Singleton; ConfigManager(); - void loadFile(const String &filename); + void loadFromStream(SeekableReadStream &stream); void writeDomain(WriteStream &stream, const String &name, const Domain &domain); Domain _transientDomain; diff --git a/common/system.cpp b/common/system.cpp index 8d528258f4..1362177011 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -121,3 +121,135 @@ void OSystem::clearScreen() { memset(screen->pixels, 0, screen->h * screen->pitch); unlockScreen(); } + + +/* +FIXME: The config file loading code below needs to be cleaned up. + Port specific variants should be pushed into the respective ports. + + Ideally, the default OSystem::openConfigFileForReading/Writing methods + should be removed completely. +*/ + +#include "common/file.h" + +#ifdef __PLAYSTATION2__ +#include "backends/platform/ps2/systemps2.h" +#endif + +#ifdef IPHONE +#include "backends/platform/iphone/osys_iphone.h" +#endif + +#if defined(WIN32) +#include +// winnt.h defines ARRAYSIZE, but we want our own one... +#undef ARRAYSIZE +#endif + + +#if defined(UNIX) +#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 + +static Common::String getDefaultConfigFileName() { + char configFile[MAXPATHLEN]; +#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) + OSVERSIONINFO win32OsVersion; + ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); + win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&win32OsVersion); + // Check for non-9X version of Windows. + if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { + // Use the Application Data directory of the user profile. + if (win32OsVersion.dwMajorVersion >= 5) { + if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile))) + error("Unable to access application data directory"); + } else { + if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile))) + error("Unable to access user profile directory"); + + strcat(configFile, "\\Application Data"); + CreateDirectory(configFile, NULL); + } + + strcat(configFile, "\\ScummVM"); + CreateDirectory(configFile, NULL); + strcat(configFile, "\\" DEFAULT_CONFIG_FILE); + + if (fopen(configFile, "r") == NULL) { + // Check windows directory + char oldConfigFile[MAXPATHLEN]; + GetWindowsDirectory(oldConfigFile, MAXPATHLEN); + strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE); + if (fopen(oldConfigFile, "r")) { + printf("The default location of the config file (scummvm.ini) in ScummVM has changed,\n"); + printf("under Windows NT4/2000/XP/Vista. You may want to consider moving your config\n"); + printf("file from the old default location:\n"); + printf("%s\n", oldConfigFile); + printf("to the new default location:\n"); + printf("%s\n\n", configFile); + strcpy(configFile, oldConfigFile); + } + } + } else { + // Check windows directory + GetWindowsDirectory(configFile, MAXPATHLEN); + strcat(configFile, "\\" DEFAULT_CONFIG_FILE); + } + +#elif defined(PALMOS_MODE) + strcpy(configFile,"/PALM/Programs/ScummVM/" DEFAULT_CONFIG_FILE); +#elif defined(IPHONE) + strcpy(configFile, OSystem_IPHONE::getConfigPath()); +#elif defined(__PLAYSTATION2__) + ((OSystem_PS2*)g_system)->makeConfigPath(configFile); +#elif defined(__PSP__) + strcpy(configFile, "ms0:/" DEFAULT_CONFIG_FILE); +#elif defined (__SYMBIAN32__) + strcpy(configFile, Symbian::GetExecutablePath()); + strcat(configFile, DEFAULT_CONFIG_FILE); +#elif defined(UNIX) && !defined(GP2X) && !defined(IPHONE) + // On UNIX type systems, by default we store the config file inside + // to the HOME directory of the user. + // + // GP2X is Linux based but Home dir can be read only so do not use + // it and put the config in the executable dir. + // + // On the iPhone, the home dir of the user when you launch the app + // from the Springboard, is /. Which we don't want. + const char *home = getenv("HOME"); + if (home != NULL && strlen(home) < MAXPATHLEN) + snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE); + else + strcpy(configFile, DEFAULT_CONFIG_FILE); +#else + strcpy(configFile, DEFAULT_CONFIG_FILE); +#endif + + return configFile; +} + +Common::SeekableReadStream *OSystem::openConfigFileForReading() { + Common::File *confFile = new Common::File(); + assert(confFile); + confFile->open(getDefaultConfigFileName()); + return confFile; +} + +Common::WriteStream *OSystem::openConfigFileForWriting() { +#ifdef __DC__ + return 0; +#else + Common::DumpFile *confFile = new Common::DumpFile(); + assert(confFile); + confFile->open(getDefaultConfigFileName()); + return confFile; +#endif +} diff --git a/common/system.h b/common/system.h index b895a5cfba..501d0802fd 100644 --- a/common/system.h +++ b/common/system.h @@ -44,6 +44,8 @@ namespace Common { class EventManager; class SaveFileManager; class TimerManager; + class SeekableReadStream; + class WriteStream; } class FilesystemFactory; @@ -900,10 +902,25 @@ public: /** * Returns the FilesystemFactory object, depending on the current architecture. * - * @return FilesystemFactory* The specific factory for the current architecture. + * @return the FSNode factory for the current architecture */ virtual FilesystemFactory *getFilesystemFactory() = 0; + /** + * Open the default config file for reading, by returning a suitable + * ReadStream instance. It is the callers responsiblity to delete + * the stream after use. + */ + virtual Common::SeekableReadStream *openConfigFileForReading(); + + /** + * Open the default config file for writing, by returning a suitable + * WriteStream instance. It is the callers responsiblity to delete + * the stream after use. + * + * May return 0 to indicate that writing to config file is not possible. + */ + virtual Common::WriteStream *openConfigFileForWriting(); /** * Return String which is used for backend-specific addition to theme -- cgit v1.2.3 From b54a1227d9bb53135e434ba9e00ce6cba592f6b1 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 3 Aug 2008 17:05:01 +0000 Subject: OSYSTEM: Pushed some SDL/Symbian specific code to the respective backends; made openConfigFileForReading/openConfigFileForWriting return 0 if they failed to open a file svn-id: r33585 --- common/system.cpp | 77 +++++++------------------------------------------------ 1 file changed, 9 insertions(+), 68 deletions(-) (limited to 'common') diff --git a/common/system.cpp b/common/system.cpp index 1362177011..1b18339623 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -149,62 +149,14 @@ FIXME: The config file loading code below needs to be cleaned up. #if defined(UNIX) -#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 static Common::String getDefaultConfigFileName() { char configFile[MAXPATHLEN]; -#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - OSVERSIONINFO win32OsVersion; - ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); - win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&win32OsVersion); - // Check for non-9X version of Windows. - if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { - // Use the Application Data directory of the user profile. - if (win32OsVersion.dwMajorVersion >= 5) { - if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile))) - error("Unable to access application data directory"); - } else { - if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile))) - error("Unable to access user profile directory"); - - strcat(configFile, "\\Application Data"); - CreateDirectory(configFile, NULL); - } - - strcat(configFile, "\\ScummVM"); - CreateDirectory(configFile, NULL); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - - if (fopen(configFile, "r") == NULL) { - // Check windows directory - char oldConfigFile[MAXPATHLEN]; - GetWindowsDirectory(oldConfigFile, MAXPATHLEN); - strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE); - if (fopen(oldConfigFile, "r")) { - printf("The default location of the config file (scummvm.ini) in ScummVM has changed,\n"); - printf("under Windows NT4/2000/XP/Vista. You may want to consider moving your config\n"); - printf("file from the old default location:\n"); - printf("%s\n", oldConfigFile); - printf("to the new default location:\n"); - printf("%s\n\n", configFile); - strcpy(configFile, oldConfigFile); - } - } - } else { - // Check windows directory - GetWindowsDirectory(configFile, MAXPATHLEN); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - } - -#elif defined(PALMOS_MODE) +#if defined(PALMOS_MODE) strcpy(configFile,"/PALM/Programs/ScummVM/" DEFAULT_CONFIG_FILE); #elif defined(IPHONE) strcpy(configFile, OSystem_IPHONE::getConfigPath()); @@ -212,23 +164,6 @@ static Common::String getDefaultConfigFileName() { ((OSystem_PS2*)g_system)->makeConfigPath(configFile); #elif defined(__PSP__) strcpy(configFile, "ms0:/" DEFAULT_CONFIG_FILE); -#elif defined (__SYMBIAN32__) - strcpy(configFile, Symbian::GetExecutablePath()); - strcat(configFile, DEFAULT_CONFIG_FILE); -#elif defined(UNIX) && !defined(GP2X) && !defined(IPHONE) - // On UNIX type systems, by default we store the config file inside - // to the HOME directory of the user. - // - // GP2X is Linux based but Home dir can be read only so do not use - // it and put the config in the executable dir. - // - // On the iPhone, the home dir of the user when you launch the app - // from the Springboard, is /. Which we don't want. - const char *home = getenv("HOME"); - if (home != NULL && strlen(home) < MAXPATHLEN) - snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE); - else - strcpy(configFile, DEFAULT_CONFIG_FILE); #else strcpy(configFile, DEFAULT_CONFIG_FILE); #endif @@ -239,7 +174,10 @@ static Common::String getDefaultConfigFileName() { Common::SeekableReadStream *OSystem::openConfigFileForReading() { Common::File *confFile = new Common::File(); assert(confFile); - confFile->open(getDefaultConfigFileName()); + if (!confFile->open(getDefaultConfigFileName())) { + delete confFile; + confFile = 0; + } return confFile; } @@ -249,7 +187,10 @@ Common::WriteStream *OSystem::openConfigFileForWriting() { #else Common::DumpFile *confFile = new Common::DumpFile(); assert(confFile); - confFile->open(getDefaultConfigFileName()); + if (!confFile->open(getDefaultConfigFileName())) { + delete confFile; + confFile = 0; + } return confFile; #endif } -- cgit v1.2.3 From fe9323ae578eab9dd9f76457add2f63deefbf21d Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 3 Aug 2008 18:11:27 +0000 Subject: Implemented DumpFile::open(FSNode) svn-id: r33586 --- common/file.cpp | 25 +++++++++++++++++++++++++ common/file.h | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/file.cpp b/common/file.cpp index 5b465b5e01..e84e337d2f 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -494,6 +494,31 @@ bool DumpFile::open(const String &filename) { return _handle != NULL; } +bool DumpFile::open(const FilesystemNode &node) { + assert(!_handle); + + if (!node.exists()) { + warning("File::open: Trying to open a FilesystemNode which does not exist"); + return false; + } else if (node.isDirectory()) { + warning("File::open: Trying to open a FilesystemNode which is a directory"); + return false; + } /*else if (!node.isReadable() && mode == kFileReadMode) { + warning("File::open: Trying to open an unreadable FilesystemNode object for reading"); + return false; + } else if (!node.isWritable() && mode == kFileWriteMode) { + warning("File::open: Trying to open an unwritable FilesystemNode object for writing"); + return false; + }*/ + + _handle = fopen(node.getPath().c_str(), "rb"); + + if (_handle == NULL) + debug(2, "File %s not found", node.getName().c_str()); + + return _handle != NULL; +} + void DumpFile::close() { if (_handle) fclose((FILE *)_handle); diff --git a/common/file.h b/common/file.h index 3c2520b07c..54168ffc7d 100644 --- a/common/file.h +++ b/common/file.h @@ -125,7 +125,7 @@ public: virtual ~DumpFile(); virtual bool open(const String &filename); - //virtual bool open(const FilesystemNode &node); + virtual bool open(const FilesystemNode &node); virtual void close(); -- cgit v1.2.3 From 4d5df949c7ee7066fca39b714ecdb4679fe9b629 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 3 Aug 2008 18:35:51 +0000 Subject: FilesystemNode code: some comment cleanup; added FilesystemNode::openForReading() and openForWriting() methods (for now these are simple wrappers around Common::File) svn-id: r33590 --- common/fs.cpp | 41 ++++++++++++++++++++++++++++++++++++ common/fs.h | 67 ++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 80 insertions(+), 28 deletions(-) (limited to 'common') diff --git a/common/fs.cpp b/common/fs.cpp index 7d803dacd4..3f585c6038 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -23,10 +23,13 @@ */ #include "common/util.h" +#include "common/file.h" #include "common/system.h" #include "backends/fs/abstract-fs.h" #include "backends/fs/fs-factory.h" +//namespace Common { + FilesystemNode::FilesystemNode() { } @@ -170,3 +173,41 @@ bool FilesystemNode::lookupFile(FSList &results, const Common::String &p, bool h return !results.empty(); } + +Common::SeekableReadStream *FilesystemNode::openForReading() { + if (_realNode == 0) + return 0; +#if 0 + return _realNode->openForReading(); +#else + // FIXME: Until we support openForReading in AbstractFilesystemNode, + // we just use Common::File. + Common::File *confFile = new Common::File(); + assert(confFile); + if (!confFile->open(*this)) { + delete confFile; + confFile = 0; + } + return confFile; +#endif +} + +Common::WriteStream *FilesystemNode::openForWriting() { + if (_realNode == 0) + return 0; +#if 0 + return _realNode->openForWriting(); +#else + // FIXME: Until we support openForWriting in AbstractFilesystemNode, + // we just use Common::DumpFile. + Common::DumpFile *confFile = new Common::DumpFile(); + assert(confFile); + if (!confFile->open(*this)) { + delete confFile; + confFile = 0; + } + return confFile; +#endif +} + +//} // End of namespace Common diff --git a/common/fs.h b/common/fs.h index ed7355cc00..972e0d86af 100644 --- a/common/fs.h +++ b/common/fs.h @@ -29,10 +29,18 @@ #include "common/ptr.h" #include "common/str.h" +class AbstractFilesystemNode; + +namespace Common { + class SeekableReadStream; + class WriteStream; +} + //namespace Common { class FilesystemNode; -class AbstractFilesystemNode; +//class SeekableReadStream; +//class WriteStream; /** * List of multiple file system nodes. E.g. the contents of a given directory. @@ -49,22 +57,6 @@ class FSList : public Common::Array {}; * To this end, we abstract away from paths; implementations can be based on * paths (and it's left to them whether / or \ or : is the path separator :-); * but it is also possible to use inodes or vrefs (MacOS 9) or anything else. - * - * NOTE: Backends still have to provide a way to extract a path from a FSIntern - * - * You may ask now: "isn't this cheating? Why do we go through all this when we use - * a path in the end anyway?!?". - * Well, for once as long as we don't provide our own file open/read/write API, we - * still have to use fopen(). Since all our targets already support fopen(), it should - * be possible to get a fopen() compatible string for any file system node. - * - * Secondly, with this abstraction layer, we still avoid a lot of complications based on - * differences in FS roots, different path separators, or even systems with no real - * paths (MacOS 9 doesn't even have the notion of a "current directory"). - * And if we ever want to support devices with no FS in the classical sense (Palm...), - * we can build upon this. - * - * This class acts as a wrapper around the AbstractFilesystemNode class defined in backends/fs. */ class FilesystemNode { private: @@ -108,9 +100,9 @@ public: bool operator<(const FilesystemNode& node) const; /** - * Indicates whether the object referred by this path exists in the filesystem or not. + * Indicates whether the object referred by this node exists in the filesystem or not. * - * @return bool true if the path exists, false otherwise. + * @return bool true if the node exists, false otherwise. */ virtual bool exists() const; @@ -168,7 +160,7 @@ public: FilesystemNode getParent() const; /** - * Indicates whether the path refers to a directory or not. + * Indicates whether the node refers to a directory or not. * * @todo Currently we assume that a node that is not a directory * automatically is a file (ignoring things like symlinks or pipes). @@ -179,28 +171,28 @@ public: virtual bool isDirectory() const; /** - * Indicates whether the object referred by this path can be read from or not. + * Indicates whether the object referred by this node can be read from or not. * - * If the path refers to a directory, readability implies being able to read + * If the node refers to a directory, readability implies being able to read * and list the directory entries. * - * If the path refers to a file, readability implies being able to read the + * If the node refers to a file, readability implies being able to read the * contents of the file. * - * @return bool true if the object can be read, false otherwise. + * @return true if the object can be read, false otherwise. */ virtual bool isReadable() const; /** - * Indicates whether the object referred by this path can be written to or not. + * Indicates whether the object referred by this node can be written to or not. * - * If the path refers to a directory, writability implies being able to modify + * If the node refers to a directory, writability implies being able to modify * the directory entry (i.e. rename the directory, remove it or write files inside of it). * - * If the path refers to a file, writability implies being able to write data + * If the node refers to a file, writability implies being able to write data * to the file. * - * @return bool true if the object can be written to, false otherwise. + * @return true if the object can be written to, false otherwise. */ virtual bool isWritable() const; @@ -221,6 +213,25 @@ public: * @return true if matches could be found, false otherwise. */ virtual bool lookupFile(FSList &results, const Common::String &pattern, bool hidden, bool exhaustive, int depth = -1) const; + + + /** + * Creates a SeekableReadStream instance corresponding to the file + * referred by this node. This assumes that the node actually refers + * to a readable file. If this is not the case, 0 is returned. + * + * @return pointer to the stream object, 0 in case of a failure + */ + virtual Common::SeekableReadStream *openForReading(); + + /** + * Creates a WriteStream instance corresponding to the file + * referred by this node. This assumes that the node actually refers + * to a readable file. If this is not the case, 0 is returned. + * + * @return pointer to the stream object, 0 in case of a failure + */ + virtual Common::WriteStream *openForWriting(); }; //} // End of namespace Common -- cgit v1.2.3 From 99f546caad19cf15d4f8769672dd01ffc340d961 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 4 Aug 2008 11:30:47 +0000 Subject: Moved the OutSaveFile::finalize method to WriteStream; implemented DumpFile::flush() svn-id: r33604 --- common/file.cpp | 7 +++++++ common/file.h | 4 +++- common/savefile.h | 17 +++-------------- common/stream.h | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 15 deletions(-) (limited to 'common') diff --git a/common/file.cpp b/common/file.cpp index e84e337d2f..94b3e48930 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -553,5 +553,12 @@ uint32 DumpFile::write(const void *ptr, uint32 len) { return (uint32)fwrite(ptr, 1, len, (FILE *)_handle); } +void DumpFile::flush() { + assert(_handle); + // TODO: Should check the return value of fflush, and if it is non-zero, + // check errno and set an error flag. + fflush((FILE *)_handle); +} + } // End of namespace Common diff --git a/common/file.h b/common/file.h index 54168ffc7d..3adeb6ff36 100644 --- a/common/file.h +++ b/common/file.h @@ -148,7 +148,9 @@ public: */ virtual bool eof() const; - uint32 write(const void *dataPtr, uint32 dataSize); + virtual uint32 write(const void *dataPtr, uint32 dataSize); + + virtual void flush(); }; diff --git a/common/savefile.h b/common/savefile.h index f30ddfc160..aa91b5859d 100644 --- a/common/savefile.h +++ b/common/savefile.h @@ -39,6 +39,7 @@ namespace Common { * That typically means "save games", but also includes things like the * IQ points in Indy3. */ +//typedef SeekableReadStream InSaveFile; class InSaveFile : public SeekableReadStream {}; /** @@ -46,20 +47,8 @@ class InSaveFile : public SeekableReadStream {}; * That typically means "save games", but also includes things like the * IQ points in Indy3. */ -class OutSaveFile : public WriteStream { -public: - /** - * Close this savefile, to be called right before destruction of this - * savefile. The idea is that this ways, I/O errors that occur - * during closing/flushing of the file can still be handled by the - * game engine. - * - * By default, this just flushes the stream. - */ - virtual void finalize() { - flush(); - } -}; +//typedef WriteStream OutSaveFile; +class OutSaveFile : public WriteStream {}; /** diff --git a/common/stream.h b/common/stream.h index d07579c2d1..01a946e685 100644 --- a/common/stream.h +++ b/common/stream.h @@ -78,6 +78,22 @@ public: */ virtual void flush() {} + /** + * Finalize and close this stream. To be called right before this + * stream instance is deleted. The goal here is to enable calling + * code to detect and handle I/O errors which might occur when + * closing (and this flushing, if buffered) the stream. + * + * After this method has been called, no further writes may be + * peformed on the stream. Calling ioFailed() is allowed. + * + * By default, this just flushes the stream. + */ + virtual void finalize() { + flush(); + } + + // The remaining methods all have default implementations; subclasses // need not (and should not) overload them. -- cgit v1.2.3 From 5f4c9f913f60d1098cbe527a9a4acabd39c5c23b Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 4 Aug 2008 11:38:25 +0000 Subject: Turned InSaveFile & OutSaveFile into simple typedefs svn-id: r33606 --- common/savefile.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'common') diff --git a/common/savefile.h b/common/savefile.h index aa91b5859d..d44f946d48 100644 --- a/common/savefile.h +++ b/common/savefile.h @@ -39,16 +39,14 @@ namespace Common { * That typically means "save games", but also includes things like the * IQ points in Indy3. */ -//typedef SeekableReadStream InSaveFile; -class InSaveFile : public SeekableReadStream {}; +typedef SeekableReadStream InSaveFile; /** * A class which allows game engines to save game state data. * That typically means "save games", but also includes things like the * IQ points in Indy3. */ -//typedef WriteStream OutSaveFile; -class OutSaveFile : public WriteStream {}; +typedef WriteStream OutSaveFile; /** -- cgit v1.2.3 From 05968b18c9dac22951618ce885d8e1587d94d324 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 4 Aug 2008 13:25:30 +0000 Subject: Modified DumpFile::open to accept non-existing nodes, and to actually open files in write mode -- d'oh svn-id: r33609 --- common/file.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/common/file.cpp b/common/file.cpp index 94b3e48930..fb837b9499 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -497,10 +497,7 @@ bool DumpFile::open(const String &filename) { bool DumpFile::open(const FilesystemNode &node) { assert(!_handle); - if (!node.exists()) { - warning("File::open: Trying to open a FilesystemNode which does not exist"); - return false; - } else if (node.isDirectory()) { + if (node.isDirectory()) { warning("File::open: Trying to open a FilesystemNode which is a directory"); return false; } /*else if (!node.isReadable() && mode == kFileReadMode) { @@ -511,7 +508,7 @@ bool DumpFile::open(const FilesystemNode &node) { return false; }*/ - _handle = fopen(node.getPath().c_str(), "rb"); + _handle = fopen(node.getPath().c_str(), "wb"); if (_handle == NULL) debug(2, "File %s not found", node.getName().c_str()); -- cgit v1.2.3 From 2efe13026d3d19583429f7e0de50b062db838980 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 4 Aug 2008 15:01:41 +0000 Subject: Fixing compilation under MSVC svn-id: r33610 --- common/system.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'common') diff --git a/common/system.cpp b/common/system.cpp index 1b18339623..ac45656202 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -29,6 +29,10 @@ #include "common/config-manager.h" #include "common/system.h" #include "common/timer.h" +#if defined(WIN32) && defined(ARRAYSIZE) +// winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h +#undef ARRAYSIZE +#endif #include "common/util.h" #include "graphics/colormasks.h" -- cgit v1.2.3 From 4900a3e96ec7bb8ce2414776f55f96d8c84ebb32 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 4 Aug 2008 17:46:22 +0000 Subject: Remove some code which was rendered obsolete by md5's commit r33610 svn-id: r33617 --- common/system.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'common') diff --git a/common/system.cpp b/common/system.cpp index ac45656202..e3f81a69b6 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -145,12 +145,6 @@ FIXME: The config file loading code below needs to be cleaned up. #include "backends/platform/iphone/osys_iphone.h" #endif -#if defined(WIN32) -#include -// winnt.h defines ARRAYSIZE, but we want our own one... -#undef ARRAYSIZE -#endif - #if defined(UNIX) #define DEFAULT_CONFIG_FILE ".scummvmrc" -- cgit v1.2.3 From 476e5bbb10743a8d15271363a6ccb2be1bc780e0 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Mon, 4 Aug 2008 18:14:17 +0000 Subject: List the correct engines in about, updated actions with Lure (from WinCE). Increased min heap size to 5MB svn-id: r33618 --- common/hashmap.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/hashmap.h b/common/hashmap.h index ab6e737d74..69f367de97 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -58,21 +58,19 @@ #include "common/str.h" #include "common/util.h" -// FIXME: Since this define is very system dependant, -// it should be moved to the appropriate H file instead. -// Portdefs might be a good location for example -#if !defined(__SYMBIAN32__) #define USE_HASHMAP_MEMORY_POOL -#endif - #ifdef USE_HASHMAP_MEMORY_POOL #include "common/memorypool.h" // FIXME: we sadly can't assume standard C++ to be present // on every system we support, so we should get rid of this. // The solution should be to write a simple placement new // on our own. + +// Symbian does not have but the new operator +#if !defined(__SYMBIAN32__) #include #endif +#endif namespace Common { -- cgit v1.2.3 From f7cc93f71ab5b7526a69bae5df80abeafeef5d31 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Tue, 5 Aug 2008 00:27:25 +0000 Subject: Removed unneeded #includes. svn-id: r33627 --- common/system.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'common') diff --git a/common/system.cpp b/common/system.cpp index e3f81a69b6..3e07e4ac4c 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -28,16 +28,9 @@ #include "common/config-manager.h" #include "common/system.h" -#include "common/timer.h" -#if defined(WIN32) && defined(ARRAYSIZE) -// winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h -#undef ARRAYSIZE -#endif -#include "common/util.h" #include "graphics/colormasks.h" #include "gui/message.h" -#include "sound/mixer.h" OSystem *g_system = 0; -- cgit v1.2.3 From 71f4a15e4efebf4de7a25d2b09817cf3a5aa51b5 Mon Sep 17 00:00:00 2001 From: Kostas Nakos Date: Sat, 9 Aug 2008 18:12:43 +0000 Subject: hotfix around drascula mem leak problems. see also bug report svn-id: r33716 --- common/unarj.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/unarj.cpp b/common/unarj.cpp index da88c11fc9..9a7766a41f 100644 --- a/common/unarj.cpp +++ b/common/unarj.cpp @@ -75,7 +75,7 @@ static uint32 GetCRC(byte *data, int len) { return CRC ^ 0xFFFFFFFF; } -ArjFile::ArjFile() { +ArjFile::ArjFile() : _uncompressedData(NULL) { InitCRC(); _isOpen = false; _fallBack = false; @@ -256,6 +256,11 @@ bool ArjFile::open(const Common::String &filename) { _compsize = hdr->compSize; _origsize = hdr->origSize; + // FIXME: This hotfix prevents Drascula from leaking memory. + // As far as sanity checks go this is not bad, but the engine should be fixed. + if (_uncompressedData) + free(_uncompressedData); + _uncompressedData = (byte *)malloc(_origsize); _outstream = new MemoryWriteStream(_uncompressedData, _origsize); -- cgit v1.2.3 From 39d2c3bdadfd2e27b109a82f63340d99a15cab44 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 9 Aug 2008 22:42:03 +0000 Subject: If no default config file is present, just don't load it, instead of crashing svn-id: r33729 --- common/config-manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/config-manager.cpp b/common/config-manager.cpp index a424c4f6c7..138fcc201f 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -64,9 +64,9 @@ void ConfigManager::loadDefaultConfigFile() { SeekableReadStream *stream = g_system->openConfigFileForReading(); _filename.clear(); // clear the filename to indicate that we are using the default config file - // ... load it ... - assert(stream); - loadFromStream(*stream); + // ... load it, if available ... + if (stream) + loadFromStream(*stream); // ... and close it again. delete stream; -- cgit v1.2.3 From dca7116cb54026cfa3ee25148cf3b961f7febdd2 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 9 Aug 2008 23:07:32 +0000 Subject: Use FSNode API in default OSystem::openConfigFileForReading & OSystem::openConfigFileForWriting method implementations svn-id: r33730 --- common/system.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'common') diff --git a/common/system.cpp b/common/system.cpp index 3e07e4ac4c..d0548cdd2d 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -163,25 +163,15 @@ static Common::String getDefaultConfigFileName() { } Common::SeekableReadStream *OSystem::openConfigFileForReading() { - Common::File *confFile = new Common::File(); - assert(confFile); - if (!confFile->open(getDefaultConfigFileName())) { - delete confFile; - confFile = 0; - } - return confFile; + FilesystemNode file(getDefaultConfigFileName()); + return file.openForReading(); } Common::WriteStream *OSystem::openConfigFileForWriting() { #ifdef __DC__ return 0; #else - Common::DumpFile *confFile = new Common::DumpFile(); - assert(confFile); - if (!confFile->open(getDefaultConfigFileName())) { - delete confFile; - confFile = 0; - } - return confFile; + FilesystemNode file(getDefaultConfigFileName()); + return file.openForWriting(); #endif } -- cgit v1.2.3