diff options
-rw-r--r-- | base/main.cpp | 13 | ||||
-rw-r--r-- | common/file.cpp | 79 | ||||
-rw-r--r-- | common/file.h | 7 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/kyra.cpp | 2 | ||||
-rw-r--r-- | engines/lure/lure.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/he/script_v72he.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/he/script_v80he.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/plugin.cpp | 4 |
9 files changed, 106 insertions, 11 deletions
diff --git a/base/main.cpp b/base/main.cpp index b2f32edb1e..dba2eeacb7 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -276,6 +276,10 @@ static bool launcherDialog(GameDetector &detector, OSystem &system) { } static int runGame(GameDetector &detector, OSystem &system, const Common::String &edebuglevels) { + // We add it here, so MD5-based detection will be able to + // read mixed case files + Common::File::addDefaultDirectory(ConfMan.get("path")); + // Create the game engine Engine *engine = detector.createEngine(&system); if (!engine) { @@ -301,12 +305,17 @@ static int runGame(GameDetector &detector, OSystem &system, const Common::String system.setWindowCaption(caption.c_str()); } + Common::File::addDefaultDirectoryRecursive(ConfMan.get("path")); + // Add extrapath (if any) to the directory search list if (ConfMan.hasKey("extrapath")) - Common::File::addDefaultDirectory(ConfMan.get("extrapath")); + Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath")); if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) - Common::File::addDefaultDirectory(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain)); + Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain)); + + // As a last resort add current directory and lock further additions + Common::File::addDefaultDirectory(".", true); int result; diff --git a/common/file.cpp b/common/file.cpp index 8d0658818b..90f211ccd4 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -22,6 +22,7 @@ #include "common/file.h" #include "common/util.h" +#include "backends/fs/fs.h" #ifdef MACOSX #include "CoreFoundation/CoreFoundation.h" @@ -30,6 +31,8 @@ namespace Common { StringList File::_defaultDirectories; +File::FilesMap File::_filesMap; +bool File::_lockedDirectories; static FILE *fopenNoCase(const char *filename, const char *directory, const char *mode) { @@ -105,16 +108,80 @@ static FILE *fopenNoCase(const char *filename, const char *directory, const char return file; } -void File::addDefaultDirectory(const String &directory) { +void File::addDefaultDirectory(const String &directory, bool lockDirectories) { + String lfn; + + if (_lockedDirectories) + error("addDefaultDirectory is called too late. Move all calls to engine constructor"); + + _lockedDirectories = lockDirectories; + + FilesystemNode dir(directory.c_str()); + + if (!dir.isDirectory()) + return; + _defaultDirectories.push_back(directory); + + FSList fslist(dir.listDir(FilesystemNode::kListFilesOnly)); + + for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + lfn = file->displayName(); + lfn.toLowercase(); + if (!_filesMap.contains(lfn)) + _filesMap[lfn] = file->path(); + } +} + +void File::addDefaultDirectoryRecursive(const String &directory, int level, int baseLen) { + if (level > 4) + return; + + String lfn; + + if (_lockedDirectories) + error("addDefaultDirectoryRecursive is called too late. Move all calls to engine constructor"); + + FilesystemNode dir(directory.c_str()); + + if (!dir.isDirectory()) + return; + + _defaultDirectories.push_back(directory); + + if (baseLen == 0) { + baseLen = directory.size(); + if (directory.lastChar() != '/' +#if defined(__MORPHOS__) || defined(__amigaos4__) + && directory.lastChar() != ':' +#endif + && directory.lastChar() != '\\') + baseLen++; + } + + FSList fslist(dir.listDir(FilesystemNode::kListAll)); + + for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (file->isDirectory()) { + addDefaultDirectoryRecursive(file->path(), level + 1, baseLen); + } else { + lfn = String(file->path().c_str() + baseLen); + lfn.toLowercase(); + if (!_filesMap.contains(lfn)) + _filesMap[lfn] = file->path(); + } + } } void File::resetDefaultDirectories() { _defaultDirectories.clear(); + _filesMap.clear(); + _lockedDirectories = false; } File::File() - : _handle(0), _ioFailed(false), _refcount(1) { + : _handle(0), _ioFailed(false), _refcount(1) { + _lockedDirectories = false; } //#define DEBUG_FILE_REFCOUNT @@ -155,10 +222,18 @@ bool File::open(const char *filename, AccessMode mode, const char *directory) { clearIOFailed(); + String fname(filename); + + fname.toLowercase(); + const char *modeStr = (mode == kFileReadMode) ? "rb" : "wb"; if (mode == kFileWriteMode || directory) { _handle = fopenNoCase(filename, directory ? directory : "", modeStr); + } else if (_filesMap.contains(fname)) { + debug(3, "Opening hashed: %s", _filesMap[fname].c_str()); + _handle = fopen(_filesMap[fname].c_str(), modeStr); } else { + StringList::const_iterator x; // Try all default directories for (x = _defaultDirectories.begin(); _handle == NULL && x != _defaultDirectories.end(); ++x) { diff --git a/common/file.h b/common/file.h index e5c4fd0d2d..306dc3a915 100644 --- a/common/file.h +++ b/common/file.h @@ -27,6 +27,7 @@ #include "common/scummsys.h" #include "common/str.h" #include "common/stream.h" +#include "common/assocarray.h" namespace Common { @@ -44,8 +45,11 @@ protected: /** The name of this file, for debugging. */ String _name; + typedef AssocArray<String, String> FilesMap; static StringList _defaultDirectories; + static FilesMap _filesMap; + static bool _lockedDirectories; public: enum AccessMode { @@ -53,7 +57,8 @@ public: kFileWriteMode = 2 }; - static void addDefaultDirectory(const String &directory); + static void addDefaultDirectory(const String &directory, bool lockDirectories = false); + static void addDefaultDirectoryRecursive(const String &directory, int level = 0, int baseLen = 0); static void resetDefaultDirectories(); File(); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 58bf4252a8..2dbee4cd1f 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -343,7 +343,7 @@ Engine *Engine_GOB_create(GameDetector * detector, OSystem *syst) { uint8 md5sum[16]; char md5str[32 + 1]; - if (Common::md5_file("intro.stk", md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) { + if (Common::md5_file("intro.stk", md5sum, NULL, kMD5FileSizeLimit)) { for (int j = 0; j < 16; j++) { sprintf(md5str + j*2, "%02x", (int)md5sum[j]); } diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index be56e05a44..051260f77c 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -276,7 +276,7 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *system) if (!Common::File::exists(g->checkFile)) continue; - if (Common::md5_file(g->checkFile, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) { + if (Common::md5_file(g->checkFile, md5sum, NULL, kMD5FileSizeLimit)) { for (int j = 0; j < 16; j++) { sprintf(md5str + j*2, "%02x", (int)md5sum[j]); } diff --git a/engines/lure/lure.cpp b/engines/lure/lure.cpp index 1aa37046e7..a034fec156 100644 --- a/engines/lure/lure.cpp +++ b/engines/lure/lure.cpp @@ -221,7 +221,7 @@ void LureEngine::detectGame() { if (!Common::File::exists(g->checkFile)) continue; - if (Common::md5_file(g->checkFile, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) { + if (Common::md5_file(g->checkFile, md5sum, NULL, kMD5FileSizeLimit)) { for (int j = 0; j < 16; j++) { sprintf(md5str + j * 2, "%02x", (int)md5sum[j]); } diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 105ff8cb6b..dfa04811eb 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -560,7 +560,7 @@ int ScummEngine_v72he::convertFilePath(byte *dst, bool setFilePath) { if (setFilePath) { char filePath[256]; - sprintf(filePath, "%s%s", _gameDataPath.c_str(), dst + r); + sprintf(filePath, "%s", dst + r); if (!Common::File::exists(filePath)) { sprintf(filePath, "%s%s", _saveFileMan->getSavePath(), dst + r); } diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp index 6bb48c7ab1..c4de1bc7b6 100644 --- a/engines/scumm/he/script_v80he.cpp +++ b/engines/scumm/he/script_v80he.cpp @@ -399,9 +399,15 @@ void ScummEngine_v80he::o80_createSound() { void ScummEngine_v80he::o80_getFileSize() { byte filename[256]; + uint i; copyScriptString(filename, sizeof(filename)); + for (i = 0; i < strlen((const char *)filename); i++) { + if (filename[i] == '\\') + filename[i] = '/'; + } + Common::File f; if (!f.open((char *)filename)) { push(-1); diff --git a/engines/scumm/plugin.cpp b/engines/scumm/plugin.cpp index 4ff003e0e2..946e20e0bf 100644 --- a/engines/scumm/plugin.cpp +++ b/engines/scumm/plugin.cpp @@ -1595,7 +1595,7 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { // Instead, use the fs.h code to get a list of all files in that // directory and simply check whether that filename is contained // in it. - if (Common::File::exists(detectName, ConfMan.get("path").c_str())) { + if (Common::File::exists(detectName)) { found = true; break; } @@ -1630,7 +1630,7 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { } else { // Compute the MD5 of the file, and (if we succeeded) store a hex version // of it in gameMD5 (useful to print it to the user in messages). - if (Common::md5_file(detectName, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) { + if (Common::md5_file(detectName, md5sum, NULL, kMD5FileSizeLimit)) { for (int j = 0; j < 16; j++) { sprintf(gameMD5 + j*2, "%02x", (int)md5sum[j]); } |