diff options
author | Max Horn | 2004-06-28 00:06:31 +0000 |
---|---|---|
committer | Max Horn | 2004-06-28 00:06:31 +0000 |
commit | 53af3dc6700a6e7686fbf2e88cea283d6e335124 (patch) | |
tree | dcb1a4ffb7c717e5be3ddd909b604d5845d23597 | |
parent | b1de21accbea8c333b24db91c47235bb5a8d14ef (diff) | |
download | scummvm-rg350-53af3dc6700a6e7686fbf2e88cea283d6e335124.tar.gz scummvm-rg350-53af3dc6700a6e7686fbf2e88cea283d6e335124.tar.bz2 scummvm-rg350-53af3dc6700a6e7686fbf2e88cea283d6e335124.zip |
Enhanced default directory support in the File class; now one can specify arbitrary many default search directories
svn-id: r14095
-rw-r--r-- | base/engine.cpp | 6 | ||||
-rw-r--r-- | common/file.cpp | 137 | ||||
-rw-r--r-- | common/file.h | 5 | ||||
-rw-r--r-- | scumm/scumm.cpp | 80 | ||||
-rw-r--r-- | scumm/scumm.h | 1 | ||||
-rw-r--r-- | simon/simon.cpp | 22 | ||||
-rw-r--r-- | sword1/sword1.cpp | 9 | ||||
-rw-r--r-- | sword2/sword2.cpp | 9 |
8 files changed, 143 insertions, 126 deletions
diff --git a/base/engine.cpp b/base/engine.cpp index 3c84837a71..dce6d07f8a 100644 --- a/base/engine.cpp +++ b/base/engine.cpp @@ -41,8 +41,8 @@ Engine::Engine(OSystem *syst) _timer = g_timer; - // Set default file directory - File::setDefaultDirectory(_gameDataPath); + // Add default file directory + File::addDefaultDirectory(_gameDataPath); g_debugLevel = ConfMan.getInt("debuglevel"); @@ -50,6 +50,8 @@ Engine::Engine(OSystem *syst) } Engine::~Engine() { + File::resetDefaultDirectories(); + delete _mixer; delete _timer; delete _saveFileMan; diff --git a/common/file.cpp b/common/file.cpp index 26f6fcb603..4043143fd4 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -23,7 +23,7 @@ #include "common/util.h" -Common::String File::_defaultDirectory; +Common::StringList File::_defaultDirectories; FILE *File::fopenNoCase(const char *filename, const char *directory, const char *mode) { @@ -41,17 +41,16 @@ FILE *File::fopenNoCase(const char *filename, const char *directory, const char } #endif - // Record the length of the dir name (so we can cut of anything trailing it - // later, when we try with different file names). + // Determine the length of the dir name. const int dirLen = strlen(buf); if (dirLen > 0) { #ifdef __MORPHOS__ - if (buf[dirLen-1] != ':' && buf[dirLen-1] != '/') + if (buf[dirLen-1] != ':' && buf[dirLen-1] != '/') // prevent double / #endif #if !defined(__GP32__) && !defined(__PALM_OS__) - strcat(buf, "/"); // prevent double / + strcat(buf, "/"); #endif } strcat(buf, filename); @@ -60,73 +59,49 @@ FILE *File::fopenNoCase(const char *filename, const char *directory, const char if (file) return file; - // FIXME this should probably be engine specific... - const char *dirs[] = { - "", - "rooms/", - "ROOMS/", - "Rooms 1/", - "Rooms 2/", - "Rooms 3/", - "video/", - "VIDEO/", - "data/", - "DATA/", - "resource/", - "RESOURCE/", - // Simon the Sorcerer 1 Acorn - "execute/", - "EXECUTE/", - // Simon the Sorcerer 2 Amiga/Mac - "../", - "voices/", - "VOICES/", - // sword1/2 stuff if user just copied files without putting - // them all into the same dir like original installer did - "CLUSTERS/", - "clusters/", - "SPEECH/", - "speech/", - "SWORD2/", - "sword2/" - }; - - for (int dirIdx = 0; dirIdx < ARRAYSIZE(dirs); dirIdx++) { - buf[dirLen] = 0; - if (buf[0] != 0) { + buf[dirLen] = 0; + if (buf[0] != 0) { #ifdef __MORPHOS__ - if (buf[strlen(buf) - 1] != ':' && buf[strlen(buf) - 1] != '/') + if (buf[strlen(buf) - 1] != ':' && buf[strlen(buf) - 1] != '/') #endif #ifndef __PALM_OS__ - strcat(buf, "/"); // PALMOS + strcat(buf, "/"); // PALMOS #endif - } - strcat(buf, dirs[dirIdx]); - int8 len = strlen(buf); - strcat(buf, filename); - - ptr = buf + len; - do - *ptr = toupper(*ptr); - while (*ptr++); - file = fopen(buf, mode); - if (file) - return file; - - ptr = buf + len; - do - *ptr = tolower(*ptr); - while (*ptr++); - file = fopen(buf, mode); - if (file) - return file; } + const int8 len = strlen(buf); + strcat(buf, filename); + + // + // Try again, with file name converted to upper case + // + ptr = buf + len; + while (*ptr) { + *ptr = toupper(*ptr); + ptr++; + } + file = fopen(buf, mode); + if (file) + return file; + + // + // Try again, with file name converted to lower case + // + ptr = buf + len; + while (*ptr) { + *ptr = tolower(*ptr); + ptr++; + } + file = fopen(buf, mode); return NULL; } -void File::setDefaultDirectory(const Common::String &directory) { - _defaultDirectory = directory; +void File::addDefaultDirectory(const Common::String &directory) { + _defaultDirectories.push_back(directory); +} + +void File::resetDefaultDirectories() { + _defaultDirectories.clear(); } File::File() { @@ -146,30 +121,32 @@ bool File::open(const char *filename, AccessMode mode, const char *directory) { return false; } - if (filename == NULL || *filename == 0) + if (filename == NULL || *filename == 0) { return false; - - // If no directory was specified, use the default directory (if any). - if (directory == NULL) - directory = _defaultDirectory.isEmpty() ? "" : _defaultDirectory.c_str(); + } + + if (mode != kFileReadMode && mode != kFileWriteMode) { + warning("Only read/write mode supported!"); + return false; + } clearIOFailed(); - if (mode == kFileReadMode) { - _handle = fopenNoCase(filename, directory, "rb"); - if (_handle == NULL) { - debug(2, "File %s not found", filename); - return false; + const char *modeStr = (mode == kFileReadMode) ? "rb" : "wb"; + if (directory) { + _handle = fopenNoCase(filename, directory, modeStr); + } else { + Common::StringList::const_iterator x; + for (x = _defaultDirectories.begin(); _handle == NULL && x != _defaultDirectories.end(); ++x) { + _handle = fopenNoCase(filename, x->c_str(), modeStr); } } - else if (mode == kFileWriteMode) { - _handle = fopenNoCase(filename, directory, "wb"); - if (_handle == NULL) { + + if (_handle == NULL) { + if (mode == kFileReadMode) + debug(2, "File %s not found", filename); + else debug(2, "File %s not opened", filename); - return false; - } - } else { - warning("Only read/write mode supported!"); return false; } diff --git a/common/file.h b/common/file.h index 3a268ecc5b..d2bc217dbb 100644 --- a/common/file.h +++ b/common/file.h @@ -36,7 +36,7 @@ private: static FILE *fopenNoCase(const char *filename, const char *directory, const char *mode); - static Common::String _defaultDirectory; + static Common::StringList _defaultDirectories; public: enum AccessMode { @@ -44,7 +44,8 @@ public: kFileWriteMode = 2 }; - static void setDefaultDirectory(const Common::String &directory); + static void addDefaultDirectory(const Common::String &directory); + static void resetDefaultDirectories(); File(); virtual ~File(); diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 28e83b4651..2225dda0fa 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -352,6 +352,50 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS gdi(this), _pauseDialog(0), _optionsDialog(0), _mainMenuDialog(0), _targetName(detector->_targetName) { + // Add default file directories. + // FIXME: Which games use "rooms" or "ROOMS" ??? + if (_version < 7) { + File::addDefaultDirectory(_gameDataPath + "/ROOMS/"); + File::addDefaultDirectory(_gameDataPath + "/rooms/"); + } + + if ((_features & GF_MACINTOSH) && (_version == 3)) { + // This is the for the Mac version of Indy3/Loom + File::addDefaultDirectory(_gameDataPath + "/Rooms 1/"); + File::addDefaultDirectory(_gameDataPath + "/Rooms 2/"); + File::addDefaultDirectory(_gameDataPath + "/Rooms 3/"); + } + +#ifdef MACOSX + if (_version == 8 && !memcmp(_gameDataPath.c_str(), "/Volumes/MONKEY3_", 17)) { + // Special case for COMI on Mac OS X. The mount points on OS X depend + // on the volume name. Hence if playing from CD, we'd get a problem. + // So if loading of a resource file fails, we fall back to the (fixed) + // CD mount points (/Volumes/MONKEY3_1 and /Volumes/MONKEY3_2). + // + // This check for whether we play from CD is very crude, though. + + File::addDefaultDirectory("/Volumes/MONKEY3_1/RESOURCE/"); + File::addDefaultDirectory("/Volumes/MONKEY3_1/resource/"); + File::addDefaultDirectory("/Volumes/MONKEY3_2/"); + File::addDefaultDirectory("/Volumes/MONKEY3_2/RESOURCE/"); + File::addDefaultDirectory("/Volumes/MONKEY3_2/resource/"); + } else +#endif + if (_version == 8) { + // This is for COMI + File::addDefaultDirectory(_gameDataPath + "/RESOURCE/"); + File::addDefaultDirectory(_gameDataPath + "/resource/"); + } + + if (_version == 7) { + // This is for Full Throttle & The Dig + File::addDefaultDirectory(_gameDataPath + "/VIDEO/"); + File::addDefaultDirectory(_gameDataPath + "/video/"); + File::addDefaultDirectory(_gameDataPath + "/DATA/"); + File::addDefaultDirectory(_gameDataPath + "/data/"); + } + // Init all vars - maybe now we can get rid of our custom new/delete operators? _imuse = NULL; _imuseDigital = NULL; @@ -2770,42 +2814,6 @@ byte *ScummEngine::get2byteCharPtr(int idx) { return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx; } - -const char *ScummEngine::getGameDataPath() const { -#ifdef MACOSX - if (_version == 8 && !memcmp(_gameDataPath.c_str(), "/Volumes/MONKEY3_", 17)) { - // TODO: The following hack is currently inactive, since Fingolfin - // removed most calls to getGameDataPath(). This will soon be put - // back into place once the File::setDefaultDirectory() method is - // replaced by a more flexible system... - - - // Special case for COMI on Mac OS X. The mount points on OS X depend - // on the volume name. Hence if playing from CD, we'd get a problem. - // So if loading of a resource file fails, we fall back to the (fixed) - // CD mount points (/Volumes/MONKEY3_1 and /Volumes/MONKEY3_2). - // - // The check for whether we play from CD or not is very hackish, though. - static char buf[256]; - struct stat st; - int disk = (_scummVars && _scummVars[VAR_CURRENTDISK] == 2) ? 2 : 1; - sprintf(buf, "/Volumes/MONKEY3_%d", disk); - - if (!stat(buf, &st)) { - return buf; - } - - // Apparently that disk is not inserted. However since many data files - // (fonts, comi.la0) are on both disks, we also try the other CD. - disk = (disk == 1) ? 2 : 1; - sprintf(buf, "/Volumes/MONKEY3_%d", disk); - return buf; - } -#endif - - return _gameDataPath.c_str(); -} - void ScummEngine::errorString(const char *buf1, char *buf2) { if (_currentScript != 0xFF) { ScriptSlot *ss = &vm.slot[_currentScript]; diff --git a/scumm/scumm.h b/scumm/scumm.h index d43504a3e6..0d08b7da1b 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -387,7 +387,6 @@ public: // Misc utility functions uint32 _debugFlags; const char *getGameName() const { return _gameName.c_str(); } - const char *getGameDataPath() const; // Cursor/palette void updateCursor(); diff --git a/simon/simon.cpp b/simon/simon.cpp index 624f601aba..a273088bbf 100644 --- a/simon/simon.cpp +++ b/simon/simon.cpp @@ -269,17 +269,29 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst) SOUND_INDEX_BASE = 0; } - if (_game & GF_MAC) + if (_game & GF_MAC) { gss = PTR(simon2mac_settings); - else if ((_game & GF_SIMON2) && (_game & GF_TALKIE)) + + // Add default file directories + File::addDefaultDirectory(_gameDataPath + "/voices/"); + File::addDefaultDirectory(_gameDataPath + "/VOICES/"); + } else if ((_game & GF_SIMON2) && (_game & GF_TALKIE)) gss = PTR(simon2win_settings); else if (_game & GF_SIMON2) gss = PTR(simon2dos_settings); - else if (_game & GF_ACORN) + else if (_game & GF_ACORN) { gss = PTR(simon1acorn_settings); - else if (_game & GF_AMIGA) + + // Add default file directories + File::addDefaultDirectory(_gameDataPath + "/execute/"); + File::addDefaultDirectory(_gameDataPath + "/EXECUTE/"); + } else if (_game & GF_AMIGA) { gss = PTR(simon1amiga_settings); - else if (_game & GF_DEMO) + + // Add default file directories + File::addDefaultDirectory(_gameDataPath + "/voices/"); + File::addDefaultDirectory(_gameDataPath + "/VOICES/"); + } else if (_game & GF_DEMO) gss = PTR(simon1demo_settings); else gss = PTR(simon1_settings); diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 8fceede44f..d129d5bee1 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -97,6 +97,15 @@ SwordEngine::~SwordEngine() { } void SwordEngine::initialize(void) { + + // Add default file directories + File::addDefaultDirectory(_gameDataPath + "/CLUSTERS/"); + File::addDefaultDirectory(_gameDataPath + "/SPEECH/"); + File::addDefaultDirectory(_gameDataPath + "/VIDEO/"); + File::addDefaultDirectory(_gameDataPath + "/clusters/"); + File::addDefaultDirectory(_gameDataPath + "/speech/"); + File::addDefaultDirectory(_gameDataPath + "/video/"); + _system->initSize(640, 480); debug(5, "Starting memory manager"); _memMan = new MemMan(); diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index 873efcd851..e91ead0895 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -22,6 +22,7 @@ #include "base/gameDetector.h" #include "base/plugins.h" #include "common/config-manager.h" +#include "common/file.h" #include "sword2/sword2.h" #include "sword2/console.h" #include "sword2/controls.h" @@ -101,6 +102,14 @@ Sword2Engine *g_sword2 = NULL; Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst) : Engine(syst) { + // Add default file directories + File::addDefaultDirectory(_gameDataPath + "/CLUSTERS/"); + File::addDefaultDirectory(_gameDataPath + "/SWORD2/"); + File::addDefaultDirectory(_gameDataPath + "/VIDEO/"); + File::addDefaultDirectory(_gameDataPath + "/clusters/"); + File::addDefaultDirectory(_gameDataPath + "/sword2/"); + File::addDefaultDirectory(_gameDataPath + "/video/"); + g_sword2 = this; _debugger = NULL; _sound = NULL; |