-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable the FakeMipmapChange flag for US/EU Tactics Ogre, fixing replacement problem. #18001
Changes from all commits
5c42aa0
412c454
0cdfaff
de679e2
af1a1c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -226,31 +226,50 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri | |
ERROR_LOG(G3D, "Unsupported texture replacement version %d, trying anyway", version); | ||
} | ||
|
||
bool filenameWarning = false; | ||
int badFileNameCount = 0; | ||
|
||
std::map<ReplacementCacheKey, std::map<int, std::string>> filenameMap; | ||
std::string badFilenames; | ||
|
||
if (ini.HasSection("hashes")) { | ||
auto hashes = ini.GetOrCreateSection("hashes")->ToMap(); | ||
auto hashes = ini.GetOrCreateSection("hashes")->ToVec(); | ||
// Format: hashname = filename.png | ||
bool checkFilenames = g_Config.bSaveNewTextures && !g_Config.bIgnoreTextureFilenames && !vfsIsZip_; | ||
|
||
for (const auto &item : hashes) { | ||
ReplacementCacheKey key(0, 0); | ||
int level = 0; // sscanf might fail to pluck the level, but that's ok, we default to 0. sscanf doesn't write to non-matched outputs. | ||
// sscanf might fail to pluck the level if omitted from the line, but that's ok, we default level to 0. | ||
// sscanf doesn't write to non-matched outputs. | ||
int level = 0; | ||
if (sscanf(item.first.c_str(), "%16llx%8x_%d", &key.cachekey, &key.hash, &level) >= 1) { | ||
if (item.second.empty()) { | ||
WARN_LOG(G3D, "Texture replacement: Ignoring hash mapping to empty filename: '%s ='", item.first.c_str()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't really an error, at least it used to be documented as an intentional way to disable saving a texture which you've decided it's not useful to upscale (example: solid color texture.) Seems annoying to logspam it. -[Unknown] |
||
continue; | ||
} | ||
filenameMap[key][level] = item.second; | ||
if (checkFilenames) { | ||
// TODO: We should check for the union of these on all platforms, really. | ||
#if PPSSPP_PLATFORM(WINDOWS) | ||
bool bad = item.second.find_first_of("\\ABCDEFGHIJKLMNOPQRSTUVWXYZ:<>|?*") != std::string::npos; | ||
// Uppercase probably means the filenames don't match. | ||
// Avoiding an actual check of the filenames to avoid performance impact. | ||
filenameWarning = filenameWarning || item.second.find_first_of("\\ABCDEFGHIJKLMNOPQRSTUVWXYZ:<>|?*") != std::string::npos; | ||
#else | ||
filenameWarning = filenameWarning || item.second.find_first_of("\\:<>|?*") != std::string::npos; | ||
bool bad = item.second.find_first_of("\\:<>|?*") != std::string::npos; | ||
#endif | ||
if (bad) { | ||
badFileNameCount++; | ||
if (badFileNameCount == 10) { | ||
badFilenames.append("..."); | ||
} else if (badFileNameCount < 10) { | ||
badFilenames.append(item.second); | ||
badFilenames.push_back('\n'); | ||
} | ||
} | ||
} | ||
} else if (item.first.empty()) { | ||
INFO_LOG(G3D, "Ignoring [hashes] line with empty key: '= %s'", item.second.c_str()); | ||
} else { | ||
ERROR_LOG(G3D, "Unsupported syntax under [hashes]: %s", item.first.c_str()); | ||
ERROR_LOG(G3D, "Unsupported syntax under [hashes], ignoring: %s = ", item.first.c_str()); | ||
} | ||
} | ||
} | ||
|
@@ -308,9 +327,10 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri | |
aliases_[pair.first] = alias; | ||
} | ||
|
||
if (filenameWarning) { | ||
if (badFileNameCount > 0) { | ||
auto err = GetI18NCategory(I18NCat::ERRORS); | ||
g_OSD.Show(OSDType::MESSAGE_ERROR, err->T("textures.ini filenames may not be cross-platform (banned characters)"), 6.0f); | ||
g_OSD.Show(OSDType::MESSAGE_WARNING, err->T("textures.ini filenames may not be cross - platform(banned characters)"), badFilenames, 6.0f); | ||
WARN_LOG(G3D, "Potentially bad filenames: %s", badFilenames.c_str()); | ||
} | ||
|
||
if (ini.HasSection("hashranges")) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -265,11 +265,16 @@ ULJM06365 = true | |
# This hacks separates each mipmap to independent textures to display wrong-size mipmaps. | ||
# For example this requires games like Tactics Ogre(Japanese) to display multi bytes fonts stored in mipmaps. | ||
# See issue #5350. | ||
# Tactics Ogre(Japanese) | ||
# Tactics Ogre (Japanese) | ||
ULJM05753 = true | ||
NPJH50348 = true | ||
ULJM06009 = true | ||
|
||
# Tactics Ogre (US, EU). See #17491 / #17980 | ||
# Required for texture replacement to work correctly, though unlike JP, only one layer is actually used (two duplicates, really) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Obviously just seems like a flaw in the texture replacement engine now. But I'm sure you're going to find all the games that use cube mipmaps and add this flag to each one. Good luck. -[Unknown] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's not ideal. I will try to rectify this flaw, but I'm trying to get a release ready and the change I'm planning is a bit too big. Though in reality we've only seen this in three or four games. |
||
ULUS10565 = true | ||
ULES01500 = true | ||
|
||
[RequireBufferedRendering] | ||
# Warn the user that the game will not work and have issue, if buffered rendering is not enabled. | ||
# Midnight Club: LA Remix | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When will it make sense to map the same hash to two different filenames? The level is still part of the key, so this would just overwrite those duplicates silently anyway?
Not sure I understand what the intent would be for:
1234567890abcdef_0 = image1.png
1234567890abcdef_0 = image2.png
1234567890abcdef_0 = image3.png
-[Unknown]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The map was deduplicating the empty keys which were confusing my logging, which I added because of a theory that turned out to be wrong.