File melonds_PR1807.patch of Package melonds
From 19a40968682094540ee6028b7a7e169012ea3201 Mon Sep 17 00:00:00 2001
From: Jaklyy <102590697+Jaklyy@users.noreply.github.com>
Date: Thu, 27 Jul 2023 02:23:36 -0400
Subject: [PATCH 1/2] fix certain slopes not having gaps
---
src/GPU3D_Soft.h | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/src/GPU3D_Soft.h b/src/GPU3D_Soft.h
index 0c6ca4338..e8796f0eb 100644
--- a/src/GPU3D_Soft.h
+++ b/src/GPU3D_Soft.h
@@ -280,7 +280,6 @@ class SoftRenderer : public Renderer3D
// slope increment has a 18-bit fractional part
// note: for some reason, x/y isn't calculated directly,
// instead, 1/y is calculated and then multiplied by x
- // TODO: this is still not perfect (see for example x=169 y=33)
if (ylen == 0)
Increment = 0;
else if (ylen == xlen && xlen != 1)
@@ -313,21 +312,41 @@ class SoftRenderer : public Renderer3D
dx += (y - y0) * Increment;
+ if (XMajor)
+ {
+ // used for calculating AA coverage
+ xcov_incr = (ylen << 10) / xlen;
+
+ if (side ^ Negative)
+ {
+ dxold = dx;
+ // I dont think the first span can have a gap but i think its technically correct to do this calc anyway?
+ // could probably be removed as a minor optimization
+ dx &= ~0x1FF;
+ }
+ }
+
s32 x = XVal();
int interpoffset = (Increment >= 0x40000) && (side ^ Negative);
Interp.Setup(y0-interpoffset, y1-interpoffset, w0, w1);
Interp.SetX(y);
- // used for calculating AA coverage
- if (XMajor) xcov_incr = (ylen << 10) / xlen;
-
return x;
}
s32 Step()
- {
- dx += Increment;
+ {
+ if (XMajor && (side ^ Negative)) // tl, br (right side start) & tr, bl (left side start)
+ {
+ // round dx; required to create gaps in lines like on hw
+ // increment using dxold to make the line not completely borked after rendering a gap
+ dx = (dxold & ~0x1FF) + Increment;
+ dxold += Increment;
+ }
+ else
+ dx += Increment;
+
y++;
s32 x = XVal();
@@ -353,15 +372,18 @@ class SoftRenderer : public Renderer3D
// only needed for aa calcs, as actual line spans are broken
if constexpr (!swapped || side)
{
- if (side ^ Negative)
- *length = (dx >> 18) - ((dx-Increment) >> 18);
- else
- *length = ((dx+Increment) >> 18) - (dx >> 18);
+ if (side ^ Negative) // tr, bl (left side end) & tl br (right side end)
+ // dxold used here to avoid rounding the endpoint
+ *length = (dx >> 18) - (dxold - Increment >> 18);
+ else // tl, br (left side end) & tr, bl (right side end)
+ // dx rounded down to create gaps in lines like on hw
+ *length = ((dx & ~0x1FF) + Increment >> 18) - (dx >> 18);
}
// for X-major edges, we return the coverage
// for the first pixel, and the increment for
// further pixels on the same scanline
+ // TODO: check how coverage interacts with line gaps
s32 startx = dx >> 18;
if (Negative) startx = xlen - startx;
if (side) startx = startx - *length + 1;
@@ -421,7 +443,7 @@ class SoftRenderer : public Renderer3D
private:
s32 x0, xmin, xmax;
s32 xlen, ylen;
- s32 dx;
+ s32 dx, dxold;
s32 y;
s32 xcov_incr;
From d2eb85e69bd72ed6237cf7ad6e554648bd88ec67 Mon Sep 17 00:00:00 2001
From: Jaklyy <102590697+Jaklyy@users.noreply.github.com>
Date: Sun, 27 Aug 2023 12:14:00 -0400
Subject: [PATCH 2/2] slight tweak to comments
---
src/GPU3D_Soft.h | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/GPU3D_Soft.h b/src/GPU3D_Soft.h
index e8796f0eb..e1fb33f41 100644
--- a/src/GPU3D_Soft.h
+++ b/src/GPU3D_Soft.h
@@ -320,7 +320,8 @@ class SoftRenderer : public Renderer3D
if (side ^ Negative)
{
dxold = dx;
- // I dont think the first span can have a gap but i think its technically correct to do this calc anyway?
+ // I dont think the first span can have a gap but
+ // I think its technically correct to do this calc anyway?
// could probably be removed as a minor optimization
dx &= ~0x1FF;
}
@@ -337,7 +338,7 @@ class SoftRenderer : public Renderer3D
s32 Step()
{
- if (XMajor && (side ^ Negative)) // tl, br (right side start) & tr, bl (left side start)
+ if (XMajor && (side ^ Negative)) // tl, br = \ (right side end) & tr, bl = / (left side start)
{
// round dx; required to create gaps in lines like on hw
// increment using dxold to make the line not completely borked after rendering a gap
@@ -372,10 +373,10 @@ class SoftRenderer : public Renderer3D
// only needed for aa calcs, as actual line spans are broken
if constexpr (!swapped || side)
{
- if (side ^ Negative) // tr, bl (left side end) & tl br (right side end)
+ if (side ^ Negative) // tr, bl = / (left side end) & tl br = \ (right side start)
// dxold used here to avoid rounding the endpoint
*length = (dx >> 18) - (dxold - Increment >> 18);
- else // tl, br (left side end) & tr, bl (right side end)
+ else // tl, br = \ (left side end) & tr, bl = / (right side start)
// dx rounded down to create gaps in lines like on hw
*length = ((dx & ~0x1FF) + Increment >> 18) - (dx >> 18);
}
@@ -383,7 +384,7 @@ class SoftRenderer : public Renderer3D
// for X-major edges, we return the coverage
// for the first pixel, and the increment for
// further pixels on the same scanline
- // TODO: check how coverage interacts with line gaps
+ // TODO: check how coverage interacts with line gaps, I think it's correct though?
s32 startx = dx >> 18;
if (Negative) startx = xlen - startx;
if (side) startx = startx - *length + 1;