aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-05-03 01:21:39 +0200
committerStapleButter <thetotalworm@gmail.com>2017-05-03 01:21:39 +0200
commit9e622dcc66481350f240c5495f680613b7c98fa6 (patch)
treed37d8911af92393e0a59cef1a1010818e8220dc7
parentce240f42165c623c7c289787916dc148b0300f8a (diff)
3D: attempt at fixing culling. players in Madden are no longer full of holes, and that also fixes occasional missing polygons in RaymanDS, and probably others.
-rw-r--r--src/GPU3D.cpp19
-rw-r--r--src/Wifi.cpp2
2 files changed, 18 insertions, 3 deletions
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index 72e7179..906b04b 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -610,6 +610,8 @@ void SubmitPolygon()
int prev, next;
// culling
+ // TODO: work out how it works on the real thing
+ // the normalization part is a wild guess
Vertex *v0, *v1, *v2;
s64 normalX, normalY, normalZ;
@@ -618,9 +620,19 @@ void SubmitPolygon()
v0 = &TempVertexBuffer[0];
v1 = &TempVertexBuffer[1];
v2 = &TempVertexBuffer[2];
- normalX = (((s64)v0->Position[1] * v2->Position[3]) - ((s64)v0->Position[3] * v2->Position[1])) >> 12;
- normalY = (((s64)v0->Position[3] * v2->Position[0]) - ((s64)v0->Position[0] * v2->Position[3])) >> 12;
- normalZ = (((s64)v0->Position[0] * v2->Position[1]) - ((s64)v0->Position[1] * v2->Position[0])) >> 12;
+ normalX = ((s64)v0->Position[1] * v2->Position[3]) - ((s64)v0->Position[3] * v2->Position[1]);
+ normalY = ((s64)v0->Position[3] * v2->Position[0]) - ((s64)v0->Position[0] * v2->Position[3]);
+ normalZ = ((s64)v0->Position[0] * v2->Position[1]) - ((s64)v0->Position[1] * v2->Position[0]);
+
+ while ((((normalX>>31) ^ (normalX>>63)) != 0) ||
+ (((normalY>>31) ^ (normalY>>63)) != 0) ||
+ (((normalZ>>31) ^ (normalZ>>63)) != 0))
+ {
+ normalX >>= 4;
+ normalY >>= 4;
+ normalZ >>= 4;
+ }
+
dot = ((s64)v1->Position[0] * normalX) + ((s64)v1->Position[1] * normalY) + ((s64)v1->Position[3] * normalZ);
bool facingview = (dot < 0);
@@ -807,6 +819,7 @@ void SubmitPolygon()
// determine bounds of the polygon
// also determine the W shift and normalize W
// TODO: normalization works both ways
+ // (ie two W's that span 12 bits or less will be brought to 16 bits)
u32 vtop = 0, vbot = 0;
s32 ytop = 192, ybot = 0;
diff --git a/src/Wifi.cpp b/src/Wifi.cpp
index a6a5d55..37039c5 100644
--- a/src/Wifi.cpp
+++ b/src/Wifi.cpp
@@ -124,6 +124,8 @@ void SetIRQ14(bool forced)
if (!forced)
IOPORT(W_BeaconCount1) = IOPORT(W_BeaconInterval);
+ else
+ printf("wifi: weird forced IRQ14\n");
IOPORT(W_BeaconCount2) = 0xFFFF;
IOPORT(W_TXReqRead) &= 0xFFF2; // todo, eventually?