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);
openSUSE Build Service is sponsored by