aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-02-14 02:43:35 +0100
committerStapleButter <thetotalworm@gmail.com>2017-02-14 02:43:35 +0100
commit68fb77b2047ace4ac3f2d39b39cff70832d4460a (patch)
tree8d36650b290083f5d452ff8ee3aebf05c18235d6
parentfb53fd5195f52365dd802e54412b4af5e049b677 (diff)
* backface/frontface culling (and rendering of backfacing polygons)
* fix clipping/viewport transform precision errors * triangle/quad strips
-rw-r--r--GPU3D.cpp370
-rw-r--r--GPU3D.h6
-rw-r--r--GPU3D_Soft.cpp96
-rw-r--r--NDS.cpp2
-rw-r--r--main.cpp4
-rw-r--r--melonDS.depend10
6 files changed, 325 insertions, 163 deletions
diff --git a/GPU3D.cpp b/GPU3D.cpp
index e77af69..9f461a4 100644
--- a/GPU3D.cpp
+++ b/GPU3D.cpp
@@ -159,9 +159,14 @@ u32 PolygonMode;
s16 CurVertex[3];
u8 VertexColor[3];
+u32 PolygonAttr;
+u32 CurPolygonAttr;
+
Vertex TempVertexBuffer[4];
u32 VertexNum;
u32 VertexNumInPoly;
+u32 NumConsecutivePolygons;
+Polygon* LastStripPolygon;
Vertex VertexRAM[6144 * 2];
Polygon PolygonRAM[2048 * 2];
@@ -385,13 +390,13 @@ void UpdateClipMatrix()
template<int comp, s32 plane>
-void ClipSegment(Vertex* outbuf, int num, Vertex* vout, Vertex* vin)
+void ClipSegment(Vertex* outbuf, Vertex* vout, Vertex* vin)
{
- s64 factor = ((vin->Position[3] - (plane*vin->Position[comp])) << 12) /
+ s64 factor = ((s64)(vin->Position[3] - (plane*vin->Position[comp])) << 24) /
((vin->Position[3] - (plane*vin->Position[comp])) - (vout->Position[3] - (plane*vout->Position[comp])));
Vertex mid;
-#define INTERPOLATE(var) mid.var = vin->var + (((vout->var - vin->var) * factor) >> 12);
+#define INTERPOLATE(var) mid.var = vin->var + (((vout->var - vin->var) * factor) >> 24);
INTERPOLATE(Position[0]);
INTERPOLATE(Position[1]);
@@ -402,213 +407,339 @@ void ClipSegment(Vertex* outbuf, int num, Vertex* vout, Vertex* vin)
INTERPOLATE(Color[1]);
INTERPOLATE(Color[2]);
+ mid.Clipped = true;
+
#undef INTERPOLATE
- outbuf[num] = mid;
+ *outbuf = mid;
}
void SubmitPolygon()
{
- // clip.
- // for each vertex:
- // if it's outside, check if the previous and next vertices are inside, if so, fixor
-
Vertex clippedvertices[2][10];
- u32 numclipped;
+ Vertex* reusedvertices[2];
+ int clipstart = 0;
+ int lastpolyverts = 0;
int nverts = PolygonMode & 0x1 ? 4:3;
- int nvisible = 0;
int prev, next;
int c;
- /*if (NumPolygons == 91)
- for (int i = 0; i < nverts; i++)
+ // culling
+ //if (!(TempVertexBuffer[0].Color[0]==0 && TempVertexBuffer[0].Color[1]==63 && TempVertexBuffer[0].Color[2]==63))
+ // return;
+
+ // checkme: does it work this way for quads and up?
+ /*s32 _x1 = TempVertexBuffer[1].Position[0] - TempVertexBuffer[0].Position[0];
+ s32 _x2 = TempVertexBuffer[2].Position[0] - TempVertexBuffer[0].Position[0];
+ s32 _y1 = TempVertexBuffer[1].Position[1] - TempVertexBuffer[0].Position[1];
+ s32 _y2 = TempVertexBuffer[2].Position[1] - TempVertexBuffer[0].Position[1];
+ s32 _z1 = TempVertexBuffer[1].Position[2] - TempVertexBuffer[0].Position[2];
+ s32 _z2 = TempVertexBuffer[2].Position[2] - TempVertexBuffer[0].Position[2];
+ s32 normalX = (((s64)_y1 * _z2) - ((s64)_z1 * _y2)) >> 12;
+ s32 normalY = (((s64)_z1 * _x2) - ((s64)_x1 * _z2)) >> 12;
+ s32 normalZ = (((s64)_x1 * _y2) - ((s64)_y1 * _x2)) >> 12;*/
+ /*s32 centerX = ((s64)TempVertexBuffer[0].Position[3] * ClipMatrix[12]) >> 12;
+ s32 centerY = ((s64)TempVertexBuffer[0].Position[3] * ClipMatrix[13]) >> 12;
+ s32 centerZ = ((s64)TempVertexBuffer[0].Position[3] * ClipMatrix[14]) >> 12;*/
+ /*s64 dot = ((s64)(-TempVertexBuffer[0].Position[0]) * normalX) +
+ ((s64)(-TempVertexBuffer[0].Position[1]) * normalY) +
+ ((s64)(-TempVertexBuffer[0].Position[2]) * normalZ); // checkme*/
+ // code inspired from Dolphin's software renderer.
+ // maybe not 100% right
+ s32 _x0 = TempVertexBuffer[0].Position[0];
+ s32 _x1 = TempVertexBuffer[1].Position[0];
+ s32 _x2 = TempVertexBuffer[2].Position[0];
+ s32 _y0 = TempVertexBuffer[0].Position[1];
+ s32 _y1 = TempVertexBuffer[1].Position[1];
+ s32 _y2 = TempVertexBuffer[2].Position[1];
+ s32 _z0 = TempVertexBuffer[0].Position[3];
+ s32 _z1 = TempVertexBuffer[1].Position[3];
+ s32 _z2 = TempVertexBuffer[2].Position[3];
+ s32 normalX = (((s64)_y0 * _z2) - ((s64)_z0 * _y2)) >> 12;
+ s32 normalY = (((s64)_z0 * _x2) - ((s64)_x0 * _z2)) >> 12;
+ s32 normalZ = (((s64)_x0 * _y2) - ((s64)_y0 * _x2)) >> 12;
+ s64 dot = ((s64)_x1 * normalX) + ((s64)_y1 * normalY) + ((s64)_z1 * normalZ);
+ bool facingview = (dot < 0);
+//printf("Z: %d %d\n", normalZ, -TempVertexBuffer[0].Position[2]);
+ if (facingview)
{
- Vertex vtx = TempVertexBuffer[i];
- printf("pre-clip v%d: %f %f %f %f\n", i,
- vtx.Position[0]/4096.0f, vtx.Position[1]/4096.0f,
- vtx.Position[2]/4096.0f, vtx.Position[3]/4096.0f);
- }*/
+ if (!(CurPolygonAttr & (1<<7)))
+ {
+ LastStripPolygon = NULL;
+ return;
+ }
+ }
+ else
+ {
+ if (!(CurPolygonAttr & (1<<6)))
+ {
+ LastStripPolygon = NULL;
+ return;
+ }
+ }
+
+ // for strips, check whether we can attach to the previous polygon
+ // this requires two vertices shared with the previous polygon, and that
+ // the two polygons be of the same type
+
+ if (PolygonMode >= 2 && LastStripPolygon)
+ {
+ int id0, id1;
+ if (PolygonMode == 2)
+ {
+ if (NumConsecutivePolygons & 1)
+ {
+ id0 = 2;
+ id1 = 1;
+ }
+ else
+ {
+ id0 = 0;
+ id1 = 2;
+ }
+
+ lastpolyverts = 3;
+ }
+ else
+ {
+ id0 = 3;
+ id1 = 2;
+
+ lastpolyverts = 4;
+ }
+
+ if (LastStripPolygon->NumVertices == lastpolyverts &&
+ !LastStripPolygon->Vertices[id0]->Clipped &&
+ !LastStripPolygon->Vertices[id1]->Clipped)
+ {
+ reusedvertices[0] = LastStripPolygon->Vertices[id0];
+ reusedvertices[1] = LastStripPolygon->Vertices[id1];
+
+ clippedvertices[0][0] = *reusedvertices[0];
+ clippedvertices[0][1] = *reusedvertices[1];
+ clippedvertices[1][0] = *reusedvertices[0];
+ clippedvertices[1][1] = *reusedvertices[1];
+
+ clipstart = 2;
+ }
+ }
+
+ // clip.
+ // for each vertex:
+ // if it's outside, check if the previous and next vertices are inside
+ // if so, place a new vertex at the edge of the view volume
// X clipping
- prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = TempVertexBuffer[i];
if (vtx.Position[0] > vtx.Position[3])
{
Vertex* vprev = &TempVertexBuffer[prev];
if (vprev->Position[0] <= vprev->Position[3])
{
- ClipSegment<0, 1>(clippedvertices[0], c, &vtx, vprev);
+ ClipSegment<0, 1>(&clippedvertices[0][c], &vtx, vprev);
c++;
}
Vertex* vnext = &TempVertexBuffer[next];
if (vnext->Position[0] <= vnext->Position[3])
{
- ClipSegment<0, 1>(clippedvertices[0], c, &vtx, vnext);
+ ClipSegment<0, 1>(&clippedvertices[0][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[0][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
- nverts = c; prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ nverts = c; c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = clippedvertices[0][i];
if (vtx.Position[0] < -vtx.Position[3])
{
Vertex* vprev = &clippedvertices[0][prev];
if (vprev->Position[0] >= -vprev->Position[3])
{
- ClipSegment<0, -1>(clippedvertices[1], c, &vtx, vprev);
+ ClipSegment<0, -1>(&clippedvertices[1][c], &vtx, vprev);
c++;
}
Vertex* vnext = &clippedvertices[0][next];
if (vnext->Position[0] >= -vnext->Position[3])
{
- ClipSegment<0, -1>(clippedvertices[1], c, &vtx, vnext);
+ ClipSegment<0, -1>(&clippedvertices[1][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[1][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
// Y clipping
- nverts = c; prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ nverts = c; c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = clippedvertices[1][i];
if (vtx.Position[1] > vtx.Position[3])
{
Vertex* vprev = &clippedvertices[1][prev];
if (vprev->Position[1] <= vprev->Position[3])
{
- ClipSegment<1, 1>(clippedvertices[0], c, &vtx, vprev);
+ ClipSegment<1, 1>(&clippedvertices[0][c], &vtx, vprev);
c++;
}
Vertex* vnext = &clippedvertices[1][next];
if (vnext->Position[1] <= vnext->Position[3])
{
- ClipSegment<1, 1>(clippedvertices[0], c, &vtx, vnext);
+ ClipSegment<1, 1>(&clippedvertices[0][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[0][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
- nverts = c; prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ nverts = c; c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = clippedvertices[0][i];
if (vtx.Position[1] < -vtx.Position[3])
{
Vertex* vprev = &clippedvertices[0][prev];
if (vprev->Position[1] >= -vprev->Position[3])
{
- ClipSegment<1, -1>(clippedvertices[1], c, &vtx, vprev);
+ ClipSegment<1, -1>(&clippedvertices[1][c], &vtx, vprev);
c++;
}
Vertex* vnext = &clippedvertices[0][next];
if (vnext->Position[1] >= -vnext->Position[3])
{
- ClipSegment<1, -1>(clippedvertices[1], c, &vtx, vnext);
+ ClipSegment<1, -1>(&clippedvertices[1][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[1][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
// Z clipping
- nverts = c; prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ nverts = c; c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = clippedvertices[1][i];
if (vtx.Position[2] > vtx.Position[3])
{
Vertex* vprev = &clippedvertices[1][prev];
if (vprev->Position[2] <= vprev->Position[3])
{
- ClipSegment<2, 1>(clippedvertices[0], c, &vtx, vprev);
+ ClipSegment<2, 1>(&clippedvertices[0][c], &vtx, vprev);
c++;
}
Vertex* vnext = &clippedvertices[1][next];
if (vnext->Position[2] <= vnext->Position[3])
{
- ClipSegment<2, 1>(clippedvertices[0], c, &vtx, vnext);
+ ClipSegment<2, 1>(&clippedvertices[0][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[0][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
- nverts = c; prev = nverts-1; next = 1; c = 0;
- for (int i = 0; i < nverts; i++)
+ nverts = c; c = clipstart;
+ for (int i = clipstart; i < nverts; i++)
{
+ prev = i-1; if (prev < 0) prev = nverts-1;
+ next = i+1; if (next >= nverts) next = 0;
+
Vertex vtx = clippedvertices[0][i];
if (vtx.Position[2] < -vtx.Position[3])
{
Vertex* vprev = &clippedvertices[0][prev];
if (vprev->Position[2] >= -vprev->Position[3])
{
- ClipSegment<2, -1>(clippedvertices[1], c, &vtx, vprev);
+ ClipSegment<2, -1>(&clippedvertices[1][c], &vtx, vprev);
c++;
}
Vertex* vnext = &clippedvertices[0][next];
if (vnext->Position[2] >= -vnext->Position[3])
{
- ClipSegment<2, -1>(clippedvertices[1], c, &vtx, vnext);
+ ClipSegment<2, -1>(&clippedvertices[1][c], &vtx, vnext);
c++;
}
}
else
clippedvertices[1][c++] = vtx;
-
- prev++; if (prev >= nverts) prev = 0;
- next++; if (next >= nverts) next = 0;
}
- if (c == 0) return;
+ if (c == 0)
+ {
+ LastStripPolygon = NULL;
+ return;
+ }
// build the actual polygon
- // TODO: tri/quad strips
- if (NumPolygons >= 2048) return;
- if (NumVertices+c > 6144) return;
+ if (NumPolygons >= 2048 || NumVertices+c > 6144)
+ {
+ LastStripPolygon = NULL;
+ return;
+ }
Polygon* poly = &CurPolygonRAM[NumPolygons++];
poly->NumVertices = 0;
- for (int i = 0; i < c; i++)
+ poly->Attr = CurPolygonAttr;
+ poly->FacingView = facingview;
+
+ if (LastStripPolygon && clipstart > 0)
+ {
+ if (c == lastpolyverts)
+ {
+ poly->Vertices[0] = reusedvertices[0];
+ poly->Vertices[1] = reusedvertices[1];
+ }
+ else
+ {
+ Vertex v0 = *reusedvertices[0];
+ Vertex v1 = *reusedvertices[1];
+
+ CurVertexRAM[NumVertices] = v0;
+ poly->Vertices[0] = &CurVertexRAM[NumVertices];
+ CurVertexRAM[NumVertices+1] = v1;
+ poly->Vertices[1] = &CurVertexRAM[NumVertices+1];
+ NumVertices += 2;
+ }
+
+ poly->NumVertices += 2;
+ }
+
+ for (int i = clipstart; i < c; i++)
{
CurVertexRAM[NumVertices] = clippedvertices[1][i];
poly->Vertices[i] = &CurVertexRAM[NumVertices];
@@ -616,77 +747,29 @@ void SubmitPolygon()
NumVertices++;
poly->NumVertices++;
}
+
+ if (PolygonMode >= 2)
+ LastStripPolygon = poly;
+ else
+ LastStripPolygon = NULL;
}
void SubmitVertex()
{
s64 vertex[4] = {(s64)CurVertex[0], (s64)CurVertex[1], (s64)CurVertex[2], 0x1000};
- //s32 vertextrans[4];
Vertex* vertextrans = &TempVertexBuffer[VertexNumInPoly];
- if (PolygonMode & 0x2) return;
-
- //printf("vertex: %f %f %f\n", vertex[0]/4096.0f, vertex[1]/4096.0f, vertex[2]/4096.0f);
-
UpdateClipMatrix();
vertextrans->Position[0] = (vertex[0]*ClipMatrix[0] + vertex[1]*ClipMatrix[4] + vertex[2]*ClipMatrix[8] + vertex[3]*ClipMatrix[12]) >> 12;
vertextrans->Position[1] = (vertex[0]*ClipMatrix[1] + vertex[1]*ClipMatrix[5] + vertex[2]*ClipMatrix[9] + vertex[3]*ClipMatrix[13]) >> 12;
vertextrans->Position[2] = (vertex[0]*ClipMatrix[2] + vertex[1]*ClipMatrix[6] + vertex[2]*ClipMatrix[10] + vertex[3]*ClipMatrix[14]) >> 12;
vertextrans->Position[3] = (vertex[0]*ClipMatrix[3] + vertex[1]*ClipMatrix[7] + vertex[2]*ClipMatrix[11] + vertex[3]*ClipMatrix[15]) >> 12;
- /*printf("vertex fart: %f %f %f %f\n",
- vertextrans->Position[0]/4096.0f,
- vertextrans->Position[1]/4096.0f,
- vertextrans->Position[2]/4096.0f,
- vertextrans->Position[3]/4096.0f);*/
-
- /*s32 w_inv;
- if (vertextrans->Position[3] == 0)
- w_inv = 0x1000; // checkme
- else if(vertextrans->Position[3] < 0)
- w_inv = 0x1000000 / -vertextrans->Position[3];
- else
- w_inv = 0x1000000 / vertextrans->Position[3];
-
- vertextrans->Position[0] = (vertextrans->Position[0] * w_inv) >> 12;
- vertextrans->Position[1] = (vertextrans->Position[1] * w_inv) >> 12;
- vertextrans->Position[2] = (vertextrans->Position[2] * w_inv) >> 12;*/
-
vertextrans->Color[0] = VertexColor[0];
vertextrans->Color[1] = VertexColor[1];
vertextrans->Color[2] = VertexColor[2];
- /*printf("vertex trans: %f %f %f %f\n",
- vertextrans->Position[0]/4096.0f,
- vertextrans->Position[1]/4096.0f,
- vertextrans->Position[2]/4096.0f,
- vertextrans->Position[3]/4096.0f);
- printf("clip: %f %f %f %f\n",
- ClipMatrix[3]/4096.0f,
- ClipMatrix[7]/4096.0f,
- ClipMatrix[11]/4096.0f,
- ClipMatrix[15]/4096.0f);*/
-
- /*if (vertextrans[3] == 0)
- {
- //printf("!!!! VERTEX W IS ZERO\n");
- //return;
- vertextrans[3] = 0x1000; // checkme
- }
-
- s32 screenX = (((vertextrans[0]+vertextrans[3]) * Viewport[2]) / (vertextrans[3]<<1)) + Viewport[0];
- s32 screenY = (((vertextrans[1]+vertextrans[3]) * Viewport[3]) / (vertextrans[3]<<1)) + Viewport[1];
-
- printf("screen: %d, %d\n", screenX, screenY);
-
- s32* finalvertex = TempVertexBuffer[VertexNumInPoly];
- finalvertex[0] = screenX;
- finalvertex[1] = screenY;
- finalvertex[2] = vertextrans[2];
- finalvertex[3] = vertextrans[3];*/
-
- // triangle strip: 0,1,2 1,2,3 2,3,4 3,4,5 ...
- // quad strip: 0,1,3,2 2,3,5,4 4,5,7,6 6,7,9,8 ...
+ vertextrans->Clipped = false;
VertexNum++;
VertexNumInPoly++;
@@ -698,6 +781,7 @@ void SubmitVertex()
{
VertexNumInPoly = 0;
SubmitPolygon();
+ NumConsecutivePolygons++;
}
break;
@@ -706,32 +790,49 @@ void SubmitVertex()
{
VertexNumInPoly = 0;
SubmitPolygon();
+ NumConsecutivePolygons++;
}
break;
- /*case 2: // triangle strip
- if (VertexNum > 3)
+ case 2: // triangle strip
+ if (NumConsecutivePolygons & 1)
{
- if (VertexNumInPoly == 1)
- {
- VertexNumInPoly = 0;
- // reorder
- }
- else
- VertexNumInPoly = 0;
+ Vertex tmp = TempVertexBuffer[1];
+ TempVertexBuffer[1] = TempVertexBuffer[0];
+ TempVertexBuffer[0] = tmp;
+ VertexNumInPoly = 2;
SubmitPolygon();
+ NumConsecutivePolygons++;
+
+ TempVertexBuffer[1] = TempVertexBuffer[2];
}
- else if (VertexNum == 3)
+ else if (VertexNumInPoly == 3)
{
VertexNumInPoly = 2;
SubmitPolygon();
+ NumConsecutivePolygons++;
TempVertexBuffer[0] = TempVertexBuffer[1];
TempVertexBuffer[1] = TempVertexBuffer[2];
}
- break;*/
- default: VertexNumInPoly = 0; break;
+ break;
+
+ case 3: // quad strip
+ if (VertexNumInPoly == 4)
+ {
+ Vertex tmp = TempVertexBuffer[3];
+ TempVertexBuffer[3] = TempVertexBuffer[2];
+ TempVertexBuffer[2] = tmp;
+
+ VertexNumInPoly = 2;
+ SubmitPolygon();
+ NumConsecutivePolygons++;
+
+ TempVertexBuffer[0] = TempVertexBuffer[3];
+ TempVertexBuffer[1] = TempVertexBuffer[2];
+ }
+ break;
}
}
@@ -791,7 +892,7 @@ void ExecuteCommand()
if (ExecParamCount >= CmdNumParams[entry.Command])
{
- //CycleCount += CmdNumCycles[entry.Command];
+ CycleCount += CmdNumCycles[entry.Command];
ExecParamCount = 0;
GXStat &= ~(1<<14);
@@ -1127,10 +1228,17 @@ void ExecuteCommand()
SubmitVertex();
break;
+ case 0x29: // polygon attributes
+ PolygonAttr = ExecParams[0];
+ break;
+
case 0x40:
PolygonMode = ExecParams[0] & 0x3;
VertexNum = 0;
VertexNumInPoly = 0;
+ NumConsecutivePolygons = 0;
+ LastStripPolygon = NULL;
+ CurPolygonAttr = PolygonAttr;
break;
case 0x50:
diff --git a/GPU3D.h b/GPU3D.h
index d9e7e1a..96e76aa 100644
--- a/GPU3D.h
+++ b/GPU3D.h
@@ -27,6 +27,8 @@ typedef struct
s32 Position[4];
u8 Color[3];
+ bool Clipped;
+
} Vertex;
typedef struct
@@ -34,6 +36,10 @@ typedef struct
Vertex* Vertices[10];
u32 NumVertices;
+ u32 Attr;
+
+ bool FacingView;
+
} Polygon;
extern s32 Viewport[4];
diff --git a/GPU3D_Soft.cpp b/GPU3D_Soft.cpp
index 6ac4e81..abca24a 100644
--- a/GPU3D_Soft.cpp
+++ b/GPU3D_Soft.cpp
@@ -60,23 +60,27 @@ void RenderPolygon(Polygon* polygon)
{
Vertex* vtx = polygon->Vertices[i];
- s32 w_inv;
- if (vtx->Position[3] == 0)
+ s32 posX, posY, posZ;
+ s32 w = vtx->Position[3];
+ if (w == 0)
{
- w_inv = 0x1000; // checkme
- printf("!! W=0\n");
+ posX = 0;
+ posY = 0;
+ posZ = 0;
}
else
- w_inv = 0x1000000 / vtx->Position[3];
-
- if (vtx->Position[3] < 0) printf("!!! W=%d\n", vtx->Position[3]);
-
- s32 posX = (vtx->Position[0] * w_inv) >> 12;
- s32 posY = (vtx->Position[1] * w_inv) >> 12;
- s32 posZ = (vtx->Position[2] * w_inv) >> 12;
+ {
+ // TODO: find a way to avoid doing 3 divisions :/
+ posX = ((s64)vtx->Position[0] << 12) / w;
+ posY = ((s64)vtx->Position[1] << 12) / w;
+ posZ = ((s64)vtx->Position[2] << 12) / w;
+ }
//s32 posX = vtx->Position[0];
//s32 posY = vtx->Position[1];
+ //printf("xy: %08X %08X %08X\n", vtx->Position[0], vtx->Position[1], vtx->Position[3]);
+ //printf("w_inv: %08X res: %08X %08X\n", w_inv, posX, posY);
+
s32 scrX = (((posX + 0x1000) * Viewport[2]) >> 13) + Viewport[0];
s32 scrY = (((posY + 0x1000) * Viewport[3]) >> 13) + Viewport[1];
s32 scrZ = (vtx->Position[2] + 0x1000) >> 1;
@@ -102,7 +106,8 @@ void RenderPolygon(Polygon* polygon)
vbot = i;
}
//if (vtx->Color[0]==63 && vtx->Color[1]==0 && vtx->Color[2]==0)
- //printf("v%d: %d,%d Z=%f W=%f\n", i, scrX, 191-scrY, vtx->Position[2]/4096.0f, vtx->Position[3]/4096.0f);
+ //printf("v%d: %d,%d Z=%f W=%f %d %d\n", i, scrX, 191-scrY, vtx->Position[2]/4096.0f, vtx->Position[3]/4096.0f,
+ // polygon->FacingView, vtx->Clipped);
}
// draw, line per line
@@ -112,10 +117,20 @@ void RenderPolygon(Polygon* polygon)
s32 lstep, rstep;
//s32 xmin, xmax;
- lnext = lcur + 1;
- if (lnext >= nverts) lnext = 0;
- rnext = rcur - 1;
- if (rnext < 0) rnext = nverts - 1;
+ if (polygon->FacingView)
+ {
+ lnext = lcur + 1;
+ if (lnext >= nverts) lnext = 0;
+ rnext = rcur - 1;
+ if (rnext < 0) rnext = nverts - 1;
+ }
+ else
+ {
+ lnext = lcur - 1;
+ if (lnext < 0) lnext = nverts - 1;
+ rnext = rcur + 1;
+ if (rnext >= nverts) rnext = 0;
+ }
/*if ((scrcoords[lnext][1] - scrcoords[lcur][1]) == 0) lstep = 0; else
lstep = ((scrcoords[lnext][0] - scrcoords[lcur][0]) << 12) / (scrcoords[lnext][1] - scrcoords[lcur][1]);
@@ -131,11 +146,18 @@ void RenderPolygon(Polygon* polygon)
{
while (y == scrcoords[lnext][1])
{
- lcur++;
- if (lcur >= nverts) lcur = 0;
-
- lnext = lcur + 1;
- if (lnext >= nverts) lnext = 0;
+ lcur = lnext;
+
+ if (polygon->FacingView)
+ {
+ lnext = lcur + 1;
+ if (lnext >= nverts) lnext = 0;
+ }
+ else
+ {
+ lnext = lcur - 1;
+ if (lnext < 0) lnext = nverts - 1;
+ }
//lstep = ((scrcoords[lnext][0] - scrcoords[lcur][0]) << 12) / (scrcoords[lnext][1] - scrcoords[lcur][1]);
//xmin = scrcoords[lcur][0] << 12;
@@ -144,11 +166,18 @@ void RenderPolygon(Polygon* polygon)
while (y == scrcoords[rnext][1])
{
- rcur--;
- if (rcur < 0) rcur = nverts - 1;
-
- rnext = rcur - 1;
- if (rnext < 0) rnext = nverts - 1;
+ rcur = rnext;
+
+ if (polygon->FacingView)
+ {
+ rnext = rcur - 1;
+ if (rnext < 0) rnext = nverts - 1;
+ }
+ else
+ {
+ rnext = rcur + 1;
+ if (rnext >= nverts) rnext = 0;
+ }
//rstep = ((scrcoords[rnext][0] - scrcoords[rcur][0]) << 12) / (scrcoords[rnext][1] - scrcoords[rcur][1]);
//xmax = scrcoords[rcur][0] << 12;
@@ -232,6 +261,19 @@ void RenderPolygon(Polygon* polygon)
pixel[2] = zerp;*/
}
}
+
+ // DEBUG CODE
+ /*for (int i = 0; i < nverts; i++)
+ {
+ s32 x = scrcoords[i][0];
+ s32 y = scrcoords[i][1];
+
+ u8* pixel = &ColorBuffer[((256*y) + x) * 4];
+ pixel[0] = 63;
+ pixel[1] = 63;
+ pixel[2] = 63;
+ pixel[3] = 31;
+ }*/
}
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
@@ -254,6 +296,8 @@ void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
polygons[i].Vertices[j]->Position[2]/4096.0f);
*/
//printf("polygon %d\n", i);
+ //if (!polygons[i].Vertices[0]->Clipped) continue;
+ //printf("polygon %d\n", i);
RenderPolygon(&polygons[i]);
}
}
diff --git a/NDS.cpp b/NDS.cpp
index 68ca25c..8b911d3 100644
--- a/NDS.cpp
+++ b/NDS.cpp
@@ -307,7 +307,7 @@ void Reset()
// test
//LoadROM();
//LoadFirmware();
- if (NDSCart::LoadROM("rom/Simple_Tri.nds"))
+ if (NDSCart::LoadROM("rom/nsmb.nds"))
Running = true; // hax
}
diff --git a/main.cpp b/main.cpp
index 7600102..c403cec 100644
--- a/main.cpp
+++ b/main.cpp
@@ -85,6 +85,8 @@ LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
case VK_RIGHT: NDS::PressKey(4); break;
case 'A': NDS::PressKey(0); break;
case 'B': NDS::PressKey(1); break;
+ case 'X': NDS::PressKey(16); break;
+ case 'Y': NDS::PressKey(17); break;
case 'L': NDS::PressKey(9); break;
case 'R': NDS::PressKey(8); break;
case 'D': NDS::debug(0); break;
@@ -102,6 +104,8 @@ LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
case VK_RIGHT: NDS::ReleaseKey(4); break;
case 'A': NDS::ReleaseKey(0); break;
case 'B': NDS::ReleaseKey(1); break;
+ case 'X': NDS::ReleaseKey(16); break;
+ case 'Y': NDS::ReleaseKey(17); break;
case 'L': NDS::ReleaseKey(9); break;
case 'R': NDS::ReleaseKey(8); break;
}
diff --git a/melonDS.depend b/melonDS.depend
index 51e832c..35030a5 100644
--- a/melonDS.depend
+++ b/melonDS.depend
@@ -1,5 +1,5 @@
# depslib dependency file v1.0
-1486993536 source:c:\documents\sources\melonds\main.cpp
+1487028720 source:c:\documents\sources\melonds\main.cpp
<stdio.h>
<windows.h>
"NDS.h"
@@ -10,7 +10,7 @@
1481161027 c:\documents\sources\melonds\types.h
-1486994139 source:c:\documents\sources\melonds\nds.cpp
+1487033652 source:c:\documents\sources\melonds\nds.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -146,16 +146,16 @@
"NDS.h"
"NDSCart.h"
-1486777933 c:\documents\sources\melonds\gpu3d.h
+1487016725 c:\documents\sources\melonds\gpu3d.h
-1486993935 source:c:\documents\sources\melonds\gpu3d.cpp
+1487036430 source:c:\documents\sources\melonds\gpu3d.cpp
<stdio.h>
<string.h>
"NDS.h"
"GPU.h"
"FIFO.h"
-1486994049 source:c:\documents\sources\melonds\gpu3d_soft.cpp
+1487035597 source:c:\documents\sources\melonds\gpu3d_soft.cpp
<stdio.h>
<string.h>
"NDS.h"