aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/wintermute/base/base_file_manager.cpp2
-rw-r--r--engines/wintermute/base/file/base_disk_file.cpp76
-rw-r--r--engines/wintermute/base/file/base_disk_file.h2
3 files changed, 42 insertions, 38 deletions
diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp
index 1e3e94c4f4..addce1dea4 100644
--- a/engines/wintermute/base/base_file_manager.cpp
+++ b/engines/wintermute/base/base_file_manager.cpp
@@ -514,7 +514,7 @@ Common::SeekableReadStream *BaseFileManager::openFileRaw(const Common::String &f
return ret;
}
- ret = openDiskFile(filename, this);
+ ret = openDiskFile(filename);
if (ret)
return ret;
diff --git a/engines/wintermute/base/file/base_disk_file.cpp b/engines/wintermute/base/file/base_disk_file.cpp
index 21f7c7c189..09a83f5768 100644
--- a/engines/wintermute/base/file/base_disk_file.cpp
+++ b/engines/wintermute/base/file/base_disk_file.cpp
@@ -46,43 +46,63 @@ void correctSlashes(char *fileName) {
}
}
-bool diskFileExists(const Common::String& filename) {
- // Try directly from SearchMan first
- Common::ArchiveMemberList files;
- SearchMan.listMatchingMembers(files, filename);
-
- for (Common::ArchiveMemberList::iterator it = files.begin(); it != files.end(); it++) {
- if ((*it)->getName() == filename) {
- return true;
- }
- }
+// Parse a relative path in the game-folder, and if it exists, return a FSNode to it.
+static Common::FSNode getNodeForRelativePath(const Common::String& filename) {
// The filename can be an explicit path, thus we need to chop it up, expecting the path the game
// specifies to follow the Windows-convention of folder\subfolder\file (absolute paths should not happen)
+
+ // Absolute path: TODO: Add specific fallbacks here.
if (filename.contains(':'))
error("openDiskFile::Absolute path or invalid filename used in %s", filename.c_str());
+
+ // Relative path:
if (filename.contains('\\')) {
Common::StringTokenizer path(filename, "\\");
-
+
+ // Start traversing relative to the game-data-dir
const Common::FSNode gameDataDir(ConfMan.get("path"));
Common::FSNode curNode = gameDataDir;
+
+ // Parse all path-elements
while (!path.empty()) {
+ // Get the next path-component by slicing on '\\'
Common::String pathPart = path.nextToken();
+ // Get the next FSNode in the chain, if it exists as a child from the previous.
Common::FSNode nextNode(curNode.getChild(pathPart));
if (nextNode.exists() && nextNode.isReadable()) {
curNode = nextNode;
}
+ // Following the comments in common/fs.h, anything not a directory is a file.
if (!curNode.isDirectory()) {
- if (curNode.exists() && curNode.isReadable())
- return true;
- else
- return false;
+ assert(path.empty());
+ return curNode;
+ break;
}
}
}
+ // Return an invalid FSNode to mark that we didn't find the requested file.
+ return Common::FSNode();
+}
+
+bool diskFileExists(const Common::String& filename) {
+ // Try directly from SearchMan first
+ Common::ArchiveMemberList files;
+ SearchMan.listMatchingMembers(files, filename);
+
+ for (Common::ArchiveMemberList::iterator it = files.begin(); it != files.end(); it++) {
+ if ((*it)->getName() == filename) {
+ return true;
+ }
+ }
+ // File wasn't found in SearchMan, try to parse the path as a relative path.
+ Common::FSNode searchNode = getNodeForRelativePath(filename);
+ if (searchNode.exists() && !searchNode.isDirectory() && searchNode.isReadable()) {
+ return true;
+ }
return false;
}
-Common::SeekableReadStream *openDiskFile(const Common::String &filename, BaseFileManager *fileManager) {
+Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
uint32 prefixSize = 0;
Common::SeekableReadStream *file = NULL;
// Try directly from SearchMan first
@@ -95,27 +115,11 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename, BaseFil
break;
}
}
- // The filename can be an explicit path, thus we need to chop it up, expecting the path the game
- // specifies to follow the Windows-convention of folder\subfolder\file (absolute paths should not happen)
+ // File wasn't found in SearchMan, try to parse the path as a relative path.
if (!file) {
- if (filename.contains(':'))
- error("openDiskFile::Absolute path or invalid filename used in %s", filename.c_str());
- if (filename.contains('\\')) {
- Common::StringTokenizer path(filename, "\\");
-
- const Common::FSNode gameDataDir(ConfMan.get("path"));
- Common::FSNode curNode = gameDataDir;
- while (!path.empty()) {
- Common::String pathPart = path.nextToken();
- Common::FSNode nextNode(curNode.getChild(pathPart));
- if (nextNode.exists() && nextNode.isReadable()) {
- curNode = nextNode;
- }
- if (!curNode.isDirectory()) {
- file = curNode.createReadStream();
- break;
- }
- }
+ Common::FSNode searchNode = getNodeForRelativePath(filename);
+ if (searchNode.exists() && !searchNode.isDirectory() && searchNode.isReadable()) {
+ file = searchNode.createReadStream();
}
}
if (file) {
diff --git a/engines/wintermute/base/file/base_disk_file.h b/engines/wintermute/base/file/base_disk_file.h
index 13d5c3e03c..0653b2e854 100644
--- a/engines/wintermute/base/file/base_disk_file.h
+++ b/engines/wintermute/base/file/base_disk_file.h
@@ -33,7 +33,7 @@
namespace WinterMute {
-Common::SeekableReadStream *openDiskFile(const Common::String &filename, BaseFileManager *fileManager);
+Common::SeekableReadStream *openDiskFile(const Common::String &filename);
bool diskFileExists(const Common::String& filename);
} // end of namespace WinterMute