ENGINES: Add res-only and data-only MD5 computational methods
The current way of ADGF_MACRESFORK is an amalgam of bugs and history. Those are clean ways for direct specification. It's not accessible yet
This commit is contained in:
parent
1ebbc4071c
commit
a2233a2166
3 changed files with 58 additions and 35 deletions
|
@ -190,16 +190,6 @@ DetectedGame AdvancedMetaEngineDetection::toDetectedGame(const ADDetectedGame &a
|
||||||
game.hasUnknownFiles = adGame.hasUnknownFiles;
|
game.hasUnknownFiles = adGame.hasUnknownFiles;
|
||||||
game.matchedFiles = adGame.matchedFiles;
|
game.matchedFiles = adGame.matchedFiles;
|
||||||
|
|
||||||
// Now specify the computation method for each file entry.
|
|
||||||
// TODO: This could be potentially overridden by use of upper part of adGame.fileType
|
|
||||||
// so, individual files could have their own computation method
|
|
||||||
for (FilePropertiesMap::iterator file = game.matchedFiles.begin(); file != game.matchedFiles.end(); ++file) {
|
|
||||||
if (desc->flags & ADGF_MACRESFORK)
|
|
||||||
file->_value.md5prop = (MD5Properties)(file->_value.md5prop | kMD5MacResFork);
|
|
||||||
if (desc->flags & ADGF_TAILMD5)
|
|
||||||
file->_value.md5prop = (MD5Properties)(file->_value.md5prop | kMD5Tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extraInfo && !extraInfo->targetID.empty()) {
|
if (extraInfo && !extraInfo->targetID.empty()) {
|
||||||
game.preferredTarget = generatePreferredTarget(desc, _maxAutogenLength, extraInfo->targetID);
|
game.preferredTarget = generatePreferredTarget(desc, _maxAutogenLength, extraInfo->targetID);
|
||||||
} else {
|
} else {
|
||||||
|
@ -518,7 +508,7 @@ static MD5Properties gameFlagsToDefaultMD5Props(uint32 flags) {
|
||||||
MD5Properties ret = kMD5Head;
|
MD5Properties ret = kMD5Head;
|
||||||
|
|
||||||
if (flags & ADGF_MACRESFORK) {
|
if (flags & ADGF_MACRESFORK) {
|
||||||
ret = (MD5Properties) (ret | kMD5MacResFork);
|
ret = (MD5Properties) (ret | kMD5MacResOrDataFork);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & ADGF_TAILMD5) {
|
if (flags & ADGF_TAILMD5) {
|
||||||
|
@ -556,28 +546,40 @@ bool AdvancedMetaEngine::getFilePropertiesExtern(uint md5Bytes, const FileMap &a
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getFilePropertiesIntern(uint md5Bytes, const AdvancedMetaEngine::FileMap &allFiles, MD5Properties md5prop, const Common::String &fname, FileProperties &fileProps) {
|
static bool getFilePropertiesIntern(uint md5Bytes, const AdvancedMetaEngine::FileMap &allFiles, MD5Properties md5prop, const Common::String &fname, FileProperties &fileProps) {
|
||||||
if (md5prop & kMD5MacResFork) {
|
if (md5prop & (kMD5MacResFork | kMD5MacDataFork)) {
|
||||||
FileMapArchive fileMapArchive(allFiles);
|
FileMapArchive fileMapArchive(allFiles);
|
||||||
|
bool is_legacy = ((md5prop & kMD5MacMask) == kMD5MacResOrDataFork);
|
||||||
|
if (md5prop & kMD5MacResFork) {
|
||||||
|
Common::MacResManager macResMan;
|
||||||
|
|
||||||
Common::MacResManager macResMan;
|
if (!macResMan.open(fname, fileMapArchive))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!macResMan.open(fname, fileMapArchive))
|
fileProps.md5 = macResMan.computeResForkMD5AsString(md5Bytes, ((md5prop & kMD5Tail) != 0));
|
||||||
return false;
|
fileProps.size = macResMan.getResForkDataSize();
|
||||||
|
|
||||||
fileProps.md5 = macResMan.computeResForkMD5AsString(md5Bytes, ((md5prop & kMD5Tail) != 0));
|
if (fileProps.size != 0) {
|
||||||
fileProps.size = macResMan.getResForkDataSize();
|
fileProps.md5prop = (MD5Properties)((md5prop & kMD5Tail) | kMD5MacResFork);
|
||||||
|
return true;
|
||||||
if (fileProps.size != 0)
|
}
|
||||||
return true;
|
|
||||||
|
|
||||||
Common::SeekableReadStream *dataFork = Common::MacResManager::openFileOrDataFork(fname, fileMapArchive);
|
|
||||||
if (dataFork && dataFork->size()) {
|
|
||||||
fileProps.size = dataFork->size();
|
|
||||||
fileProps.md5 = Common::computeStreamMD5AsString(*dataFork, md5Bytes);
|
|
||||||
delete dataFork;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
delete dataFork;
|
|
||||||
|
if (md5prop & kMD5MacDataFork) {
|
||||||
|
Common::SeekableReadStream *dataFork = Common::MacResManager::openFileOrDataFork(fname, fileMapArchive);
|
||||||
|
// Logically 0-sized data fork is valid but legacy code continues fallback
|
||||||
|
if (dataFork && (dataFork->size() || !is_legacy)) {
|
||||||
|
fileProps.size = dataFork->size();
|
||||||
|
fileProps.md5 = Common::computeStreamMD5AsString(*dataFork, md5Bytes);
|
||||||
|
fileProps.md5prop = (MD5Properties)((md5prop & kMD5Tail) | kMD5MacDataFork);
|
||||||
|
delete dataFork;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
delete dataFork;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In modern case stop here
|
||||||
|
if (!is_legacy)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allFiles.contains(fname))
|
if (!allFiles.contains(fname))
|
||||||
|
@ -595,6 +597,7 @@ static bool getFilePropertiesIntern(uint md5Bytes, const AdvancedMetaEngine::Fil
|
||||||
|
|
||||||
fileProps.size = testFile.size();
|
fileProps.size = testFile.size();
|
||||||
fileProps.md5 = Common::computeStreamMD5AsString(testFile, md5Bytes);
|
fileProps.md5 = Common::computeStreamMD5AsString(testFile, md5Bytes);
|
||||||
|
fileProps.md5prop = (MD5Properties) (md5prop & kMD5Tail);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,15 +166,32 @@ Common::U32String DetectionResults::generateUnknownGameReport(bool translate, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
char md5PropToCacheChar(MD5Properties flags) {
|
char md5PropToCacheChar(MD5Properties flags) {
|
||||||
if (flags & kMD5MacResFork) {
|
switch (flags & kMD5MacMask) {
|
||||||
|
case kMD5MacDataFork: {
|
||||||
|
if (flags & kMD5Tail)
|
||||||
|
return 'd';
|
||||||
|
return 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
case kMD5MacResOrDataFork: {
|
||||||
if (flags & kMD5Tail)
|
if (flags & kMD5Tail)
|
||||||
return 'e';
|
return 'e';
|
||||||
return 'm';
|
return 'm';
|
||||||
}
|
}
|
||||||
if (flags & kMD5Tail)
|
|
||||||
return 't';
|
|
||||||
|
|
||||||
return 'f';
|
case kMD5MacResFork: {
|
||||||
|
if (flags & kMD5Tail)
|
||||||
|
return 'x';
|
||||||
|
return 'r';
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (flags & kMD5Tail)
|
||||||
|
return 't';
|
||||||
|
|
||||||
|
return 'f';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::U32String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt) {
|
Common::U32String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt) {
|
||||||
|
|
|
@ -103,9 +103,12 @@ enum GameSupportLevel {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum MD5Properties {
|
enum MD5Properties {
|
||||||
kMD5Head = 0 << 1, // the MD5 is calculated from the head, default
|
kMD5Head = 0 << 1, // the MD5 is calculated from the head, default
|
||||||
kMD5Tail = 1 << 1, // the MD5 is calculated from the tail
|
kMD5Tail = 1 << 1, // the MD5 is calculated from the tail
|
||||||
kMD5MacResFork = 1 << 2 // the MD5 is calculated from the Mac Resource fork (head or tail)
|
kMD5MacResFork = 1 << 2, // the MD5 is calculated from the Mac Resource fork (no fall back) (head or tail)
|
||||||
|
kMD5MacDataFork = 1 << 3, // the MD5 is calculated from the Mac Data fork (head or tail)
|
||||||
|
kMD5MacResOrDataFork = kMD5MacResFork | kMD5MacDataFork, // the MD5 is calculated from the Mac Resource fork falling back to data fork (head or tail). Deprecated.
|
||||||
|
kMD5MacMask = kMD5MacResFork | kMD5MacDataFork, // Mask for mac type
|
||||||
};
|
};
|
||||||
|
|
||||||
char md5PropToCacheChar(MD5Properties val);
|
char md5PropToCacheChar(MD5Properties val);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue