From 0cdfaffb4898e645a70512ce0cf551660d3d80e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 28 Aug 2023 20:58:57 +0200 Subject: [PATCH] Enable the FakeMipmapChange flag for US/EU Tactics Ogre, fixing replacement problem. For correct lookups, without our texture replacement actually supporting volume textures, we need to use this mechanism here too. The game actually uses two mipmaps, but they're identical and point to the same memory, so we treat them as a regular 2D texture instead for purposes of both texturing and replacement. This is presumably legacy from the initial Japanese version that needs to use multiple texture layers. Similarly it does in in pairs. This does actually not fully fix texture replacement for the Japanese version, unfortunately. For that we need more proper support for these weird textures in the texture replacement code - when I refactored it before for more natural handling of regular mipmapping, this kinda got lost. --- GPU/Common/TextureCacheCommon.cpp | 13 +++++++++++-- assets/compat.ini | 7 ++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index f7d51f354d..246a973262 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -2769,9 +2769,10 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt plan.scaleFactor = plan.scaleFactor > 4 ? 4 : (plan.scaleFactor > 2 ? 2 : 1); } - bool isFakeMipmapChange = IsFakeMipmapChange(); - + bool isFakeMipmapChange = false; if (plan.badMipSizes) { + isFakeMipmapChange = IsFakeMipmapChange(); + // Check for pure 3D texture. int tw = gstate.getTextureWidth(0); int th = gstate.getTextureHeight(0); @@ -2784,6 +2785,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt } } } else { + // We don't want to create a volume texture, if this is a "fake mipmap change". pure3D = false; } @@ -2911,6 +2913,13 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt if (isFakeMipmapChange) { // NOTE: Since the level is not part of the cache key, we assume it never changes. plan.baseLevelSrc = std::max(0, gstate.getTexLevelOffset16() / 16); + // If this is level 1 and it has the same texture address as level 0, let's just say it's + // level 0 for the purposes of replacement. Seen in Tactics Ogre. + // I assume this is done to avoid blending between levels accidentally? + // The Japanese version uses more levels, but similarly in pairs. + if (plan.baseLevelSrc == 1 && gstate.getTextureAddress(1) == gstate.getTextureAddress(0)) { + plan.baseLevelSrc = 0; + } plan.levelsToCreate = 1; plan.levelsToLoad = 1; // Make sure we already decided not to do a 3D texture above. diff --git a/assets/compat.ini b/assets/compat.ini index d5ac571422..03db9859d0 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -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) +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