diff options
| -rw-r--r-- | gui/launcher.cpp | 18 | ||||
| -rw-r--r-- | gui/massadd.cpp | 57 | ||||
| -rw-r--r-- | gui/massadd.h | 10 | 
3 files changed, 73 insertions, 12 deletions
diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 92867562ad..2c1212b84a 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -572,8 +572,16 @@ void LauncherDialog::updateListing() {  	// Retrieve a list of all games defined in the config file  	_domains.clear();  	const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); -	ConfigManager::DomainMap::const_iterator iter = domains.begin(); +	ConfigManager::DomainMap::const_iterator iter;  	for (iter = domains.begin(); iter != domains.end(); ++iter) { +#ifdef __DS__ +		// DS port uses an extra section called 'ds'.  This prevents the section from being +		// detected as a game. +		if (iter->_key == "ds") { +			continue; +		} +#endif +  		String gameid(iter->_value.get("gameid"));  		String description(iter->_value.get("description")); @@ -585,14 +593,6 @@ void LauncherDialog::updateListing() {  				description = g.description();  		} -#ifdef __DS__ -		// DS port uses an extra section called 'ds'.  This prevents the section from being -		// detected as a game. -		if (gameid == "ds") { -			continue; -		} -#endif -  		if (description.empty())  			description = "Unknown (target " + iter->_key + ", gameid " + gameid + ")"; diff --git a/gui/massadd.cpp b/gui/massadd.cpp index b39b51f1fb..687d367516 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -24,6 +24,7 @@  #include "engines/metaengine.h"  #include "common/events.h" +#include "common/config-manager.h"  #include "gui/launcher.h"	// For addGameToConf()  #include "gui/massadd.h" @@ -87,6 +88,29 @@ MassAddDialog::MassAddDialog(const FilesystemNode &startDir)  	new ButtonWidget(this, "massadddialog_cancel", "Cancel", kCancelCmd, Common::ASCII_ESCAPE); +	// Build a map from all configured game paths to the targets using them +	const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); +	Common::ConfigManager::DomainMap::const_iterator iter; +	for (iter = domains.begin(); iter != domains.end(); ++iter) { + +#ifdef __DS__ +		// DS port uses an extra section called 'ds'.  This prevents the section from being +		// detected as a game. +		if (iter->_key == "ds") { +			continue; +		} +#endif + +		Common::String path(iter->_value.get("path")); +		// Remove trailing slash, so that "/foo" and "/foo/" match. +		// This works around a bug in the POSIX FS code (and others?) +		// where paths are not normalized (so FSNodes refering to identical +		// FS objects may return different values in path()). +		while (path != "/" && path.lastChar() == '/') +			path.deleteLastChar(); +		if (!path.empty()) +			_pathToTargets[path].push_back(iter->_key); +	}  } @@ -136,9 +160,36 @@ void MassAddDialog::handleTickle() {  		// that either means the directory contains multiple games, or the detector  		// could not fully determine which game variant it was seeing. In either  		// case, let the user choose which entries he wants to keep. +		// +		// However, we only add games which are not already in the config file.  		for (GameList::const_iterator cand = candidates.begin(); cand != candidates.end(); ++cand) {  			GameDescriptor result = *cand; -			result["path"] = dir.getPath(); +			Common::String path = dir.getPath(); + +			// Remove trailing slashes +			while (path != "/" && path.lastChar() == '/') +				path.deleteLastChar(); + +			// Check for existing config entries for this path/gameid/lang/platform combination +			if (_pathToTargets.contains(path)) { +				bool duplicate = false; +				const Common::StringList &targets = _pathToTargets[path]; +				for (Common::StringList::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) { +					// If the gameid, platform and language match -> skip it +					Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter); +					assert(dom); + +					if ((*dom)["gameid"] == result["gameid"] && +					    (*dom)["platform"] == result["platform"] &&  +					    (*dom)["language"] == result["language"]) { +						duplicate = true; +						break; +					} +				} +				if (duplicate) +					break;	// Skip duplicates +			} +			result["path"] = path;  			_games.push_back(result);  		} @@ -164,14 +215,14 @@ void MassAddDialog::handleTickle() {  		snprintf(buf, sizeof(buf), "Scan complete!");  		_dirProgressText->setLabel(buf); -		snprintf(buf, sizeof(buf), "Discovered %d games.", _games.size()); +		snprintf(buf, sizeof(buf), "Discovered %d new games.", _games.size());  		_gameProgressText->setLabel(buf);  	} else {  		snprintf(buf, sizeof(buf), "Scanned %d directories ...", _dirsScanned);  		_dirProgressText->setLabel(buf); -		snprintf(buf, sizeof(buf), "Discovered %d games ...", _games.size()); +		snprintf(buf, sizeof(buf), "Discovered %d new games ...", _games.size());  		_gameProgressText->setLabel(buf);  	} diff --git a/gui/massadd.h b/gui/massadd.h index 29d24ca9a5..e0eff75c64 100644 --- a/gui/massadd.h +++ b/gui/massadd.h @@ -27,7 +27,10 @@  #include "gui/dialog.h"  #include "common/fs.h" +#include "common/hashmap.h"  #include "common/stack.h" +#include "common/str.h" +#include "common/hash-str.h"  namespace GUI { @@ -45,6 +48,13 @@ private:  	Common::Stack<FilesystemNode>  _scanStack;  	GameList _games; +	/** +	 * Map each path occuring in the config file to the target(s) using that path. +	 * Used to detect whether a potential new target is already present in the +	 * config manager. +	 */ +	Common::HashMap<Common::String, Common::StringList>	_pathToTargets; +  	int _dirsScanned;  	Widget *_okButton;  | 
