mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-24 14:00:03 +00:00
Merge pull request #8792 from unknownbrackets/tex-replace
Allow more options in texture [hashes] syntax
This commit is contained in:
commit
a690492836
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,6 +319,19 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
size_t slash = hashfile.find_last_of("/\\");
|
||||
#else
|
||||
size_t slash = hashfile.find_last_of("/");
|
||||
#endif
|
||||
if (slash != hashfile.npos) {
|
||||
// Create any directory structure as needed.
|
||||
const std::string saveDirectory = basePath_ + NEW_TEXTURE_DIR + hashfile.substr(0, slash);
|
||||
if (!File::Exists(saveDirectory)) {
|
||||
File::CreateFullPath(saveDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
// Only save the hashed portion of the PNG.
|
||||
int lookupW = w / replacedInfo.scaleFactor;
|
||||
int lookupH = h / replacedInfo.scaleFactor;
|
||||
@ -385,22 +402,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) {
|
||||
|
@ -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<u64>()(k.cachekey ^ ((u64)k.hash << 32));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<ReplacementAliasKey> {
|
||||
size_t operator()(const ReplacementAliasKey &k) const {
|
||||
return std::hash<u64>()(k.cachekey ^ k.hashAndLevel);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -169,12 +201,13 @@ protected:
|
||||
std::string gameID_;
|
||||
std::string basePath_;
|
||||
ReplacedTextureHash hash_;
|
||||
std::unordered_map<std::string, std::string> aliases_;
|
||||
typedef std::pair<int, int> WidthHeightPair;
|
||||
#ifdef __SYMBIAN32__
|
||||
std::map<u64, WidthHeightPair> hashranges_;
|
||||
std::map<ReplacementAliasKey, std::string> aliases_;
|
||||
#else
|
||||
std::unordered_map<u64, WidthHeightPair> hashranges_;
|
||||
std::unordered_map<ReplacementAliasKey, std::string> aliases_;
|
||||
#endif
|
||||
|
||||
ReplacedTexture none_;
|
||||
|
Loading…
Reference in New Issue
Block a user