From bfda12fa232b177d23a8d77c6b078924d2c90cbe Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 30 May 2016 22:31:02 -0700 Subject: [PATCH] Allow more options in texture [hashes] syntax. This allows you to ignore the address or address and clut hash. --- Core/TextureReplacer.cpp | 50 +++++++++++++++++++++++++++++----------- Core/TextureReplacer.h | 35 +++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 4da568218e..ec7e842110 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -99,8 +99,12 @@ bool TextureReplacer::LoadIni() { auto hashes = ini.GetOrCreateSection("hashes"); // Format: hashname = filename.png for (std::string hashName : hashNames) { - std::transform(hashName.begin(), hashName.end(), hashName.begin(), tolower); - hashes->Get(hashName.c_str(), &aliases_[hashName], ""); + ReplacementAliasKey key(0, 0, 0); + if (sscanf(hashName.c_str(), "%16llx%8x_%d", &key.cachekey, &key.hash, &key.level) >= 1) { + hashes->Get(hashName.c_str(), &aliases_[key], ""); + } else { + ERROR_LOG(G3D, "Unsupported syntax under [hashes]: %s", hashName.c_str()); + } } } @@ -385,22 +389,42 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl } std::string TextureReplacer::LookupHashFile(u64 cachekey, u32 hash, int level) { - const std::string hashname = HashName(cachekey, hash, level); - auto alias = aliases_.find(hashname); + ReplacementAliasKey key(cachekey, hash, level); + auto alias = aliases_.find(key); + if (alias == aliases_.end()) { + // Also check for a few more aliases with zeroed portions: + // No data hash. + key.hash = 0; + alias = aliases_.find(key); + + if (alias == aliases_.end()) { + // No address. + key.cachekey = cachekey & 0xFFFFFFFFULL; + key.hash = hash; + alias = aliases_.find(key); + } + + if (alias == aliases_.end()) { + // Address, but not clut hash (in case of garbage clut data.) + key.cachekey = cachekey & ~0xFFFFFFFFULL; + key.hash = hash; + alias = aliases_.find(key); + } + + if (alias == aliases_.end()) { + // Anything with this data hash (a little dangerous.) + key.cachekey = 0; + key.hash = hash; + alias = aliases_.find(key); + } + } + if (alias != aliases_.end()) { // Note: this will be blank if explicitly ignored. return alias->second; } - // Also check for a cachekey-only alias. This is mainly for ignoring videos. - const std::string keyonly = hashname.substr(0, 16); - auto keyonlyAlias = aliases_.find(keyonly); - if (keyonlyAlias != aliases_.end()) { - // Note: this will be blank if explicitly ignored. - return keyonlyAlias->second; - } - - return hashname + ".png"; + return HashName(cachekey, hash, level) + ".png"; } std::string TextureReplacer::HashName(u64 cachekey, u32 hash, int level) { diff --git a/Core/TextureReplacer.h b/Core/TextureReplacer.h index d90d484e28..c90b9efa0d 100644 --- a/Core/TextureReplacer.h +++ b/Core/TextureReplacer.h @@ -78,6 +78,31 @@ struct ReplacementCacheKey { } }; +struct ReplacementAliasKey { + u64 cachekey; + union { + u64 hashAndLevel; + struct { + u32 level; + u32 hash; + }; + }; + + ReplacementAliasKey(u64 c, u32 h, u32 l) : cachekey(c), hash(h), level(l) { + } + + bool operator ==(const ReplacementAliasKey &k) const { + return k.cachekey == cachekey && k.hashAndLevel == hashAndLevel; + } + + bool operator <(const ReplacementAliasKey &k) const { + if (k.cachekey == cachekey) { + return k.hashAndLevel < hashAndLevel; + } + return k.cachekey < cachekey; + } +}; + #ifndef __SYMBIAN32__ namespace std { template <> @@ -86,6 +111,13 @@ namespace std { return std::hash()(k.cachekey ^ ((u64)k.hash << 32)); } }; + + template <> + struct hash { + size_t operator()(const ReplacementAliasKey &k) const { + return std::hash()(k.cachekey ^ k.hashAndLevel); + } + }; } #endif @@ -169,12 +201,13 @@ protected: std::string gameID_; std::string basePath_; ReplacedTextureHash hash_; - std::unordered_map aliases_; typedef std::pair WidthHeightPair; #ifdef __SYMBIAN32__ std::map hashranges_; + std::map aliases_; #else std::unordered_map hashranges_; + std::unordered_map aliases_; #endif ReplacedTexture none_;