diff options
| -rw-r--r-- | common/archive.cpp | 46 | ||||
| -rw-r--r-- | common/archive.h | 46 | ||||
| -rw-r--r-- | common/file.cpp | 10 | ||||
| -rw-r--r-- | common/file.h | 4 | ||||
| -rw-r--r-- | engines/agos/agos.cpp | 18 | ||||
| -rw-r--r-- | engines/groovie/groovie.cpp | 6 | ||||
| -rw-r--r-- | engines/m4/m4.cpp | 5 | ||||
| -rw-r--r-- | engines/saga/saga.cpp | 16 | ||||
| -rw-r--r-- | engines/scumm/scumm.cpp | 29 | ||||
| -rw-r--r-- | engines/sword1/sword1.cpp | 20 | ||||
| -rw-r--r-- | engines/sword2/sword2.cpp | 12 | ||||
| -rw-r--r-- | engines/tinsel/tinsel.cpp | 2 | ||||
| -rw-r--r-- | sound/softsynth/mt32.cpp | 3 | 
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; | 
