aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-04-22 16:47:31 +0200
committerStapleButter <thetotalworm@gmail.com>2017-04-22 16:47:31 +0200
commit4f72ee389560a471313dc6f646e0b0074302fab0 (patch)
treed160d350e3d0a548525ddf63a4285f049b52955a /src
parenteb656857d9be9c7acf6d1152724518b73aa0fee7 (diff)
add support for polygon ID and conditional depth update for translucent pixels
Diffstat (limited to 'src')
-rw-r--r--src/ARM.h9
-rw-r--r--src/GPU3D_Soft.cpp67
2 files changed, 47 insertions, 29 deletions
diff --git a/src/ARM.h b/src/ARM.h
index 3631f86..a51c3ff 100644
--- a/src/ARM.h
+++ b/src/ARM.h
@@ -47,6 +47,15 @@ public:
Halted = halt;
}
+ void CheckIRQ()
+ {
+ if (!(NDS::IME[Num] & 0x1)) return;
+ if (NDS::IF[Num] & NDS::IE[Num])
+ {
+ TriggerIRQ();
+ }
+ }
+
s32 Execute();
bool CheckCondition(u32 code)
diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp
index f129350..6dd5676 100644
--- a/src/GPU3D_Soft.cpp
+++ b/src/GPU3D_Soft.cpp
@@ -32,8 +32,9 @@ u32 DepthBuffer[256*192];
u32 AttrBuffer[256*192];
// attribute buffer:
-// bit0-5: polygon ID
-// bit8: fog enable
+// bit15: fog enable
+// bit24-29: polygon ID
+// bit30: translucent flag
bool Init()
@@ -918,7 +919,7 @@ void RenderPolygon(Polygon* polygon)
s16 t = interpX.Interpolate(tl, tr);
u32 color = RenderPixel(polygon, vr>>3, vg>>3, vb>>3, s, t);
- u32 attr = 0;
+ u32 attr = polygon->Attr & 0x3F008000;
u8 alpha = color >> 24;
@@ -937,9 +938,6 @@ void RenderPolygon(Polygon* polygon)
if (!(DispCnt & (1<<3)))
alpha = 31;
- u32 dstcolor = ColorBuffer[pixeladdr];
- u32 dstalpha = dstcolor >> 24;
-
if (alpha == 31)
{
// edge fill rules for opaque pixels
@@ -954,33 +952,44 @@ void RenderPolygon(Polygon* polygon)
DepthBuffer[pixeladdr] = z;
}
- else if (dstalpha == 0)
- {
- // TODO: conditional Z-buffer update
- DepthBuffer[pixeladdr] = z;
- }
else
{
- u32 srcR = color & 0x3F;
- u32 srcG = (color >> 8) & 0x3F;
- u32 srcB = (color >> 16) & 0x3F;
+ u32 dstattr = AttrBuffer[pixeladdr];
+ attr |= (1<<30);
+
+ // skip if polygon IDs are equal
+ // note: this only happens if the destination pixel was translucent
+ // the GPU keeps track of which pixels are translucent, regardless of
+ // the destination alpha
+ if ((dstattr & 0x7F000000) == (attr & 0x7F000000))
+ continue;
- u32 dstR = dstcolor & 0x3F;
- u32 dstG = (dstcolor >> 8) & 0x3F;
- u32 dstB = (dstcolor >> 16) & 0x3F;
+ u32 dstcolor = ColorBuffer[pixeladdr];
+ u32 dstalpha = dstcolor >> 24;
- alpha++;
- dstR = ((srcR * alpha) + (dstR * (32-alpha))) >> 5;
- dstG = ((srcG * alpha) + (dstG * (32-alpha))) >> 5;
- dstB = ((srcB * alpha) + (dstB * (32-alpha))) >> 5;
+ if (dstalpha > 0)
+ {
+ u32 srcR = color & 0x3F;
+ u32 srcG = (color >> 8) & 0x3F;
+ u32 srcB = (color >> 16) & 0x3F;
- alpha--;
- if (alpha > dstalpha) dstalpha = alpha;
+ u32 dstR = dstcolor & 0x3F;
+ u32 dstG = (dstcolor >> 8) & 0x3F;
+ u32 dstB = (dstcolor >> 16) & 0x3F;
- color = dstR | (dstG << 8) | (dstB << 16) | (dstalpha << 24);
+ alpha++;
+ dstR = ((srcR * alpha) + (dstR * (32-alpha))) >> 5;
+ dstG = ((srcG * alpha) + (dstG * (32-alpha))) >> 5;
+ dstB = ((srcB * alpha) + (dstB * (32-alpha))) >> 5;
- // TODO: conditional Z-buffer update
- DepthBuffer[pixeladdr] = z;
+ alpha--;
+ if (alpha > dstalpha) dstalpha = alpha;
+
+ color = dstR | (dstG << 8) | (dstB << 16) | (dstalpha << 24);
+ }
+
+ if (polygon->Attr & (1<<11))
+ DepthBuffer[pixeladdr] = z;
}
ColorBuffer[pixeladdr] = color;
@@ -994,7 +1003,7 @@ void RenderPolygon(Polygon* polygon)
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
{
- u32 polyid = (RenderClearAttr1 >> 24) & 0x3F;
+ u32 polyid = RenderClearAttr1 & 0x3F000000;
if (DispCnt & (1<<14))
{
@@ -1019,7 +1028,7 @@ void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
ColorBuffer[y+x] = color;
DepthBuffer[y+x] = z;
- AttrBuffer[y+x] = polyid | ((val3 & 0x8000) >> 7);
+ AttrBuffer[y+x] = polyid | (val3 & 0x8000);
xoff++;
}
@@ -1038,7 +1047,7 @@ void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
u32 z = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
- polyid |= ((RenderClearAttr1 & 0x8000) >> 7);
+ polyid |= (RenderClearAttr1 & 0x8000);
for (int i = 0; i < 256*192; i++)
{