File melonds_PR1824.patch of Package melonds
From 8186ac1d6ab65a853daab77132672cbee7c7fce0 Mon Sep 17 00:00:00 2001
From: Jaklyy <102590697+Jaklyy@users.noreply.github.com>
Date: Sun, 10 Sep 2023 14:03:12 -0400
Subject: [PATCH] Check for line polygons using cur/next vl/vr
fixes a few cases that weren't handled properly
---
src/GPU3D_Soft.cpp | 45 ++++++++++++++++++++++++++++++++++++++-------
src/GPU3D_Soft.h | 2 ++
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp
index 98514ab7e..d9bb0aab0 100644
--- a/src/GPU3D_Soft.cpp
+++ b/src/GPU3D_Soft.cpp
@@ -569,6 +569,20 @@ void SoftRenderer::PlotTranslucentPixel(u32 pixeladdr, u32 color, u32 z, u32 pol
AttrBuffer[pixeladdr] = attr;
}
+void SoftRenderer::CheckForLine(RendererPolygon* rp)
+{
+ Polygon* polygon = rp->PolyData;
+
+ // check for line polygons
+ if (polygon->Vertices[rp->CurVL]->FinalPosition[0] == polygon->Vertices[rp->CurVR]->FinalPosition[0]
+ && polygon->Vertices[rp->CurVL]->FinalPosition[1] == polygon->Vertices[rp->CurVR]->FinalPosition[1]
+ && polygon->Vertices[rp->NextVL]->FinalPosition[0] == polygon->Vertices[rp->NextVR]->FinalPosition[0]
+ && polygon->Vertices[rp->NextVL]->FinalPosition[1] == polygon->Vertices[rp->NextVR]->FinalPosition[1])
+ rp->Line = true;
+ else
+ rp->Line = false;
+}
+
void SoftRenderer::SetupPolygonLeftEdge(SoftRenderer::RendererPolygon* rp, s32 y)
{
Polygon* polygon = rp->PolyData;
@@ -673,6 +687,7 @@ void SoftRenderer::SetupPolygon(SoftRenderer::RendererPolygon* rp, Polygon* poly
{
SetupPolygonLeftEdge(rp, ytop);
SetupPolygonRightEdge(rp, ytop);
+ CheckForLine(rp);
}
}
@@ -701,15 +716,23 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
if (polygon->YTop != polygon->YBottom)
{
- if (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom)
+ bool updateLeftSlope = (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom);
+ bool updateRightSlope = (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom);
+
+ if (updateLeftSlope)
{
SetupPolygonLeftEdge(rp, y);
}
- if (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom)
+ if (updateRightSlope)
{
SetupPolygonRightEdge(rp, y);
}
+
+ if (updateLeftSlope || updateRightSlope)
+ {
+ CheckForLine(rp);
+ }
}
Vertex *vlcur, *vlnext, *vrcur, *vrnext;
@@ -790,7 +813,7 @@ void SoftRenderer::RenderShadowMaskScanline(RendererPolygon* rp, s32 y)
{
l_filledge = ((rp->SlopeL.Negative || !rp->SlopeL.XMajor)
|| (y == polygon->YBottom-1) && rp->SlopeL.XMajor && (vlnext->FinalPosition[0] != vrnext->FinalPosition[0]))
- || (rp->SlopeL.Increment == rp->SlopeR.Increment) && (xstart+l_edgelen == xend+1);
+ || rp->Line;
r_filledge = (!rp->SlopeR.Negative && rp->SlopeR.XMajor) || (rp->SlopeR.Increment==0)
|| (y == polygon->YBottom-1) && rp->SlopeR.XMajor && (vlnext->FinalPosition[0] != vrnext->FinalPosition[0]);
}
@@ -926,15 +949,23 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
if (polygon->YTop != polygon->YBottom)
{
- if (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom)
+ bool updateLeftSlope = (y >= polygon->Vertices[rp->NextVL]->FinalPosition[1] && rp->CurVL != polygon->VBottom);
+ bool updateRightSlope = (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom);
+
+ if (updateLeftSlope)
{
SetupPolygonLeftEdge(rp, y);
}
- if (y >= polygon->Vertices[rp->NextVR]->FinalPosition[1] && rp->CurVR != polygon->VBottom)
+ if (updateRightSlope)
{
SetupPolygonRightEdge(rp, y);
}
+
+ if (updateLeftSlope || updateRightSlope)
+ {
+ CheckForLine(rp);
+ }
}
Vertex *vlcur, *vlnext, *vrcur, *vrnext;
@@ -986,7 +1017,7 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
// * left edge is filled if slope <= 1
// * the bottom-most pixel of negative x-major slopes are filled if they are next to a flat bottom edge
// edges are always filled if antialiasing/edgemarking are enabled or if the pixels are translucent
- // checkme: do swapped line polygons exist?
+ // checkme: do swapped line polygons exist? if they do then they likely should also be filled
if ((polyalpha < 31) || wireframe || (RenderDispCnt & ((1<<4)|(1<<5))))
{
l_filledge = true;
@@ -1030,7 +1061,7 @@ void SoftRenderer::RenderPolygonScanline(RendererPolygon* rp, s32 y)
{
l_filledge = ((rp->SlopeL.Negative || !rp->SlopeL.XMajor)
|| (y == polygon->YBottom-1) && rp->SlopeL.XMajor && (vlnext->FinalPosition[0] != vrnext->FinalPosition[0]))
- || (rp->SlopeL.Increment == rp->SlopeR.Increment) && (xstart+l_edgelen == xend+1);
+ || rp->Line;
r_filledge = (!rp->SlopeR.Negative && rp->SlopeR.XMajor) || (rp->SlopeR.Increment==0)
|| (y == polygon->YBottom-1) && rp->SlopeR.XMajor && (vlnext->FinalPosition[0] != vrnext->FinalPosition[0]);
}
diff --git a/src/GPU3D_Soft.h b/src/GPU3D_Soft.h
index 0c6ca4338..af9371f7a 100644
--- a/src/GPU3D_Soft.h
+++ b/src/GPU3D_Soft.h
@@ -448,6 +448,7 @@ class SoftRenderer : public Renderer3D
s32 XL, XR;
u32 CurVL, CurVR;
u32 NextVL, NextVR;
+ bool Line;
};
@@ -455,6 +456,7 @@ class SoftRenderer : public Renderer3D
void TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u16* color, u8* alpha);
u32 RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t);
void PlotTranslucentPixel(u32 pixeladdr, u32 color, u32 z, u32 polyattr, u32 shadow);
+ void CheckForLine(RendererPolygon* rp);
void SetupPolygonLeftEdge(RendererPolygon* rp, s32 y);
void SetupPolygonRightEdge(RendererPolygon* rp, s32 y);
void SetupPolygon(RendererPolygon* rp, Polygon* polygon);