diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 95f4aa16fd46..3c3f1f092675 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -482,73 +482,6 @@ void SoftwareTransform::Transform(int prim, u32 vertType, const DecVtxFormat &de } } -// Also, this assumes SetTexture() has already figured out the actual texture height. -void SoftwareTransform::DetectOffsetTexture(int maxIndex) { - TransformedVertex *transformed = params_.transformed; - - const int w = gstate.getTextureWidth(0); - const int h = gstate.getTextureHeight(0); - float widthFactor = (float)w / (float)gstate_c.curTextureWidth; - float heightFactor = (float)h / (float)gstate_c.curTextureHeight; - - // Breath of Fire 3 does some interesting rendering here, probably from being a port. - // It draws at 384x240 to two buffers in VRAM, one right after the other. - // We end up creating separate framebuffers, and rendering to each. - // But the game then stretches this to the screen - and reads from a single 512 tall texture. - // We initially use the first framebuffer. This code detects the read from the second. - // - // First Vs: 12, 228 - second Vs: 252, 468 - estimated fb height: 272 - - // If curTextureHeight is < h, it must be a framebuffer that wasn't full height. - if (gstate_c.curTextureHeight < (u32)h && maxIndex >= 2) { - // This is the max V that will still land within the framebuffer (since it's shorter.) - // We already adjusted V to the framebuffer above. - const float maxAvailableV = 1.0f; - // This is the max V that would've been inside the original texture size. - const float maxValidV = heightFactor; - - // Apparently, Assassin's Creed: Bloodlines accesses just outside. - const float invTexH = 1.0f / gstate_c.curTextureHeight; // size of one texel. - - // Are either TL or BR inside the texture but outside the framebuffer? - const bool tlOutside = transformed[0].v > maxAvailableV + invTexH && transformed[0].v <= maxValidV; - const bool brOutside = transformed[1].v > maxAvailableV + invTexH && transformed[1].v <= maxValidV; - - // If TL isn't outside, is it at least near the end? - // We check this because some games do 0-512 from a 272 tall framebuf. - const bool tlAlmostOutside = transformed[0].v > maxAvailableV * 0.5f && transformed[0].v <= maxValidV; - - if (tlOutside || (brOutside && tlAlmostOutside)) { - const u32 prevXOffset = gstate_c.curTextureXOffset; - const u32 prevYOffset = gstate_c.curTextureYOffset; - - // This is how far the nearest coord is, so that's where we'll look for the next framebuf. - const u32 yOffset = (int)(gstate_c.curTextureHeight * std::min(transformed[0].v, transformed[1].v)); - if (params_.texCache->SetOffsetTexture(yOffset)) { - const float oldWidthFactor = widthFactor; - const float oldHeightFactor = heightFactor; - widthFactor = (float)w / (float)gstate_c.curTextureWidth; - heightFactor = (float)h / (float)gstate_c.curTextureHeight; - - // We need to subtract this offset from the UVs to address the new framebuf. - const float adjustedYOffset = yOffset + prevYOffset - gstate_c.curTextureYOffset; - const float yDiff = (float)adjustedYOffset / (float)h; - const float adjustedXOffset = prevXOffset - gstate_c.curTextureXOffset; - const float xDiff = (float)adjustedXOffset / (float)w; - - for (int index = 0; index < maxIndex; ++index) { - transformed[index].u = (transformed[index].u / oldWidthFactor - xDiff) * widthFactor; - transformed[index].v = (transformed[index].v / oldHeightFactor - yDiff) * heightFactor; - } - - // We undid the offset, so reset. This avoids a different shader. - gstate_c.curTextureXOffset = prevXOffset; - gstate_c.curTextureYOffset = prevYOffset; - } - } - } -} - // NOTE: The viewport must be up to date! void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *&inds, int &maxIndex, SoftwareTransformResult *result) { TransformedVertex *transformed = params_.transformed; diff --git a/GPU/Common/SoftwareTransformCommon.h b/GPU/Common/SoftwareTransformCommon.h index 47c79a82de32..987e65c236c2 100644 --- a/GPU/Common/SoftwareTransformCommon.h +++ b/GPU/Common/SoftwareTransformCommon.h @@ -66,7 +66,6 @@ class SoftwareTransform { void SetProjMatrix(const float mtx[14], bool invertedX, bool invertedY, const Lin::Vec3 &trans, const Lin::Vec3 &scale); void Transform(int prim, u32 vertexType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result); - void DetectOffsetTexture(int maxIndex); void BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *&inds, int &maxIndex, SoftwareTransformResult *result); protected: diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index d2c6b4825d79..ac7dece6cf17 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -407,9 +407,6 @@ void DrawEngineD3D11::DoFlush() { // Games sometimes expect exact matches (see #12626, for example) for equal comparisons. if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (result.action == SW_NOT_READY) { - swTransform.DetectOffsetTexture(numDecodedVerts_); - } if (textureNeedsApply) textureCache_->ApplyTexture(); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index c3214f548cf8..20f98dfc5963 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -364,9 +364,6 @@ void DrawEngineDX9::DoFlush() { // Games sometimes expect exact matches (see #12626, for example) for equal comparisons. if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (result.action == SW_NOT_READY) { - swTransform.DetectOffsetTexture(numDecodedVerts_); - } if (textureNeedsApply) textureCache_->ApplyTexture(); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 681f5e81bbbf..0e44b8b667c0 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -392,8 +392,6 @@ void DrawEngineGLES::DoFlush() { // Games sometimes expect exact matches (see #12626, for example) for equal comparisons. if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (result.action == SW_NOT_READY) - swTransform.DetectOffsetTexture(numDecodedVerts_); if (textureNeedsApply) textureCache_->ApplyTexture(); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 6937217166d5..daf4b25a3a95 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -428,8 +428,8 @@ void DrawEngineVulkan::DoFlush() { // Games sometimes expect exact matches (see #12626, for example) for equal comparisons. if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; + if (result.action == SW_NOT_READY) { - swTransform.DetectOffsetTexture(numDecodedVerts_); swTransform.BuildDrawingParams(prim, vertexCount, dec_->VertexType(), inds, numDecodedVerts_, &result); } diff --git a/assets/compat.ini b/assets/compat.ini index c41796cf57ec..b53428e6ded0 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1280,6 +1280,12 @@ ULKS46226 = true ULAS42206 = true ULJM05541 = true +# Breath of Fire III +ULES00193 = true +ULJM05029 = true +ULJM05224 = true +NPJH50214 = true + [AtracLoopHack] #Atrac looped incorrectly see #7601 #13773 #11586 #10139 #12083