mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 05:17:40 -07:00
Merge 3268f94f4b
into 7c1d2a64f4
This commit is contained in:
commit
d7f39a2f2b
@ -774,8 +774,8 @@ void SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
|
|||||||
interp_start = &rp->SlopeR.Interp;
|
interp_start = &rp->SlopeR.Interp;
|
||||||
interp_end = &rp->SlopeL.Interp;
|
interp_end = &rp->SlopeL.Interp;
|
||||||
|
|
||||||
rp->SlopeR.EdgeParams<true>(&l_edgelen, &l_edgecov);
|
rp->SlopeR.EdgeParams(&l_edgelen, &l_edgecov, true);
|
||||||
rp->SlopeL.EdgeParams<true>(&r_edgelen, &r_edgecov);
|
rp->SlopeL.EdgeParams(&r_edgelen, &r_edgecov, true);
|
||||||
|
|
||||||
std::swap(xstart, xend);
|
std::swap(xstart, xend);
|
||||||
std::swap(wl, wr);
|
std::swap(wl, wr);
|
||||||
@ -806,9 +806,9 @@ void SoftRenderer::RenderShadowMaskScanline(const GPU3D& gpu3d, RendererPolygon*
|
|||||||
interp_start = &rp->SlopeL.Interp;
|
interp_start = &rp->SlopeL.Interp;
|
||||||
interp_end = &rp->SlopeR.Interp;
|
interp_end = &rp->SlopeR.Interp;
|
||||||
|
|
||||||
rp->SlopeL.EdgeParams<false>(&l_edgelen, &l_edgecov);
|
rp->SlopeL.EdgeParams(&l_edgelen, &l_edgecov, false);
|
||||||
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov);
|
rp->SlopeR.EdgeParams(&r_edgelen, &r_edgecov, false);
|
||||||
|
|
||||||
// CHECKME: edge fill rules for unswapped opaque shadow mask polygons
|
// CHECKME: edge fill rules for unswapped opaque shadow mask polygons
|
||||||
if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe)
|
if ((gpu3d.RenderDispCnt & ((1<<4)|(1<<5))) || ((polyalpha < 31) && (gpu3d.RenderDispCnt & (1<<3))) || wireframe)
|
||||||
{
|
{
|
||||||
@ -1003,8 +1003,8 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
interp_start = &rp->SlopeR.Interp;
|
interp_start = &rp->SlopeR.Interp;
|
||||||
interp_end = &rp->SlopeL.Interp;
|
interp_end = &rp->SlopeL.Interp;
|
||||||
|
|
||||||
rp->SlopeR.EdgeParams<true>(&l_edgelen, &l_edgecov);
|
rp->SlopeR.EdgeParams(&l_edgelen, &l_edgecov, true);
|
||||||
rp->SlopeL.EdgeParams<true>(&r_edgelen, &r_edgecov);
|
rp->SlopeL.EdgeParams(&r_edgelen, &r_edgecov, true);
|
||||||
|
|
||||||
std::swap(xstart, xend);
|
std::swap(xstart, xend);
|
||||||
std::swap(wl, wr);
|
std::swap(wl, wr);
|
||||||
@ -1041,8 +1041,8 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
interp_start = &rp->SlopeL.Interp;
|
interp_start = &rp->SlopeL.Interp;
|
||||||
interp_end = &rp->SlopeR.Interp;
|
interp_end = &rp->SlopeR.Interp;
|
||||||
|
|
||||||
rp->SlopeL.EdgeParams<false>(&l_edgelen, &l_edgecov);
|
rp->SlopeL.EdgeParams(&l_edgelen, &l_edgecov, false);
|
||||||
rp->SlopeR.EdgeParams<false>(&r_edgelen, &r_edgecov);
|
rp->SlopeR.EdgeParams(&r_edgelen, &r_edgecov, false);
|
||||||
|
|
||||||
// edge fill rules for unswapped opaque edges:
|
// edge fill rules for unswapped opaque edges:
|
||||||
// * right edge is filled if slope > 1
|
// * right edge is filled if slope > 1
|
||||||
@ -1096,18 +1096,11 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
if (x < 0) x = 0;
|
if (x < 0) x = 0;
|
||||||
s32 xlimit;
|
s32 xlimit;
|
||||||
|
|
||||||
s32 xcov = 0;
|
|
||||||
|
|
||||||
// part 1: left edge
|
// part 1: left edge
|
||||||
edge = yedge | 0x1;
|
edge = yedge | 0x1;
|
||||||
xlimit = xstart+l_edgelen;
|
xlimit = xstart+l_edgelen;
|
||||||
if (xlimit > xend+1) xlimit = xend+1;
|
if (xlimit > xend+1) xlimit = xend+1;
|
||||||
if (xlimit > 256) xlimit = 256;
|
if (xlimit > 256) xlimit = 256;
|
||||||
if (l_edgecov & (1<<31))
|
|
||||||
{
|
|
||||||
xcov = (l_edgecov >> 12) & 0x3FF;
|
|
||||||
if (xcov == 0x3FF) xcov = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!l_filledge) x = xlimit;
|
if (!l_filledge) x = xlimit;
|
||||||
else
|
else
|
||||||
@ -1166,14 +1159,12 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
// anti-aliasing: all edges are rendered
|
// anti-aliasing: all edges are rendered
|
||||||
|
|
||||||
// calculate coverage
|
// calculate coverage
|
||||||
s32 cov = l_edgecov;
|
attr |= (l_edgecov >> 5) << 8;
|
||||||
if (cov & (1<<31))
|
if (x < xlimit-1)
|
||||||
{
|
{
|
||||||
cov = xcov >> 5;
|
l_edgecov += rp->SlopeL.XCov_Incr;
|
||||||
if (cov > 31) cov = 31;
|
if (l_edgecov > 0x3FF) l_edgecov = 0x3FF;
|
||||||
xcov += (l_edgecov & 0x3FF);
|
|
||||||
}
|
}
|
||||||
attr |= (cov << 8);
|
|
||||||
|
|
||||||
// push old pixel down if needed
|
// push old pixel down if needed
|
||||||
if (pixeladdr < BufferSize)
|
if (pixeladdr < BufferSize)
|
||||||
@ -1292,11 +1283,6 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
edge = yedge | 0x2;
|
edge = yedge | 0x2;
|
||||||
xlimit = xend+1;
|
xlimit = xend+1;
|
||||||
if (xlimit > 256) xlimit = 256;
|
if (xlimit > 256) xlimit = 256;
|
||||||
if (r_edgecov & (1<<31))
|
|
||||||
{
|
|
||||||
xcov = (r_edgecov >> 12) & 0x3FF;
|
|
||||||
if (xcov == 0x3FF) xcov = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_filledge)
|
if (r_filledge)
|
||||||
for (; x < xlimit; x++)
|
for (; x < xlimit; x++)
|
||||||
@ -1354,14 +1340,12 @@ void SoftRenderer::RenderPolygonScanline(const GPU& gpu, RendererPolygon* rp, s3
|
|||||||
// anti-aliasing: all edges are rendered
|
// anti-aliasing: all edges are rendered
|
||||||
|
|
||||||
// calculate coverage
|
// calculate coverage
|
||||||
s32 cov = r_edgecov;
|
attr |= (r_edgecov >> 5) << 8;
|
||||||
if (cov & (1<<31))
|
if (x < xlimit-1)
|
||||||
{
|
{
|
||||||
cov = 0x1F - (xcov >> 5);
|
r_edgecov -= rp->SlopeR.XCov_Incr;
|
||||||
if (cov < 0) cov = 0;
|
if (r_edgecov < 0) r_edgecov = 0;
|
||||||
xcov += (r_edgecov & 0x3FF);
|
|
||||||
}
|
}
|
||||||
attr |= (cov << 8);
|
|
||||||
|
|
||||||
// push old pixel down if needed
|
// push old pixel down if needed
|
||||||
if (pixeladdr < BufferSize)
|
if (pixeladdr < BufferSize)
|
||||||
|
@ -238,6 +238,7 @@ private:
|
|||||||
dx = 0;
|
dx = 0;
|
||||||
|
|
||||||
this->x0 = x0;
|
this->x0 = x0;
|
||||||
|
this->y0 = y0;
|
||||||
this->xmin = x0;
|
this->xmin = x0;
|
||||||
this->xmax = x0;
|
this->xmax = x0;
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ private:
|
|||||||
Interp.Setup(0, 0, 0, 0);
|
Interp.Setup(0, 0, 0, 0);
|
||||||
Interp.SetX(0);
|
Interp.SetX(0);
|
||||||
|
|
||||||
xcov_incr = 0;
|
XCov_Incr = 0;
|
||||||
|
|
||||||
return x0;
|
return x0;
|
||||||
}
|
}
|
||||||
@ -255,6 +256,7 @@ private:
|
|||||||
constexpr s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y)
|
constexpr s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y)
|
||||||
{
|
{
|
||||||
this->x0 = x0;
|
this->x0 = x0;
|
||||||
|
this->y0 = y0;
|
||||||
this->y = y;
|
this->y = y;
|
||||||
|
|
||||||
if (x1 > x0)
|
if (x1 > x0)
|
||||||
@ -322,7 +324,7 @@ private:
|
|||||||
Interp.SetX(y);
|
Interp.SetX(y);
|
||||||
|
|
||||||
// used for calculating AA coverage
|
// used for calculating AA coverage
|
||||||
if (XMajor) xcov_incr = (ylen << 10) / xlen;
|
if (XMajor) XCov_Incr = ((ylen << 10) / xlen) & 0x3FF;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@ -347,19 +349,15 @@ private:
|
|||||||
else if (ret > xmax) ret = xmax;
|
else if (ret > xmax) ret = xmax;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool swapped>
|
constexpr void EdgeParams_XMajor(s32* length, s32* coverage, bool swapped) const
|
||||||
constexpr void EdgeParams_XMajor(s32* length, s32* coverage) const
|
|
||||||
{
|
{
|
||||||
// only do length calc for right side when swapped as it's
|
// only do length calc for right side when swapped as it's
|
||||||
// only needed for aa calcs, as actual line spans are broken
|
// only needed for aa calcs, as actual line spans are broken
|
||||||
if constexpr (!swapped || side)
|
if (side ^ Negative)
|
||||||
{
|
*length = (dx >> 18) - ((dx-Increment) >> 18);
|
||||||
if (side ^ Negative)
|
else
|
||||||
*length = (dx >> 18) - ((dx-Increment) >> 18);
|
*length = ((dx+Increment) >> 18) - (dx >> 18);
|
||||||
else
|
|
||||||
*length = ((dx+Increment) >> 18) - (dx >> 18);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for X-major edges, we return the coverage
|
// for X-major edges, we return the coverage
|
||||||
// for the first pixel, and the increment for
|
// for the first pixel, and the increment for
|
||||||
@ -369,13 +367,20 @@ private:
|
|||||||
if (side) startx = startx - *length + 1;
|
if (side) startx = startx - *length + 1;
|
||||||
|
|
||||||
s32 startcov = (((startx << 10) + 0x1FF) * ylen) / xlen;
|
s32 startcov = (((startx << 10) + 0x1FF) * ylen) / xlen;
|
||||||
*coverage = (1<<31) | ((startcov & 0x3FF) << 12) | (xcov_incr & 0x3FF);
|
|
||||||
|
|
||||||
if constexpr (swapped) *length = 1;
|
// fix the y value for negative slopes
|
||||||
|
s32 ycoord = Negative ? (ylen << 10) - startcov >> 10 : startcov >> 10;
|
||||||
|
// if yvalue is not equal to actual y value, invert coverage value
|
||||||
|
startcov &= 0x3FF;
|
||||||
|
if (ycoord != y - y0) startcov = 0x3FF - startcov;
|
||||||
|
if (side ^ swapped) startcov = 0x3FF - startcov;
|
||||||
|
|
||||||
|
*coverage = startcov;
|
||||||
|
|
||||||
|
if (swapped) *length = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool swapped>
|
constexpr void EdgeParams_YMajor(s32* length, s32* coverage, bool swapped) const
|
||||||
constexpr void EdgeParams_YMajor(s32* length, s32* coverage) const
|
|
||||||
{
|
{
|
||||||
*length = 1;
|
*length = 1;
|
||||||
|
|
||||||
@ -383,51 +388,39 @@ private:
|
|||||||
{
|
{
|
||||||
// for some reason vertical edges' aa values
|
// for some reason vertical edges' aa values
|
||||||
// are inverted too when the edges are swapped
|
// are inverted too when the edges are swapped
|
||||||
if constexpr (swapped)
|
*coverage = swapped ? 0 : 31 << 5;
|
||||||
*coverage = 0;
|
|
||||||
else
|
|
||||||
*coverage = 31;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s32 cov = ((dx >> 9) + (Increment >> 10)) >> 4;
|
s32 cov = ((dx >> 9) + (Increment >> 10)) >> 4;
|
||||||
if ((cov >> 5) != (dx >> 18)) cov = 31;
|
if ((cov >> 5) != (dx >> 18)) cov = 31;
|
||||||
cov &= 0x1F;
|
cov &= 0x1F;
|
||||||
if constexpr (swapped)
|
if (side ^ !Negative ^ swapped) cov = 0x1F - cov;
|
||||||
{
|
|
||||||
if (side ^ Negative) cov = 0x1F - cov;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(side ^ Negative)) cov = 0x1F - cov;
|
|
||||||
}
|
|
||||||
|
|
||||||
*coverage = cov;
|
// shift left 5 just to make it align with xmajor coverage values
|
||||||
|
*coverage = cov << 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool swapped>
|
constexpr void EdgeParams(s32* length, s32* coverage, bool swapped) const
|
||||||
constexpr void EdgeParams(s32* length, s32* coverage) const
|
|
||||||
{
|
{
|
||||||
if (XMajor)
|
if (XMajor)
|
||||||
return EdgeParams_XMajor<swapped>(length, coverage);
|
return EdgeParams_XMajor(length, coverage, swapped);
|
||||||
else
|
else
|
||||||
return EdgeParams_YMajor<swapped>(length, coverage);
|
return EdgeParams_YMajor(length, coverage, swapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Increment;
|
s32 Increment;
|
||||||
bool Negative;
|
bool Negative;
|
||||||
bool XMajor;
|
bool XMajor;
|
||||||
Interpolator<1> Interp;
|
Interpolator<1> Interp;
|
||||||
|
s32 XCov_Incr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
s32 x0, xmin, xmax;
|
s32 x0, y0, xmin, xmax;
|
||||||
s32 xlen, ylen;
|
s32 xlen, ylen;
|
||||||
s32 dx;
|
s32 dx;
|
||||||
s32 y;
|
s32 y;
|
||||||
|
|
||||||
s32 xcov_incr;
|
|
||||||
s32 ycoverage, ycov_incr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 AlphaBlend(const GPU3D& gpu3d, u32 srccolor, u32 dstcolor, u32 alpha) const noexcept;
|
u32 AlphaBlend(const GPU3D& gpu3d, u32 srccolor, u32 dstcolor, u32 alpha) const noexcept;
|
||||||
|
Loading…
Reference in New Issue
Block a user