aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/archive.cpp46
-rw-r--r--common/archive.h46
-rw-r--r--common/file.cpp10
-rw-r--r--common/file.h4
-rw-r--r--engines/agos/agos.cpp18
-rw-r--r--engines/groovie/groovie.cpp6
-rw-r--r--engines/m4/m4.cpp5
-rw-r--r--engines/saga/saga.cpp16
-rw-r--r--engines/scumm/scumm.cpp29
-rw-r--r--engines/sword1/sword1.cpp20
-rw-r--r--engines/sword2/sword2.cpp12
-rw-r--r--engines/tinsel/tinsel.cpp2
-rw-r--r--sound/softsynth/mt32.cpp3
13 files changed, 136 insertions, 81 deletions
diff --git a/common/archive.cpp b/common/archive.cpp
index ecc00f4cff..e815b781bf 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -123,6 +123,52 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority
add(name, new FSDirectory(dir, depth, flat), priority);
}
+void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String pattern, bool ignoreCase, int priority) {
+ FSList subDirs;
+ if (!directory.getChildren(subDirs))
+ return;
+
+ String nextPattern;
+ String::const_iterator sep = Common::find(pattern.begin(), pattern.end(), '/');
+ if (sep != pattern.end()) {
+ pattern = String(pattern.begin(), sep);
+
+ ++sep;
+ if (sep != pattern.end())
+ nextPattern = String(sep, pattern.end());
+ }
+
+ // TODO: The code we have for displaying all matches, which vary only in case, might
+ // be a bit overhead, but as long as we want to display all useful information to the
+ // user we will need to keep track of all directory names added so far. We might
+ // want to reconsider this though.
+ typedef HashMap<String, bool, IgnoreCase_Hash, IgnoreCase_EqualTo> MatchList;
+ MatchList multipleMatches;
+ MatchList::iterator matchIter;
+
+ for (FSList::const_iterator i = subDirs.begin(); i != subDirs.end(); ++i) {
+ String name = i->getName();
+
+ if (Common::matchString(name.c_str(), pattern.c_str(), ignoreCase)) {
+ matchIter = multipleMatches.find(name);
+ if (matchIter == multipleMatches.end()) {
+ multipleMatches[name] = true;
+ } else {
+ if (matchIter->_value) {
+ warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), matchIter->_key.c_str());
+ matchIter->_value = false;
+ }
+
+ warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), name.c_str());
+ }
+
+ if (nextPattern.empty())
+ addDirectory(name, *i, priority);
+ else
+ addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority);
+ }
+ }
+}
void SearchSet::remove(const String &name) {
ArchiveNodeList::iterator it = find(name);
diff --git a/common/archive.h b/common/archive.h
index aa13d26d16..39fce497c4 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -169,6 +169,52 @@ public:
void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
/**
+ * Create and add a sub directory by name (caseless).
+ *
+ * It is also possible to add sub directories of sub directories (of any depth) with this function.
+ * The path seperator for this case is SLASH for *all* systems.
+ *
+ * An example would be:
+ *
+ * "game/itedata"
+ *
+ * In this example the code would first try to search for all directories matching
+ * "game" (case insensitive) in the path "directory" first and search through all
+ * of the matches for "itedata" (case insensitive too).
+ *
+ * Note that it will add *all* matches found!
+ *
+ * Even though this method is currently implemented via addSubDirectoriesMatching it is not safe
+ * to assume that this method is using anything other than a simple case insensitive compare.
+ * Thus do not use any tokens like '*' or '?' in the "caselessName" parameter of this function!
+ */
+ void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0) {
+ addSubDirectoriesMatching(directory, caselessName, true, priority);
+ }
+
+ /**
+ * Create and add sub directories by pattern.
+ *
+ * It is also possible to add sub directories of sub directories (of any depth) with this function.
+ * The path seperator for this case is SLASH for *all* systems.
+ *
+ * An example would be:
+ *
+ * "game/itedata"
+ *
+ * In this example the code would first try to search for all directories matching
+ * "game" in the path "directory" first and search through all of the matches for
+ * "itedata". If "ingoreCase" is set to true, the code would do a case insensitive
+ * match, otherwise it is doing a case sensitive match.
+ *
+ * This method works of course also with tokens. For a list of available tokens
+ * see the documentation for Common::matchString.
+ *
+ * @see Common::matchString
+ */
+ void addSubDirectoriesMatching(const FSNode &directory, String pattern, bool ignoreCase, int priority = 0);
+
+ /**
* Remove an archive from the searchable set.
*/
void remove(const String& name);
diff --git a/common/file.cpp b/common/file.cpp
index dd4281bd03..6291aa8855 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -32,16 +32,6 @@
namespace Common {
-void File::addDefaultDirectory(const String &directory) {
- FSNode dir(directory);
- addDefaultDirectory(dir);
-}
-
-void File::addDefaultDirectory(const FSNode &dir) {
- if (dir.exists() && dir.isDirectory())
- SearchMan.addDirectory(dir.getPath(), dir);
-}
-
File::File()
: _handle(0) {
}
diff --git a/common/file.h b/common/file.h
index 6ac633c462..8eb03f1629 100644
--- a/common/file.h
+++ b/common/file.h
@@ -48,10 +48,6 @@ protected:
String _name;
public:
-
- static void addDefaultDirectory(const String &directory);
- static void addDefaultDirectory(const FSNode &directory);
-
File();
virtual ~File();
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index ee2ef98c42..b9de7b7a05 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -512,24 +512,18 @@ AGOSEngine::AGOSEngine(OSystem *syst)
// Add default file directories for Acorn version of
// Simon the Sorcerer 1
- File::addDefaultDirectory(_gameDataDir.getChild("execute"));
- File::addDefaultDirectory(_gameDataDir.getChild("EXECUTE"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "execute");
// Add default file directories for Amiga/Macintosh
// verisons of Simon the Sorcerer 2
- File::addDefaultDirectory(_gameDataDir.getChild("voices"));
- File::addDefaultDirectory(_gameDataDir.getChild("VOICES"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "voices");
// Add default file directories for Amiga & Macintosh
// versions of The Feeble Files
- File::addDefaultDirectory(_gameDataDir.getChild("gfx"));
- File::addDefaultDirectory(_gameDataDir.getChild("GFX"));
- File::addDefaultDirectory(_gameDataDir.getChild("movies"));
- File::addDefaultDirectory(_gameDataDir.getChild("MOVIES"));
- File::addDefaultDirectory(_gameDataDir.getChild("sfx"));
- File::addDefaultDirectory(_gameDataDir.getChild("SFX"));
- File::addDefaultDirectory(_gameDataDir.getChild("speech"));
- File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "gfx");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "movies");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "sfx");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "speech");
g_eventRec.registerRandomSource(_rnd, "agos");
}
diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp
index bb4e142196..24af155637 100644
--- a/engines/groovie/groovie.cpp
+++ b/engines/groovie/groovie.cpp
@@ -40,9 +40,9 @@ GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) :
_graphicsMan(NULL), _waitingForInput(false) {
// Adding the default directories
- Common::File::addDefaultDirectory(_gameDataDir.getChild("groovie"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("media"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("system"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "groovie");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "media");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "system");
// Initialize the custom debug levels
Common::addDebugChannel(kGroovieDebugAll, "All", "Debug everything");
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index b4973002a6..79ffd7bfd0 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -108,9 +108,8 @@ M4Engine::M4Engine(OSystem *syst, const M4GameDescription *gameDesc) :
// FIXME
_vm = this;
- Common::File::addDefaultDirectory(_gameDataDir);
- Common::File::addDefaultDirectory("goodstuf"); // FIXME: This is nonsense
- Common::File::addDefaultDirectory("resource"); // FIXME: This is nonsense
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "goodstuf");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "resource");
Common::addDebugChannel(kDebugScript, "script", "Script debug level");
Common::addDebugChannel(kDebugConversations, "conversations", "Conversations debugging");
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 2a2a4b993c..7386b6dd10 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -93,26 +93,26 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)
// The Linux version of Inherit the Earth puts all data files in an
// 'itedata' sub-directory, except for voices.rsc
- Common::File::addDefaultDirectory(_gameDataDir.getChild("itedata"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "itedata");
// The Windows version of Inherit the Earth puts various data files in
// other subdirectories.
- Common::File::addDefaultDirectory(_gameDataDir.getChild("graphics"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("music"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("sound"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "graphics");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "music");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "sound");
// The Multi-OS version puts the voices file in the root directory of
// the CD. The rest of the data files are in game/itedata
- Common::File::addDefaultDirectory(_gameDataDir.getChild("game").getChild("itedata"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "game/itedata");
// Mac CD Wyrmkeep
- Common::File::addDefaultDirectory(_gameDataDir.getChild("patch"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "patch");
// Dinotopia
- Common::File::addDefaultDirectory(_gameDataDir.getChild("smack"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "smack");
// FTA2
- Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "video");
_displayClip.left = _displayClip.top = 0;
g_eventRec.registerRandomSource(_rnd, "saga");
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 587e2a8abe..13a12c5480 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -934,15 +934,14 @@ Common::Error ScummEngine::init() {
// Add default file directories.
if (((_game.platform == Common::kPlatformAmiga) || (_game.platform == Common::kPlatformAtariST)) && (_game.version <= 4)) {
// This is for the Amiga version of Indy3/Loom/Maniac/Zak
- File::addDefaultDirectory(_gameDataDir.getChild("ROOMS"));
- File::addDefaultDirectory(_gameDataDir.getChild("rooms"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "rooms");
}
if ((_game.platform == Common::kPlatformMacintosh) && (_game.version == 3)) {
// This is for the Mac version of Indy3/Loom
- File::addDefaultDirectory(_gameDataDir.getChild("Rooms 1"));
- File::addDefaultDirectory(_gameDataDir.getChild("Rooms 2"));
- File::addDefaultDirectory(_gameDataDir.getChild("Rooms 3"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "rooms 1");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "rooms 2");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "rooms 3");
}
#ifdef ENABLE_SCUMM_7_8
@@ -955,25 +954,19 @@ Common::Error ScummEngine::init() {
//
// 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/");
+ SearchMan.addSubDirectoryMatching(Common::FSNode("/"), "Volumes/MONKEY3_1/RESOURCE");
+ SearchMan.addSubDirectoryMatching(Common::FSNode("/"), "Volumes/MONKEY3_2");
+ SearchMan.addSubDirectoryMatching(Common::FSNode("/"), "Volumes/MONKEY3_2/RESOURCE");
} else
#endif
- if (_game.version == 8) {
+ if (_game.version == 8)
// This is for COMI
- File::addDefaultDirectory(_gameDataDir.getChild("RESOURCE"));
- File::addDefaultDirectory(_gameDataDir.getChild("resource"));
- }
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "resource");
if (_game.version == 7) {
// This is for Full Throttle & The Dig
- File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
- File::addDefaultDirectory(_gameDataDir.getChild("video"));
- File::addDefaultDirectory(_gameDataDir.getChild("DATA"));
- File::addDefaultDirectory(_gameDataDir.getChild("data"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "video");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "data");
}
#endif
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 94216d8584..180537f4ec 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -56,19 +56,13 @@ SwordEngine::SwordEngine(OSystem *syst)
_features = 0;
// Add default file directories
- Common::File::addDefaultDirectory(_gameDataDir.getChild("CLUSTERS"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("MUSIC"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("SMACKSHI"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("ENGLISH"));//PSX Demo
- Common::File::addDefaultDirectory(_gameDataDir.getChild("ITALIAN"));//PSX Demo
- Common::File::addDefaultDirectory(_gameDataDir.getChild("clusters"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("music"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("speech"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("smackshi"));
-
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "clusters");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "music");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "speech");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "video");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "smackshi");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "english");//PSX Demo
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "italian");//PSX Demo
}
SwordEngine::~SwordEngine() {
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index e368f257a2..ec1bb4888c 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -257,14 +257,10 @@ namespace Sword2 {
Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst) {
// Add default file directories
- Common::File::addDefaultDirectory(_gameDataDir.getChild("CLUSTERS"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("SWORD2"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("SMACKS"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("clusters"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("sword2"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
- Common::File::addDefaultDirectory(_gameDataDir.getChild("smacks"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "clusters");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "sword2");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "video");
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "smacks");
if (!scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2demo") || !scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2psxdemo"))
_features = GF_DEMO;
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 7586c5e749..a375e48a2b 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -844,7 +844,7 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
// Add DW2 subfolder to search path in case user is running directly from the CDs
- Common::File::addDefaultDirectory(_gameDataDir.getChild("dw2"));
+ SearchMan.addSubDirectoryMatching(_gameDataDir, "dw2");
// Add subfolders needed for psx versions of Discworld 1
if (TinselV1PSX)
diff --git a/sound/softsynth/mt32.cpp b/sound/softsynth/mt32.cpp
index d662be989e..914b37b6eb 100644
--- a/sound/softsynth/mt32.cpp
+++ b/sound/softsynth/mt32.cpp
@@ -38,6 +38,7 @@
#include "common/file.h"
#include "common/system.h"
#include "common/util.h"
+#include "common/archive.h"
#include "graphics/fontman.h"
#include "graphics/surface.h"
@@ -514,7 +515,7 @@ Common::Error MT32EmuMusicPlugin::createInstance(Audio::Mixer *mixer, MidiDriver
MidiDriver *MidiDriver_MT32_create(Audio::Mixer *mixer) {
// HACK: It will stay here until engine plugin loader overhaul
if (ConfMan.hasKey("extrapath"))
- Common::File::addDefaultDirectory(ConfMan.get("extrapath"));
+ SearchMan.addDirectory("extrapath", ConfMan.get("extrapath"));
MidiDriver *mididriver;