aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GPU3D.cpp155
1 files changed, 152 insertions, 3 deletions
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index 92b7c5d..41baf34 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -215,6 +215,9 @@ u32 CurPolygonAttr;
u32 TexParam;
u32 TexPalette;
+s32 PosTestResult[4];
+s16 VecTestResult[3];
+
Vertex TempVertexBuffer[4];
u32 VertexNum;
u32 VertexNumInPoly;
@@ -301,6 +304,9 @@ void Reset()
PosMatrixStackPointer = 0;
TexMatrixStackPointer = 0;
+ memset(PosTestResult, 0, 4*4);
+ memset(VecTestResult, 0, 2*3);
+
VertexNum = 0;
VertexNumInPoly = 0;
@@ -551,6 +557,7 @@ int ClipAgainstPlane(Vertex* vertices, int nverts, int clipstart)
vertices[c++] = vtx;
}
+ // checkme
for (int i = 0; i < c; i++)
{
Vertex* vtx = &vertices[i];
@@ -908,6 +915,8 @@ void SubmitVertex()
s32 CalculateLighting()
{
+ // TODO: this requires matrix mode 2, apparently
+
if ((TexParam >> 30) == 2)
{
TexCoords[0] = RawTexCoords[0] + (((s64)Normal[0]*TexMatrix[0] + (s64)Normal[1]*TexMatrix[4] + (s64)Normal[2]*TexMatrix[8]) >> 21);
@@ -974,6 +983,134 @@ s32 CalculateLighting()
}
+void BoxTest(u32* params)
+{
+ Vertex cube[8];
+ Vertex face[10];
+ int res;
+
+ GXStat &= ~(1<<1);
+
+ s32 x0 = (s32)(s16)(params[0] & 0xFFFF);
+ s32 y0 = ((s32)params[0]) >> 16;
+ s32 z0 = (s32)(s16)(params[1] & 0xFFFF);
+ s32 x1 = ((s32)params[1]) >> 16;
+ s32 y1 = (s32)(s16)(params[2] & 0xFFFF);
+ s32 z1 = ((s32)params[2]) >> 16;
+
+ x1 += x0;
+ y1 += y0;
+ z1 += z0;
+
+ cube[0].Position[0] = x0; cube[0].Position[1] = y0; cube[0].Position[2] = z0;
+ cube[1].Position[0] = x1; cube[1].Position[1] = y0; cube[1].Position[2] = z0;
+ cube[2].Position[0] = x1; cube[2].Position[1] = y1; cube[2].Position[2] = z0;
+ cube[3].Position[0] = x0; cube[3].Position[1] = y1; cube[3].Position[2] = z0;
+ cube[4].Position[0] = x0; cube[4].Position[1] = y1; cube[4].Position[2] = z1;
+ cube[5].Position[0] = x0; cube[5].Position[1] = y0; cube[5].Position[2] = z1;
+ cube[6].Position[0] = x1; cube[6].Position[1] = y0; cube[6].Position[2] = z1;
+ cube[7].Position[0] = x1; cube[7].Position[1] = y1; cube[7].Position[2] = z1;
+
+ UpdateClipMatrix();
+ for (int i = 0; i < 8; i++)
+ {
+ s32 x = cube[i].Position[0];
+ s32 y = cube[i].Position[1];
+ s32 z = cube[i].Position[2];
+
+ cube[i].Position[0] = ((s64)x*ClipMatrix[0] + (s64)y*ClipMatrix[4] + (s64)z*ClipMatrix[8] + 0x1000*ClipMatrix[12]) >> 12;
+ cube[i].Position[1] = ((s64)x*ClipMatrix[1] + (s64)y*ClipMatrix[5] + (s64)z*ClipMatrix[9] + 0x1000*ClipMatrix[13]) >> 12;
+ cube[i].Position[2] = ((s64)x*ClipMatrix[2] + (s64)y*ClipMatrix[6] + (s64)z*ClipMatrix[10] + 0x1000*ClipMatrix[14]) >> 12;
+ cube[i].Position[3] = ((s64)x*ClipMatrix[3] + (s64)y*ClipMatrix[7] + (s64)z*ClipMatrix[11] + 0x1000*ClipMatrix[15]) >> 12;
+ }
+
+ // front face (-Z)
+ face[0] = cube[0]; face[1] = cube[1]; face[2] = cube[2]; face[3] = cube[3];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+
+ // back face (+Z)
+ face[0] = cube[4]; face[1] = cube[5]; face[2] = cube[6]; face[3] = cube[7];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+
+ // left face (-X)
+ face[0] = cube[0]; face[1] = cube[3]; face[2] = cube[4]; face[3] = cube[5];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+
+ // right face (+X)
+ face[0] = cube[1]; face[1] = cube[2]; face[2] = cube[7]; face[3] = cube[6];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+
+ // bottom face (-Y)
+ face[0] = cube[0]; face[1] = cube[1]; face[2] = cube[6]; face[3] = cube[5];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+
+ // top face (+Y)
+ face[0] = cube[2]; face[1] = cube[3]; face[2] = cube[4]; face[3] = cube[7];
+ res = ClipPolygon<false>(face, 4, 0);
+ if (res > 0)
+ {
+ GXStat |= (1<<1);
+ return;
+ }
+}
+
+void PosTest()
+{
+ s64 vertex[4] = {(s64)CurVertex[0], (s64)CurVertex[1], (s64)CurVertex[2], 0x1000};
+
+ UpdateClipMatrix();
+ PosTestResult[0] = (vertex[0]*ClipMatrix[0] + vertex[1]*ClipMatrix[4] + vertex[2]*ClipMatrix[8] + vertex[3]*ClipMatrix[12]) >> 12;
+ PosTestResult[1] = (vertex[0]*ClipMatrix[1] + vertex[1]*ClipMatrix[5] + vertex[2]*ClipMatrix[9] + vertex[3]*ClipMatrix[13]) >> 12;
+ PosTestResult[2] = (vertex[0]*ClipMatrix[2] + vertex[1]*ClipMatrix[6] + vertex[2]*ClipMatrix[10] + vertex[3]*ClipMatrix[14]) >> 12;
+ PosTestResult[3] = (vertex[0]*ClipMatrix[3] + vertex[1]*ClipMatrix[7] + vertex[2]*ClipMatrix[11] + vertex[3]*ClipMatrix[15]) >> 12;
+}
+
+void VecTest(u32* params)
+{
+ // TODO: apparently requires matrix mode 2
+ // TODO: maybe it overwrites the normal registers, too
+
+ s16 normal[3];
+
+ normal[0] = (s16)((params[0] & 0x000003FF) << 6) >> 6;
+ normal[1] = (s16)((params[0] & 0x000FFC00) >> 4) >> 6;
+ normal[2] = (s16)((params[0] & 0x3FF00000) >> 14) >> 6;
+
+ VecTestResult[0] = (normal[0]*VecMatrix[0] + normal[1]*VecMatrix[4] + normal[2]*VecMatrix[8]) >> 9;
+ VecTestResult[1] = (normal[0]*VecMatrix[1] + normal[1]*VecMatrix[5] + normal[2]*VecMatrix[9]) >> 9;
+ VecTestResult[2] = (normal[0]*VecMatrix[2] + normal[1]*VecMatrix[6] + normal[2]*VecMatrix[10]) >> 9;
+
+ if (VecTestResult[0] & 0x1000) VecTestResult[0] |= 0xF000;
+ if (VecTestResult[1] & 0x1000) VecTestResult[1] |= 0xF000;
+ if (VecTestResult[2] & 0x1000) VecTestResult[2] |= 0xF000;
+}
+
+
void CmdFIFOWrite(CmdFIFOEntry& entry)
{
@@ -1505,17 +1642,20 @@ void ExecuteCommand()
case 0x70: // box test
NumTestCommands -= 3;
- // TODO
+ BoxTest(ExecParams);
break;
case 0x71: // pos test
NumTestCommands -= 2;
- //
+ CurVertex[0] = ExecParams[0] & 0xFFFF;
+ CurVertex[1] = ExecParams[0] >> 16;
+ CurVertex[2] = ExecParams[1] & 0xFFFF;
+ PosTest();
break;
case 0x72: // vec test
NumTestCommands--;
- //
+ VecTest(ExecParams);
break;
default:
@@ -1636,6 +1776,10 @@ u16 Read16(u32 addr)
return NumPolygons;
case 0x04000606:
return NumVertices;
+
+ case 0x04000630: return VecTestResult[0];
+ case 0x04000632: return VecTestResult[1];
+ case 0x04000634: return VecTestResult[2];
}
printf("unknown GPU3D read16 %08X\n", addr);
@@ -1667,6 +1811,11 @@ u32 Read32(u32 addr)
case 0x04000604:
return NumPolygons | (NumVertices << 16);
+ case 0x04000620: return PosTestResult[0];
+ case 0x04000624: return PosTestResult[1];
+ case 0x04000628: return PosTestResult[2];
+ case 0x0400062C: return PosTestResult[3];
+
case 0x04000680: return VecMatrix[0];
case 0x04000684: return VecMatrix[1];
case 0x04000688: return VecMatrix[2];