mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
* more accurate flags (push/pop busy, test busy, vertex/poly overflow)
* more versatile and better clipping code
This commit is contained in:
@ -32,6 +32,8 @@
|
|||||||
// * VRAM/FIFO display modes convert colors the same way
|
// * VRAM/FIFO display modes convert colors the same way
|
||||||
// * 3D engine converts colors differently (18bit = 15bit * 2 + 1, except 0 = 0)
|
// * 3D engine converts colors differently (18bit = 15bit * 2 + 1, except 0 = 0)
|
||||||
// * 'screen disabled' white is 63,63,63
|
// * 'screen disabled' white is 63,63,63
|
||||||
|
// * [Gericom] bit15 is used as bottom green bit for palettes. TODO: check where this applies.
|
||||||
|
// tested on the normal BG palette and applies there
|
||||||
//
|
//
|
||||||
// oh also, changing DISPCNT bit16-17 midframe doesn't work (ignored? applied for next frame?)
|
// oh also, changing DISPCNT bit16-17 midframe doesn't work (ignored? applied for next frame?)
|
||||||
// TODO, eventually: check whether other DISPCNT bits can be changed midframe
|
// TODO, eventually: check whether other DISPCNT bits can be changed midframe
|
||||||
@ -68,6 +70,9 @@
|
|||||||
// * if BG0 is selected as 1st target, destination not selected as 2nd target:
|
// * if BG0 is selected as 1st target, destination not selected as 2nd target:
|
||||||
// brightness up/down effect is applied if selected. if blending is selected, it doesn't apply.
|
// brightness up/down effect is applied if selected. if blending is selected, it doesn't apply.
|
||||||
// * 3D layer pixels with alpha=0 are always transparent.
|
// * 3D layer pixels with alpha=0 are always transparent.
|
||||||
|
//
|
||||||
|
// mosaic:
|
||||||
|
// * mosaic grid starts at 0,0 regardless of the BG/sprite position
|
||||||
|
|
||||||
|
|
||||||
GPU2D::GPU2D(u32 num)
|
GPU2D::GPU2D(u32 num)
|
||||||
|
416
src/GPU3D.cpp
416
src/GPU3D.cpp
@ -164,6 +164,9 @@ u32 ExecParams[32];
|
|||||||
u32 ExecParamCount;
|
u32 ExecParamCount;
|
||||||
s32 CycleCount;
|
s32 CycleCount;
|
||||||
|
|
||||||
|
u32 NumPushPopCommands;
|
||||||
|
u32 NumTestCommands;
|
||||||
|
|
||||||
|
|
||||||
u32 MatrixMode;
|
u32 MatrixMode;
|
||||||
|
|
||||||
@ -265,6 +268,9 @@ void Reset()
|
|||||||
ParamCount = 0;
|
ParamCount = 0;
|
||||||
TotalParams = 0;
|
TotalParams = 0;
|
||||||
|
|
||||||
|
NumPushPopCommands = 0;
|
||||||
|
NumTestCommands = 0;
|
||||||
|
|
||||||
DispCnt = 0;
|
DispCnt = 0;
|
||||||
AlphaRef = 0;
|
AlphaRef = 0;
|
||||||
|
|
||||||
@ -448,44 +454,147 @@ void UpdateClipMatrix()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<int comp, s32 plane>
|
template<int comp, s32 plane, bool attribs>
|
||||||
void ClipSegment(Vertex* outbuf, Vertex* vout, Vertex* vin)
|
void ClipSegment(Vertex* outbuf, Vertex* vout, Vertex* vin)
|
||||||
{
|
{
|
||||||
s64 factor_num = vin->Position[3] - (plane*vin->Position[comp]);
|
s64 factor_num = vin->Position[3] - (plane*vin->Position[comp]);
|
||||||
s32 factor_den = factor_num - (vout->Position[3] - (plane*vout->Position[comp]));
|
s32 factor_den = factor_num - (vout->Position[3] - (plane*vout->Position[comp]));
|
||||||
|
|
||||||
Vertex mid;
|
#define INTERPOLATE(var) { outbuf->var = (vin->var + ((vout->var - vin->var) * factor_num) / factor_den); }
|
||||||
#define INTERPOLATE(var) { mid.var = (vin->var + ((vout->var - vin->var) * factor_num) / factor_den); }
|
|
||||||
|
|
||||||
if (comp != 0) INTERPOLATE(Position[0]);
|
if (comp != 0) INTERPOLATE(Position[0]);
|
||||||
if (comp != 1) INTERPOLATE(Position[1]);
|
if (comp != 1) INTERPOLATE(Position[1]);
|
||||||
if (comp != 2) INTERPOLATE(Position[2]);
|
if (comp != 2) INTERPOLATE(Position[2]);
|
||||||
INTERPOLATE(Position[3]);
|
INTERPOLATE(Position[3]);
|
||||||
mid.Position[comp] = plane*mid.Position[3];
|
outbuf->Position[comp] = plane*outbuf->Position[3];
|
||||||
|
|
||||||
INTERPOLATE(Color[0]);
|
if (attribs)
|
||||||
INTERPOLATE(Color[1]);
|
{
|
||||||
INTERPOLATE(Color[2]);
|
INTERPOLATE(Color[0]);
|
||||||
|
INTERPOLATE(Color[1]);
|
||||||
|
INTERPOLATE(Color[2]);
|
||||||
|
|
||||||
INTERPOLATE(TexCoords[0]);
|
INTERPOLATE(TexCoords[0]);
|
||||||
INTERPOLATE(TexCoords[1]);
|
INTERPOLATE(TexCoords[1]);
|
||||||
|
}
|
||||||
|
|
||||||
mid.Clipped = true;
|
outbuf->Clipped = true;
|
||||||
|
|
||||||
#undef INTERPOLATE
|
#undef INTERPOLATE
|
||||||
*outbuf = mid;
|
}
|
||||||
|
|
||||||
|
template<int comp, bool attribs>
|
||||||
|
int ClipAgainstPlane(Vertex* vertices, int nverts, int clipstart)
|
||||||
|
{
|
||||||
|
Vertex temp[10];
|
||||||
|
int prev, next;
|
||||||
|
int c = clipstart;
|
||||||
|
|
||||||
|
if (clipstart == 2)
|
||||||
|
{
|
||||||
|
temp[0] = vertices[0];
|
||||||
|
temp[1] = vertices[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = vertices[i];
|
||||||
|
if (vtx.Position[comp] > vtx.Position[3])
|
||||||
|
{
|
||||||
|
if ((comp == 2) && (!(CurPolygonAttr & (1<<12)))) return 0;
|
||||||
|
|
||||||
|
Vertex* vprev = &vertices[prev];
|
||||||
|
if (vprev->Position[comp] <= vprev->Position[3])
|
||||||
|
{
|
||||||
|
ClipSegment<comp, 1, attribs>(&temp[c], &vtx, vprev);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex* vnext = &vertices[next];
|
||||||
|
if (vnext->Position[comp] <= vnext->Position[3])
|
||||||
|
{
|
||||||
|
ClipSegment<comp, 1, attribs>(&temp[c], &vtx, vnext);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
temp[c++] = vtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = temp[i];
|
||||||
|
if (vtx.Position[comp] < -vtx.Position[3])
|
||||||
|
{
|
||||||
|
Vertex* vprev = &temp[prev];
|
||||||
|
if (vprev->Position[comp] >= -vprev->Position[3])
|
||||||
|
{
|
||||||
|
ClipSegment<comp, -1, attribs>(&vertices[c], &vtx, vprev);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex* vnext = &temp[next];
|
||||||
|
if (vnext->Position[comp] >= -vnext->Position[3])
|
||||||
|
{
|
||||||
|
ClipSegment<comp, -1, attribs>(&vertices[c], &vtx, vnext);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vertices[c++] = vtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < c; i++)
|
||||||
|
{
|
||||||
|
Vertex* vtx = &vertices[i];
|
||||||
|
|
||||||
|
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
||||||
|
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
||||||
|
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool attribs>
|
||||||
|
int ClipPolygon(Vertex* vertices, int nverts, int clipstart)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// TODO: check for 1-dot polygons
|
||||||
|
// TODO: the hardware seems to use a different algorithm. it reacts differently to vertices with W=0
|
||||||
|
|
||||||
|
// X clipping
|
||||||
|
nverts = ClipAgainstPlane<0, attribs>(vertices, nverts, clipstart);
|
||||||
|
|
||||||
|
// Y clipping
|
||||||
|
nverts = ClipAgainstPlane<1, attribs>(vertices, nverts, clipstart);
|
||||||
|
|
||||||
|
// Z clipping
|
||||||
|
nverts = ClipAgainstPlane<2, attribs>(vertices, nverts, clipstart);
|
||||||
|
|
||||||
|
return nverts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubmitPolygon()
|
void SubmitPolygon()
|
||||||
{
|
{
|
||||||
Vertex clippedvertices[2][10];
|
Vertex clippedvertices[10];
|
||||||
Vertex* reusedvertices[2];
|
Vertex* reusedvertices[2];
|
||||||
int clipstart = 0;
|
int clipstart = 0;
|
||||||
int lastpolyverts = 0;
|
int lastpolyverts = 0;
|
||||||
|
|
||||||
int nverts = PolygonMode & 0x1 ? 4:3;
|
int nverts = PolygonMode & 0x1 ? 4:3;
|
||||||
int prev, next;
|
int prev, next;
|
||||||
int c;
|
|
||||||
|
|
||||||
// culling
|
// culling
|
||||||
|
|
||||||
@ -557,225 +666,21 @@ void SubmitPolygon()
|
|||||||
reusedvertices[0] = LastStripPolygon->Vertices[id0];
|
reusedvertices[0] = LastStripPolygon->Vertices[id0];
|
||||||
reusedvertices[1] = LastStripPolygon->Vertices[id1];
|
reusedvertices[1] = LastStripPolygon->Vertices[id1];
|
||||||
|
|
||||||
clippedvertices[0][0] = *reusedvertices[0];
|
clippedvertices[0] = *reusedvertices[0];
|
||||||
clippedvertices[0][1] = *reusedvertices[1];
|
clippedvertices[1] = *reusedvertices[1];
|
||||||
clippedvertices[1][0] = *reusedvertices[0];
|
|
||||||
clippedvertices[1][1] = *reusedvertices[1];
|
|
||||||
|
|
||||||
clipstart = 2;
|
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
|
|
||||||
|
|
||||||
c = clipstart;
|
|
||||||
for (int i = clipstart; i < nverts; i++)
|
for (int i = clipstart; i < nverts; i++)
|
||||||
{
|
clippedvertices[i] = TempVertexBuffer[i];
|
||||||
prev = i-1; if (prev < 0) prev = nverts-1;
|
|
||||||
next = i+1; if (next >= nverts) next = 0;
|
|
||||||
|
|
||||||
Vertex vtx = TempVertexBuffer[i];
|
// clipping
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex* vnext = &TempVertexBuffer[next];
|
nverts = ClipPolygon<true>(clippedvertices, nverts, clipstart);
|
||||||
if (vnext->Position[0] <= vnext->Position[3])
|
|
||||||
{
|
|
||||||
ClipSegment<0, 1>(&clippedvertices[0][c], &vtx, vnext);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[0][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
nverts = c; c = clipstart;
|
if (nverts == 0)
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex* vnext = &clippedvertices[0][next];
|
|
||||||
if (vnext->Position[0] >= -vnext->Position[3])
|
|
||||||
{
|
|
||||||
ClipSegment<0, -1>(&clippedvertices[1][c], &vtx, vnext);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[1][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < c; i++)
|
|
||||||
{
|
|
||||||
Vertex* vtx = &clippedvertices[1][i];
|
|
||||||
|
|
||||||
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
|
||||||
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
|
||||||
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Y clipping
|
|
||||||
|
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex* vnext = &clippedvertices[1][next];
|
|
||||||
if (vnext->Position[1] <= vnext->Position[3])
|
|
||||||
{
|
|
||||||
ClipSegment<1, 1>(&clippedvertices[0][c], &vtx, vnext);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[0][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex* vnext = &clippedvertices[0][next];
|
|
||||||
if (vnext->Position[1] >= -vnext->Position[3])
|
|
||||||
{
|
|
||||||
ClipSegment<1, -1>(&clippedvertices[1][c], &vtx, vnext);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[1][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < c; i++)
|
|
||||||
{
|
|
||||||
Vertex* vtx = &clippedvertices[1][i];
|
|
||||||
|
|
||||||
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
|
||||||
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
|
||||||
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Z clipping
|
|
||||||
|
|
||||||
bool farplaneclip = false;
|
|
||||||
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])
|
|
||||||
{
|
|
||||||
farplaneclip = true;
|
|
||||||
|
|
||||||
Vertex* vprev = &clippedvertices[1][prev];
|
|
||||||
if (vprev->Position[2] <= vprev->Position[3])
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[0][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (farplaneclip && (!(CurPolygonAttr & (1<<12))))
|
|
||||||
{
|
|
||||||
LastStripPolygon = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertex* vnext = &clippedvertices[0][next];
|
|
||||||
if (vnext->Position[2] >= -vnext->Position[3])
|
|
||||||
{
|
|
||||||
ClipSegment<2, -1>(&clippedvertices[1][c], &vtx, vnext);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clippedvertices[1][c++] = vtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < c; i++)
|
|
||||||
{
|
|
||||||
Vertex* vtx = &clippedvertices[1][i];
|
|
||||||
|
|
||||||
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
|
||||||
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
|
||||||
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == 0)
|
|
||||||
{
|
{
|
||||||
LastStripPolygon = NULL;
|
LastStripPolygon = NULL;
|
||||||
return;
|
return;
|
||||||
@ -783,10 +688,10 @@ void SubmitPolygon()
|
|||||||
|
|
||||||
// build the actual polygon
|
// build the actual polygon
|
||||||
|
|
||||||
if (NumPolygons >= 2048 || NumVertices+c > 6144)
|
if (NumPolygons >= 2048 || NumVertices+nverts > 6144)
|
||||||
{
|
{
|
||||||
LastStripPolygon = NULL;
|
LastStripPolygon = NULL;
|
||||||
// TODO: set DISP3DCNT overflow flag
|
DispCnt |= (1<<13);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,7 +710,7 @@ void SubmitPolygon()
|
|||||||
|
|
||||||
if (LastStripPolygon && clipstart > 0)
|
if (LastStripPolygon && clipstart > 0)
|
||||||
{
|
{
|
||||||
if (c == lastpolyverts)
|
if (nverts == lastpolyverts)
|
||||||
{
|
{
|
||||||
poly->Vertices[0] = reusedvertices[0];
|
poly->Vertices[0] = reusedvertices[0];
|
||||||
poly->Vertices[1] = reusedvertices[1];
|
poly->Vertices[1] = reusedvertices[1];
|
||||||
@ -825,10 +730,10 @@ void SubmitPolygon()
|
|||||||
poly->NumVertices += 2;
|
poly->NumVertices += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = clipstart; i < c; i++)
|
for (int i = clipstart; i < nverts; i++)
|
||||||
{
|
{
|
||||||
Vertex* vtx = &CurVertexRAM[NumVertices];
|
Vertex* vtx = &CurVertexRAM[NumVertices];
|
||||||
*vtx = clippedvertices[1][i];
|
*vtx = clippedvertices[i];
|
||||||
poly->Vertices[i] = vtx;
|
poly->Vertices[i] = vtx;
|
||||||
|
|
||||||
NumVertices++;
|
NumVertices++;
|
||||||
@ -878,7 +783,7 @@ void SubmitPolygon()
|
|||||||
s32 ytop = 192, ybot = 0;
|
s32 ytop = 192, ybot = 0;
|
||||||
s32 xtop = 256, xbot = 0;
|
s32 xtop = 256, xbot = 0;
|
||||||
|
|
||||||
for (int i = 0; i < c; i++)
|
for (int i = 0; i < nverts; i++)
|
||||||
{
|
{
|
||||||
Vertex* vtx = poly->Vertices[i];
|
Vertex* vtx = poly->Vertices[i];
|
||||||
|
|
||||||
@ -1095,6 +1000,17 @@ void CmdFIFOWrite(CmdFIFOEntry& entry)
|
|||||||
|
|
||||||
CmdFIFO->Write(entry);
|
CmdFIFO->Write(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entry.Command == 0x11 || entry.Command == 0x12)
|
||||||
|
{
|
||||||
|
GXStat |= (1<<14); // push/pop matrix
|
||||||
|
NumPushPopCommands++;
|
||||||
|
}
|
||||||
|
else if (entry.Command == 0x70 || entry.Command == 0x71 || entry.Command == 0x72)
|
||||||
|
{
|
||||||
|
GXStat |= (1<<0); // box/pos/vec test
|
||||||
|
NumTestCommands++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdFIFOEntry CmdFIFORead()
|
CmdFIFOEntry CmdFIFORead()
|
||||||
@ -1131,7 +1047,6 @@ void ExecuteCommand()
|
|||||||
CycleCount += CmdNumCycles[entry.Command];
|
CycleCount += CmdNumCycles[entry.Command];
|
||||||
ExecParamCount = 0;
|
ExecParamCount = 0;
|
||||||
|
|
||||||
GXStat &= ~(1<<14);
|
|
||||||
if (CycleCount > 0)
|
if (CycleCount > 0)
|
||||||
GXStat |= (1<<27);
|
GXStat |= (1<<27);
|
||||||
|
|
||||||
@ -1142,6 +1057,7 @@ void ExecuteCommand()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x11: // push matrix
|
case 0x11: // push matrix
|
||||||
|
NumPushPopCommands--;
|
||||||
if (MatrixMode == 0)
|
if (MatrixMode == 0)
|
||||||
{
|
{
|
||||||
if (ProjMatrixStackPointer > 0)
|
if (ProjMatrixStackPointer > 0)
|
||||||
@ -1153,7 +1069,6 @@ void ExecuteCommand()
|
|||||||
|
|
||||||
memcpy(ProjMatrixStack, ProjMatrix, 16*4);
|
memcpy(ProjMatrixStack, ProjMatrix, 16*4);
|
||||||
ProjMatrixStackPointer++;
|
ProjMatrixStackPointer++;
|
||||||
GXStat |= (1<<14);
|
|
||||||
}
|
}
|
||||||
else if (MatrixMode == 3)
|
else if (MatrixMode == 3)
|
||||||
{
|
{
|
||||||
@ -1166,7 +1081,6 @@ void ExecuteCommand()
|
|||||||
|
|
||||||
memcpy(TexMatrixStack, TexMatrix, 16*4);
|
memcpy(TexMatrixStack, TexMatrix, 16*4);
|
||||||
TexMatrixStackPointer++;
|
TexMatrixStackPointer++;
|
||||||
GXStat |= (1<<14);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1180,11 +1094,11 @@ void ExecuteCommand()
|
|||||||
memcpy(PosMatrixStack[PosMatrixStackPointer], PosMatrix, 16*4);
|
memcpy(PosMatrixStack[PosMatrixStackPointer], PosMatrix, 16*4);
|
||||||
memcpy(VecMatrixStack[PosMatrixStackPointer], VecMatrix, 16*4);
|
memcpy(VecMatrixStack[PosMatrixStackPointer], VecMatrix, 16*4);
|
||||||
PosMatrixStackPointer++;
|
PosMatrixStackPointer++;
|
||||||
GXStat |= (1<<14);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x12: // pop matrix
|
case 0x12: // pop matrix
|
||||||
|
NumPushPopCommands--;
|
||||||
if (MatrixMode == 0)
|
if (MatrixMode == 0)
|
||||||
{
|
{
|
||||||
if (ProjMatrixStackPointer <= 0)
|
if (ProjMatrixStackPointer <= 0)
|
||||||
@ -1196,7 +1110,6 @@ void ExecuteCommand()
|
|||||||
|
|
||||||
ProjMatrixStackPointer--;
|
ProjMatrixStackPointer--;
|
||||||
memcpy(ProjMatrix, ProjMatrixStack, 16*4);
|
memcpy(ProjMatrix, ProjMatrixStack, 16*4);
|
||||||
GXStat |= (1<<14);
|
|
||||||
ClipMatrixDirty = true;
|
ClipMatrixDirty = true;
|
||||||
}
|
}
|
||||||
else if (MatrixMode == 3)
|
else if (MatrixMode == 3)
|
||||||
@ -1210,7 +1123,6 @@ void ExecuteCommand()
|
|||||||
|
|
||||||
TexMatrixStackPointer--;
|
TexMatrixStackPointer--;
|
||||||
memcpy(TexMatrix, TexMatrixStack, 16*4);
|
memcpy(TexMatrix, TexMatrixStack, 16*4);
|
||||||
GXStat |= (1<<14);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1227,7 +1139,6 @@ void ExecuteCommand()
|
|||||||
|
|
||||||
memcpy(PosMatrix, PosMatrixStack[PosMatrixStackPointer], 16*4);
|
memcpy(PosMatrix, PosMatrixStack[PosMatrixStackPointer], 16*4);
|
||||||
memcpy(VecMatrix, VecMatrixStack[PosMatrixStackPointer], 16*4);
|
memcpy(VecMatrix, VecMatrixStack[PosMatrixStackPointer], 16*4);
|
||||||
GXStat |= (1<<14);
|
|
||||||
ClipMatrixDirty = true;
|
ClipMatrixDirty = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1592,6 +1503,21 @@ void ExecuteCommand()
|
|||||||
Viewport[3] = (ExecParams[0] >> 24) - Viewport[1] + 1;
|
Viewport[3] = (ExecParams[0] >> 24) - Viewport[1] + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x70: // box test
|
||||||
|
NumTestCommands -= 3;
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x71: // pos test
|
||||||
|
NumTestCommands -= 2;
|
||||||
|
//
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x72: // vec test
|
||||||
|
NumTestCommands--;
|
||||||
|
//
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//if (entry.Command != 0x41)
|
//if (entry.Command != 0x41)
|
||||||
//printf("!! UNKNOWN GX COMMAND %02X %08X\n", entry.Command, entry.Param);
|
//printf("!! UNKNOWN GX COMMAND %02X %08X\n", entry.Command, entry.Param);
|
||||||
@ -1612,13 +1538,21 @@ void Run(s32 cycles)
|
|||||||
if (CycleCount <= 0)
|
if (CycleCount <= 0)
|
||||||
{
|
{
|
||||||
while (CycleCount <= 0 && !CmdPIPE->IsEmpty())
|
while (CycleCount <= 0 && !CmdPIPE->IsEmpty())
|
||||||
|
{
|
||||||
|
if (NumPushPopCommands == 0) GXStat &= ~(1<<14);
|
||||||
|
if (NumTestCommands == 0) GXStat &= ~(1<<0);
|
||||||
|
|
||||||
ExecuteCommand();
|
ExecuteCommand();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CycleCount <= 0 && CmdPIPE->IsEmpty())
|
if (CycleCount <= 0 && CmdPIPE->IsEmpty())
|
||||||
{
|
{
|
||||||
CycleCount = 0;
|
CycleCount = 0;
|
||||||
GXStat &= ~((1<<27)|(1<<14));
|
GXStat &= ~(1<<27);
|
||||||
|
|
||||||
|
if (NumPushPopCommands == 0) GXStat &= ~(1<<14);
|
||||||
|
if (NumTestCommands == 0) GXStat &= ~(1<<0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1777,7 +1711,9 @@ void Write16(u32 addr, u16 val)
|
|||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x04000060:
|
case 0x04000060:
|
||||||
DispCnt = val;
|
DispCnt = (val & 0x4FFF) | (DispCnt & 0x3000);
|
||||||
|
if (val & (1<<12)) DispCnt &= ~(1<<12);
|
||||||
|
if (val & (1<<13)) DispCnt &= ~(1<<13);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04000340:
|
case 0x04000340:
|
||||||
@ -1836,7 +1772,9 @@ void Write32(u32 addr, u32 val)
|
|||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x04000060:
|
case 0x04000060:
|
||||||
DispCnt = val & 0xFFFF;
|
DispCnt = (val & 0x4FFF) | (DispCnt & 0x3000);
|
||||||
|
if (val & (1<<12)) DispCnt &= ~(1<<12);
|
||||||
|
if (val & (1<<13)) DispCnt &= ~(1<<13);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04000340:
|
case 0x04000340:
|
||||||
|
@ -769,6 +769,14 @@ void RenderPolygon(Polygon* polygon)
|
|||||||
if (rslope > 0) dxr += rslope;
|
if (rslope > 0) dxr += rslope;
|
||||||
else dxr -= rslope;
|
else dxr -= rslope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*for (int i = 0; i < polygon->NumVertices; i++)
|
||||||
|
{
|
||||||
|
Vertex* vtx = polygon->Vertices[i];
|
||||||
|
u32 addr = vtx->FinalPosition[0] + (vtx->FinalPosition[1]*256);
|
||||||
|
if (addr < 256*192)
|
||||||
|
ColorBuffer[addr] = 0x1F3F003F;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
|
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
|
||||||
|
Reference in New Issue
Block a user