aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/advancedDetector.cpp93
-rw-r--r--common/advancedDetector.h15
-rw-r--r--engines/kyra/plugin.cpp3
3 files changed, 40 insertions, 71 deletions
diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp
index d385bbdaef..7d6fd630ff 100644
--- a/common/advancedDetector.cpp
+++ b/common/advancedDetector.cpp
@@ -131,11 +131,10 @@ DetectedGameList real_ADVANCED_DETECTOR_DETECT_GAMES_FUNCTION(
descList.push_back((const ADGameDescription *)descPtr);
ad.registerGameDescriptions(descList);
- ad.setFileMD5Bytes(md5Bytes);
debug(3, "%s: cnt: %d", ((const ADGameDescription *)descs)->name, descList.size());
- matches = ad.detectGame(&fslist, Common::UNK_LANG, Common::kPlatformUnknown);
+ matches = ad.detectGame(&fslist, md5Bytes, Common::UNK_LANG, Common::kPlatformUnknown);
for (uint i = 0; i < matches.size(); i++)
detectedGames.push_back(toDetectedGame(*(const ADGameDescription *)(descs + matches[i] * descItemSize), list));
@@ -171,9 +170,8 @@ int real_ADVANCED_DETECTOR_DETECT_INIT_GAME(
descList.push_back((const ADGameDescription *)descPtr);
ad.registerGameDescriptions(descList);
- ad.setFileMD5Bytes(md5Bytes);
- matches = ad.detectGame(0, language, platform);
+ matches = ad.detectGame(0, md5Bytes, language, platform);
for (uint i = 0; i < matches.size(); i++) {
if (toDetectedGame(*(const ADGameDescription *)(descs + matches[i] * descItemSize), list).gameid == gameid) {
@@ -192,10 +190,6 @@ int real_ADVANCED_DETECTOR_DETECT_INIT_GAME(
}
-AdvancedDetector::AdvancedDetector() {
- _fileMD5Bytes = 0;
-}
-
String AdvancedDetector::getDescription(int num) const {
char tmp[256];
const ADGameDescription *g = _gameDescriptions[num];
@@ -206,7 +200,7 @@ String AdvancedDetector::getDescription(int num) const {
return String(tmp);
}
-ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Platform platform) {
+ADList AdvancedDetector::detectGame(const FSList *fslist, int md5Bytes, Language language, Platform platform) {
typedef HashMap<String, bool, CaseSensitiveString_Hash, CaseSensitiveString_EqualTo> StringSet;
StringSet filesList;
@@ -219,16 +213,12 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
int j;
char md5str[32+1];
uint8 md5sum[16];
- int *matched;
- uint matchedCount = 0;
bool fileMissing;
const ADGameFileDescription *fileDesc;
assert(_gameDescriptions.size());
- matched = new int[_gameDescriptions.size()];
-
// First we compose list of files which we need MD5s for
for (i = 0; i < _gameDescriptions.size(); i++) {
for (j = 0; _gameDescriptions[i]->filesDescriptions[j].fileName; j++) {
@@ -249,7 +239,7 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
if (!filesList.contains(tstr) && !filesList.contains(tstr2)) continue;
- if (!md5_file(*file, md5sum, _fileMD5Bytes)) continue;
+ if (!md5_file(*file, md5sum, md5Bytes)) continue;
for (j = 0; j < 16; j++) {
sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
}
@@ -268,7 +258,7 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
if (testFile.open(file->_key)) {
testFile.close();
- if (md5_file(file->_key.c_str(), md5sum, _fileMD5Bytes)) {
+ if (md5_file(file->_key.c_str(), md5sum, md5Bytes)) {
for (j = 0; j < 16; j++) {
sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
}
@@ -280,9 +270,19 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
}
}
+ ADList matched;
+ int maxFilesMatched = 0;
+
for (i = 0; i < _gameDescriptions.size(); i++) {
fileMissing = false;
+ // Do not even bother to look at entries which do not have matching
+ // language and platform (if specified).
+ if ((_gameDescriptions[i]->language != language && language != UNK_LANG) ||
+ (_gameDescriptions[i]->platform != platform && platform != kPlatformUnknown)) {
+ continue;
+ }
+
// Try to open all files for this game
for (j = 0; _gameDescriptions[i]->filesDescriptions[j].fileName; j++) {
fileDesc = &_gameDescriptions[i]->filesDescriptions[j];
@@ -302,13 +302,30 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
}
if (!fileMissing) {
debug(2, "Found game: %s (%d)", getDescription(i).c_str(), i);
- matched[matchedCount++] = i;
+
+ // Count the number of matching files. Then, only keep those
+ // entries which match a maximal amount of files.
+ int curFilesMatched = 0;
+ for (j = 0; _gameDescriptions[i]->filesDescriptions[j].fileName; j++)
+ curFilesMatched++;
+
+ if (curFilesMatched > maxFilesMatched) {
+ debug(2, " ... new best match, removing all previous candidates");
+ maxFilesMatched = curFilesMatched;
+ matched.clear();
+ matched.push_back(i);
+ } else if (curFilesMatched == maxFilesMatched) {
+ matched.push_back(i);
+ } else {
+ debug(2, " ... skipped");
+ }
+
} else {
debug(5, "Skipping game: %s (%d)", getDescription(i).c_str(), i);
}
}
- if (!filesMD5.empty() && (matchedCount == 0)) {
+ if (!filesMD5.empty() && matched.empty()) {
printf("MD5s of your game version are unknown. Please, report following data to\n");
printf("ScummVM team along with your game name and version:\n");
@@ -316,47 +333,7 @@ ADList AdvancedDetector::detectGame(const FSList *fslist, Language language, Pla
printf("%s: %s\n", file->_key.c_str(), file->_value.c_str());
}
- // We have some resource sets which are superpositions of other
- // Now remove lesser set if bigger matches too
-
- if (matchedCount > 1) {
- // Search max number
- int maxcount = 0;
- for (i = 0; i < matchedCount; i++) {
- int fCount = 0;
- for (j = 0; _gameDescriptions[i]->filesDescriptions[j].fileName; j++)
- fCount++;
- maxcount = MAX(fCount, maxcount);
- }
-
- // Now purge targets with number of files lesser than max
- for (i = 0; i < matchedCount; i++) {
- if ((_gameDescriptions[matched[i]]->language != language && language != UNK_LANG) ||
- (_gameDescriptions[matched[i]]->platform != platform && platform != kPlatformUnknown)) {
- debug(2, "Purged %s", getDescription(matched[i]).c_str());
- matched[i] = -1;
- continue;
- }
-
- int fCount = 0;
- for (j = 0; _gameDescriptions[matched[i]]->filesDescriptions[j].fileName; j++)
- fCount++;
-
- if (fCount < maxcount) {
- debug(2, "Purged: %s", getDescription(matched[i]).c_str());
- matched[i] = -1;
- }
- }
- }
-
-
- ADList returnMatches;
- for (i = 0; i < matchedCount; i++)
- if (matched[i] != -1)
- returnMatches.push_back(matched[i]);
-
- delete[] matched;
- return returnMatches;
+ return matched;
}
} // End of namespace Common
diff --git a/common/advancedDetector.h b/common/advancedDetector.h
index 437f17d8f9..00f223cf3f 100644
--- a/common/advancedDetector.h
+++ b/common/advancedDetector.h
@@ -67,8 +67,8 @@ typedef Array<const ADGameDescription*> ADGameDescList;
class AdvancedDetector {
public:
- AdvancedDetector();
- ~AdvancedDetector() {};
+ AdvancedDetector() {}
+ ~AdvancedDetector() {}
void registerGameDescriptions(ADGameDescList gameDescriptions) {
@@ -76,29 +76,22 @@ public:
}
/**
- * Specify number of bytes which are used to calculate MD5.
- * Default value is 0 which means whole file.
- */
- void setFileMD5Bytes(int bytes) { _fileMD5Bytes = bytes; }
-
- /**
* Detect games in specified directory.
* Parameters language and platform are used to pass on values
* specified by the user. I.e. this is used to restrict search scope.
*
* @param fslist FSList to scan or NULL for scanning all specified
* default directories.
+ * @param md5Bytes number of bytes which are used to calculate MD5
* @param language restrict results to specified language only
* @param platform restrict results to specified platform only
* @return list of indexes to GameDescriptions of matched games
*/
- ADList detectGame(const FSList *fslist, Language language, Platform platform);
+ ADList detectGame(const FSList *fslist, int md5Bytes, Language language, Platform platform);
private:
ADGameDescList _gameDescriptions;
- int _fileMD5Bytes;
-
String getDescription(int num) const;
};
diff --git a/engines/kyra/plugin.cpp b/engines/kyra/plugin.cpp
index cb98666805..a479f5b793 100644
--- a/engines/kyra/plugin.cpp
+++ b/engines/kyra/plugin.cpp
@@ -161,9 +161,8 @@ static ADList detectKyraGames(const FSList &fslist) {
}
ad.registerGameDescriptions(descList);
- ad.setFileMD5Bytes(kMD5FileSizeLimit);
- matches = ad.detectGame(&fslist, Common::UNK_LANG, Common::kPlatformUnknown);
+ matches = ad.detectGame(&fslist, kMD5FileSizeLimit, Common::UNK_LANG, Common::kPlatformUnknown);
return matches;
}