Skip to content

Commit

Permalink
Use the Tokimeki / old Juiced 2 method for Breath of Fire III
Browse files Browse the repository at this point in the history
Allows us to delete a bunch of complex code.
  • Loading branch information
hrydgard committed Jan 11, 2024
1 parent 0f01aa6 commit 0b6ea4b
Show file tree
Hide file tree
Showing 7 changed files with 7 additions and 77 deletions.
67 changes: 0 additions & 67 deletions GPU/Common/SoftwareTransformCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion GPU/Common/SoftwareTransformCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 0 additions & 3 deletions GPU/D3D11/DrawEngineD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 0 additions & 3 deletions GPU/Directx9/DrawEngineDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 0 additions & 2 deletions GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion GPU/Vulkan/DrawEngineVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
6 changes: 6 additions & 0 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 0b6ea4b

Please sign in to comment.