mirror of https://github.com/mgba-emu/mgba.git
DS GX: Pay down tech debt around coordinates
This commit is contained in:
parent
2a29a4dd58
commit
2b6ed2661e
|
@ -109,9 +109,7 @@ struct DSGXEntry {
|
|||
|
||||
struct DSGXVertex {
|
||||
// World coords
|
||||
int16_t x; // 4.12
|
||||
int16_t y; // 4.12
|
||||
int16_t z; // 4.12
|
||||
int16_t coord[3]; // 4.12
|
||||
|
||||
// Color/Texcoords
|
||||
uint16_t color; // 5.5.5
|
||||
|
@ -119,10 +117,7 @@ struct DSGXVertex {
|
|||
int16_t t; // 12.4
|
||||
|
||||
// Viewport coords
|
||||
int32_t vx;
|
||||
int32_t vy;
|
||||
int32_t vz;
|
||||
int32_t vw;
|
||||
int32_t viewCoord[4];
|
||||
int16_t vs; // 12.4
|
||||
int16_t vt; // 12.4
|
||||
};
|
||||
|
|
|
@ -49,9 +49,7 @@ struct DSGXSoftwareEdge {
|
|||
};
|
||||
|
||||
struct DSGXSoftwareEndpoint {
|
||||
int32_t x; // 20.12
|
||||
int32_t z;
|
||||
int32_t w;
|
||||
int32_t coord[4]; // 20.12
|
||||
int64_t wRecip;
|
||||
uint8_t cr;
|
||||
uint8_t cg;
|
||||
|
@ -91,7 +89,7 @@ struct DSGXSoftwareRenderer {
|
|||
uint8_t stencilBuffer[DS_VIDEO_HORIZONTAL_PIXELS];
|
||||
color_t* scanlineCache;
|
||||
bool flushPending;
|
||||
bool wSort;
|
||||
int sort;
|
||||
|
||||
struct DSGXVertex* verts;
|
||||
};
|
||||
|
|
395
src/ds/gx.c
395
src/ds/gx.c
|
@ -25,15 +25,6 @@ static void DSGXWriteFIFO(struct DSGX* gx, struct DSGXEntry entry);
|
|||
|
||||
static bool _boxTestVertex(struct DSGX* gx, struct DSGXVertex* vertex);
|
||||
|
||||
enum CSCode {
|
||||
CS_LEFT = 1,
|
||||
CS_RIGHT = 2,
|
||||
CS_BOTTOM = 4,
|
||||
CS_TOP = 8,
|
||||
CS_NEAR = 16,
|
||||
CS_FAR = 32
|
||||
};
|
||||
|
||||
static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = {
|
||||
[DS_GX_CMD_NOP] = 0,
|
||||
[DS_GX_CMD_MTX_MODE] = 2,
|
||||
|
@ -195,22 +186,22 @@ static inline int32_t _lerp(int32_t x0, int32_t x1, int32_t q, int64_t r) {
|
|||
return x;
|
||||
}
|
||||
|
||||
static int _cohenSutherlandCode(const struct DSGX* gx, const struct DSGXVertex* v) {
|
||||
static int _cohenSutherlandCode(const struct DSGXVertex* v) {
|
||||
int code = 0;
|
||||
if (v->vx < -v->vw) {
|
||||
code |= CS_LEFT;
|
||||
} else if (v->vx > v->vw) {
|
||||
code |= CS_RIGHT;
|
||||
if (v->viewCoord[0] < -v->viewCoord[3]) {
|
||||
code |= 1 << 0;
|
||||
} else if (v->viewCoord[0] > v->viewCoord[3]) {
|
||||
code |= 2 << 0;
|
||||
}
|
||||
if (v->vy < -v->vw) {
|
||||
code |= CS_BOTTOM;
|
||||
} else if (v->vy > v->vw) {
|
||||
code |= CS_TOP;
|
||||
if (v->viewCoord[1] < -v->viewCoord[3]) {
|
||||
code |= 1 << 2;
|
||||
} else if (v->viewCoord[1] > v->viewCoord[3]) {
|
||||
code |= 2 << 2;
|
||||
}
|
||||
if (v->vz < -v->vw) {
|
||||
code |= CS_NEAR;
|
||||
} else if (v->vz > v->vw) {
|
||||
code |= CS_FAR;
|
||||
if (v->viewCoord[2] < -v->viewCoord[3]) {
|
||||
code |= 1 << 4;
|
||||
} else if (v->viewCoord[2] > v->viewCoord[3]) {
|
||||
code |= 2 << 4;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -230,31 +221,19 @@ static bool _lerpVertex(const struct DSGXVertex* v0, const struct DSGXVertex* v1
|
|||
cb0 = _lerp(cb0, cb1, q, r) & 0x1F;
|
||||
out->color = cr0 | (cg0 << 5) | (cb0 << 10);
|
||||
|
||||
out->vx = _lerp(v0->vx, v1->vx, q, r);
|
||||
out->vy = _lerp(v0->vy, v1->vy, q, r);
|
||||
out->vz = _lerp(v0->vz, v1->vz, q, r);
|
||||
out->vw = _lerp(v0->vw, v1->vw, q, r);
|
||||
out->viewCoord[0] = _lerp(v0->viewCoord[0], v1->viewCoord[0], q, r);
|
||||
out->viewCoord[1] = _lerp(v0->viewCoord[1], v1->viewCoord[1], q, r);
|
||||
out->viewCoord[2] = _lerp(v0->viewCoord[2], v1->viewCoord[2], q, r);
|
||||
out->viewCoord[3] = _lerp(v0->viewCoord[3], v1->viewCoord[3], q, r);
|
||||
|
||||
out->vs = _lerp(v0->vs, v1->vs, q, r);
|
||||
out->vt = _lerp(v0->vt, v1->vt, q, r);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _lerpVertexX(const struct DSGXVertex* v0, const struct DSGXVertex* v1, struct DSGXVertex* out, int sign) {
|
||||
int32_t q = v0->vw - sign * v0->vx;
|
||||
int64_t r = q - (v1->vw - sign * v1->vx);
|
||||
return _lerpVertex(v0, v1, out, q, r);
|
||||
}
|
||||
|
||||
static bool _lerpVertexY(const struct DSGXVertex* v0, const struct DSGXVertex* v1, struct DSGXVertex* out, int sign) {
|
||||
int32_t q = v0->vw - sign * v0->vy;
|
||||
int64_t r = q - (v1->vw - sign * v1->vy);
|
||||
return _lerpVertex(v0, v1, out, q, r);
|
||||
}
|
||||
|
||||
static bool _lerpVertexZ(const struct DSGXVertex* v0, const struct DSGXVertex* v1, struct DSGXVertex* out, int sign) {
|
||||
int32_t q = v0->vw - sign * v0->vz;
|
||||
int64_t r = q - (v1->vw - sign * v1->vz);
|
||||
static bool _lerpVertexP(const struct DSGXVertex* v0, const struct DSGXVertex* v1, struct DSGXVertex* out, int plane, int sign) {
|
||||
int32_t q = v0->viewCoord[3] - sign * v0->viewCoord[plane];
|
||||
int64_t r = q - (v1->viewCoord[3] - sign * v1->viewCoord[plane]);
|
||||
return _lerpVertex(v0, v1, out, q, r);
|
||||
}
|
||||
|
||||
|
@ -284,10 +263,10 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
v1 = &gx->pendingVertices[poly->vertIds[v + 1 - poly->verts]];
|
||||
v2 = &gx->pendingVertices[poly->vertIds[v + 2 - poly->verts]];
|
||||
}
|
||||
nx = ((int64_t) v0->vy * v2->vw - (int64_t) v0->vw * v2->vy) >> 24;
|
||||
ny = ((int64_t) v0->vw * v2->vx - (int64_t) v0->vx * v2->vw) >> 24;
|
||||
nz = ((int64_t) v0->vx * v2->vy - (int64_t) v0->vy * v2->vx) >> 24;
|
||||
dot += nx * v1->vx + ny * v1->vy + nz * v1->vw;
|
||||
nx = ((int64_t) v0->viewCoord[1] * v2->viewCoord[3] - (int64_t) v0->viewCoord[3] * v2->viewCoord[1]) >> 24;
|
||||
ny = ((int64_t) v0->viewCoord[3] * v2->viewCoord[0] - (int64_t) v0->viewCoord[0] * v2->viewCoord[3]) >> 24;
|
||||
nz = ((int64_t) v0->viewCoord[0] * v2->viewCoord[1] - (int64_t) v0->viewCoord[1] * v2->viewCoord[0]) >> 24;
|
||||
dot += nx * v1->viewCoord[0] + ny * v1->viewCoord[1] + nz * v1->viewCoord[3];
|
||||
}
|
||||
if (!DSGXPolygonAttrsIsBackFace(poly->polyParams) && dot < 0) {
|
||||
return false;
|
||||
|
@ -299,7 +278,7 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
|
||||
// Collect offscreen vertices
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
offscreenVerts[v] = _cohenSutherlandCode(gx, &gx->pendingVertices[poly->vertIds[v]]);
|
||||
offscreenVerts[v] = _cohenSutherlandCode(&gx->pendingVertices[poly->vertIds[v]]);
|
||||
oldVerts[v] = poly->vertIds[v];
|
||||
if (offscreenVerts[v]) {
|
||||
++nOffscreen;
|
||||
|
@ -335,61 +314,11 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
|
||||
int newV;
|
||||
|
||||
// Clip near
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_NEAR)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
struct DSGXVertex* in = &inList[v];
|
||||
struct DSGXVertex* in2;
|
||||
struct DSGXVertex* out;
|
||||
int iv;
|
||||
|
||||
if (v > 0) {
|
||||
iv = v - 1;
|
||||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_NEAR)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexZ(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < poly->verts - 1) {
|
||||
iv = v + 1;
|
||||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_NEAR)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexZ(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
// Clip far
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_FAR)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
if (!(offscreenVerts[v] & CS_NEAR)) {
|
||||
int plane;
|
||||
for (plane = 5; plane >= 0; --plane) {
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & (1 << plane))) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
|
@ -404,11 +333,11 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_FAR)) {
|
||||
if (!(offscreenVerts[iv] & (1 << plane))) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexZ(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
if (_lerpVertexP(in, in2, out, plane >> 1, -1 + (plane & 1) * 2)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
@ -418,204 +347,20 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_FAR)) {
|
||||
if (!(offscreenVerts[iv] & (1 << plane))) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexZ(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
if (_lerpVertexP(in, in2, out, plane >> 1, -1 + (plane & 1) * 2)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
// Clip left
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_LEFT)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
struct DSGXVertex* in = &inList[v];
|
||||
struct DSGXVertex* in2;
|
||||
struct DSGXVertex* out;
|
||||
int iv;
|
||||
|
||||
if (v > 0) {
|
||||
iv = v - 1;
|
||||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_LEFT)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexX(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < poly->verts - 1) {
|
||||
iv = v + 1;
|
||||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_LEFT)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexX(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
// Clip right
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_RIGHT)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
struct DSGXVertex* in = &inList[v];
|
||||
struct DSGXVertex* in2;
|
||||
struct DSGXVertex* out;
|
||||
int iv;
|
||||
|
||||
if (v > 0) {
|
||||
iv = v - 1;
|
||||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_RIGHT)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexX(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < poly->verts - 1) {
|
||||
iv = v + 1;
|
||||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_RIGHT)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexX(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
// Clip bottom
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_BOTTOM)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
struct DSGXVertex* in = &inList[v];
|
||||
struct DSGXVertex* in2;
|
||||
struct DSGXVertex* out;
|
||||
int iv;
|
||||
|
||||
if (v > 0) {
|
||||
iv = v - 1;
|
||||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_BOTTOM)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexY(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < poly->verts - 1) {
|
||||
iv = v + 1;
|
||||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_BOTTOM)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexY(in, in2, out, -1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
// Clip top
|
||||
newV = 0;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (!(offscreenVerts[v] & CS_TOP)) {
|
||||
outList[newV] = inList[v];
|
||||
outOffscreenVerts[newV] = offscreenVerts[v];
|
||||
++newV;
|
||||
} else {
|
||||
struct DSGXVertex* in = &inList[v];
|
||||
struct DSGXVertex* in2;
|
||||
struct DSGXVertex* out;
|
||||
int iv;
|
||||
|
||||
if (v > 0) {
|
||||
iv = v - 1;
|
||||
} else {
|
||||
iv = poly->verts - 1;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_TOP)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexY(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < poly->verts - 1) {
|
||||
iv = v + 1;
|
||||
} else {
|
||||
iv = 0;
|
||||
}
|
||||
if (!(offscreenVerts[iv] & CS_TOP)) {
|
||||
in2 = &inList[iv];
|
||||
out = &outList[newV];
|
||||
if (_lerpVertexY(in, in2, out, 1)) {
|
||||
outOffscreenVerts[newV] = _cohenSutherlandCode(gx, out);
|
||||
++newV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->verts = newV;
|
||||
memcpy(inList, outList, newV * sizeof(*inList));
|
||||
memcpy(offscreenVerts, outOffscreenVerts, newV * sizeof(*offscreenVerts));
|
||||
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
if (gx->vertexIndex == DS_GX_VERTEX_BUFFER_SIZE) {
|
||||
|
@ -635,13 +380,13 @@ static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) {
|
|||
int64_t b;
|
||||
int64_t sum;
|
||||
a = col[0];
|
||||
b = vertex->x;
|
||||
b = vertex->coord[0];
|
||||
sum = a * b;
|
||||
a = col[4];
|
||||
b = vertex->y;
|
||||
b = vertex->coord[1];
|
||||
sum += a * b;
|
||||
a = col[8];
|
||||
b = vertex->z;
|
||||
b = vertex->coord[2];
|
||||
sum += a * b;
|
||||
a = col[12];
|
||||
b = MTX_ONE;
|
||||
|
@ -672,13 +417,13 @@ static int16_t _dotTexture(struct DSGXVertex* vertex, int mode, int32_t* col) {
|
|||
return 0;
|
||||
case 3:
|
||||
a = col[0];
|
||||
b = vertex->vx << 8;
|
||||
b = vertex->viewCoord[0] << 8;
|
||||
sum = a * b;
|
||||
a = col[4];
|
||||
b = vertex->vy << 8;
|
||||
b = vertex->viewCoord[1] << 8;
|
||||
sum += a * b;
|
||||
a = col[8];
|
||||
b = vertex->vz << 8;
|
||||
b = vertex->viewCoord[2] << 8;
|
||||
sum += a * b;
|
||||
a = col[12];
|
||||
b = MTX_ONE;
|
||||
|
@ -720,13 +465,13 @@ static void _emitVertex(struct DSGX* gx, uint16_t x, uint16_t y, uint16_t z) {
|
|||
if (gx->vertexMode < 0 || gx->vertexIndex == DS_GX_VERTEX_BUFFER_SIZE || gx->polygonIndex == DS_GX_POLYGON_BUFFER_SIZE) {
|
||||
return;
|
||||
}
|
||||
gx->currentVertex.x = x;
|
||||
gx->currentVertex.y = y;
|
||||
gx->currentVertex.z = z;
|
||||
gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[0]);
|
||||
gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[1]);
|
||||
gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[2]);
|
||||
gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]);
|
||||
gx->currentVertex.coord[0] = x;
|
||||
gx->currentVertex.coord[1] = y;
|
||||
gx->currentVertex.coord[2] = z;
|
||||
gx->currentVertex.viewCoord[0] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[0]);
|
||||
gx->currentVertex.viewCoord[1] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[1]);
|
||||
gx->currentVertex.viewCoord[2] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[2]);
|
||||
gx->currentVertex.viewCoord[3] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]);
|
||||
|
||||
if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 0) {
|
||||
gx->currentVertex.vs = gx->currentVertex.s;
|
||||
|
@ -861,49 +606,47 @@ static bool _boxTest(struct DSGX* gx) {
|
|||
d |= gx->activeEntries[2].params[3] << 8;
|
||||
|
||||
struct DSGXVertex vertex = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
.z = z
|
||||
.coord = { x, y, z }
|
||||
};
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x += w;
|
||||
vertex.coord[0] += w;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x = x;
|
||||
vertex.y += h;
|
||||
vertex.coord[0] = x;
|
||||
vertex.coord[1] += h;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x += w;
|
||||
vertex.coord[0] += w;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x = x;
|
||||
vertex.y = y;
|
||||
vertex.z += d;
|
||||
vertex.coord[0] = x;
|
||||
vertex.coord[1] = y;
|
||||
vertex.coord[2] += d;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x += w;
|
||||
vertex.coord[0] += w;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x = x;
|
||||
vertex.y += h;
|
||||
vertex.coord[0] = x;
|
||||
vertex.coord[1] += h;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
vertex.x += w;
|
||||
vertex.coord[0] += w;
|
||||
if (_boxTestVertex(gx, &vertex)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1391,7 +1134,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
|||
x |= entry.params[1] << 8;
|
||||
int16_t y = entry.params[2];
|
||||
y |= entry.params[3] << 8;
|
||||
_emitVertex(gx, x, y, gx->currentVertex.z);
|
||||
_emitVertex(gx, x, y, gx->currentVertex.coord[2]);
|
||||
break;
|
||||
}
|
||||
case DS_GX_CMD_VTX_XZ: {
|
||||
|
@ -1399,7 +1142,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
|||
x |= entry.params[1] << 8;
|
||||
int16_t z = entry.params[2];
|
||||
z |= entry.params[3] << 8;
|
||||
_emitVertex(gx, x, gx->currentVertex.y, z);
|
||||
_emitVertex(gx, x, gx->currentVertex.coord[1], z);
|
||||
break;
|
||||
}
|
||||
case DS_GX_CMD_VTX_YZ: {
|
||||
|
@ -1407,7 +1150,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
|||
y |= entry.params[1] << 8;
|
||||
int16_t z = entry.params[2];
|
||||
z |= entry.params[3] << 8;
|
||||
_emitVertex(gx, gx->currentVertex.x, y, z);
|
||||
_emitVertex(gx, gx->currentVertex.coord[0], y, z);
|
||||
break;
|
||||
}
|
||||
case DS_GX_CMD_VTX_DIFF: {
|
||||
|
@ -1418,7 +1161,9 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
|||
int16_t x = (xyz << 6) & 0xFFC0;
|
||||
int16_t y = (xyz >> 4) & 0xFFC0;
|
||||
int16_t z = (xyz >> 14) & 0xFFC0;
|
||||
_emitVertex(gx, gx->currentVertex.x + (x >> 6), gx->currentVertex.y + (y >> 6), gx->currentVertex.z + (z >> 6));
|
||||
_emitVertex(gx, gx->currentVertex.coord[0] + (x >> 6),
|
||||
gx->currentVertex.coord[1] + (y >> 6),
|
||||
gx->currentVertex.coord[2] + (z >> 6));
|
||||
break;
|
||||
}
|
||||
case DS_GX_CMD_DIF_AMB:
|
||||
|
|
|
@ -300,16 +300,16 @@ static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftware
|
|||
return false;
|
||||
}
|
||||
|
||||
span->ep[index].x = (((int64_t) (edge->x1 - edge->x0) * yw) / height) + edge->x0;
|
||||
span->ep[index].coord[0] = (((int64_t) (edge->x1 - edge->x0) * yw) / height) + edge->x0;
|
||||
|
||||
if (index) {
|
||||
if (span->ep[0].x == span->ep[index].x) {
|
||||
if (span->ep[0].coord[0] == span->ep[index].coord[0]) {
|
||||
return false;
|
||||
}
|
||||
if (span->ep[0].x > span->ep[index].x) {
|
||||
int32_t temp = span->ep[index].x;
|
||||
if (span->ep[0].coord[0] > span->ep[index].coord[0]) {
|
||||
int32_t temp = span->ep[index].coord[0];
|
||||
span->ep[index] = span->ep[0];
|
||||
span->ep[0].x = temp;
|
||||
span->ep[0].coord[0] = temp;
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
@ -329,11 +329,11 @@ static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftware
|
|||
w += div;
|
||||
w += w0;
|
||||
|
||||
span->ep[index].w = 0x7FFFFFFFFFFFFFFF / w;
|
||||
span->ep[index].coord[3] = 0x7FFFFFFFFFFFFFFF / w;
|
||||
span->ep[index].wRecip = w;
|
||||
int32_t qr = (yw << 12) / height;
|
||||
|
||||
span->ep[index].z = _interpolate(edge->z0, edge->z1, w0, w1, w, qr);
|
||||
span->ep[index].coord[2] = _interpolate(edge->z0, edge->z1, w0, w1, w, qr);
|
||||
span->ep[index].cr = _interpolate(edge->cr0, edge->cr1, w0, w1, w, qr);
|
||||
span->ep[index].cg = _interpolate(edge->cg0, edge->cg1, w0, w1, w, qr);
|
||||
span->ep[index].cb = _interpolate(edge->cb0, edge->cb1, w0, w1, w, qr);
|
||||
|
@ -344,10 +344,10 @@ static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftware
|
|||
}
|
||||
|
||||
static void _createStep(struct DSGXSoftwareSpan* span) {
|
||||
int32_t width = (span->ep[1].x - span->ep[0].x) >> 7;
|
||||
int32_t width = (span->ep[1].coord[0] - span->ep[0].coord[0]) >> 7;
|
||||
|
||||
span->ep[0].stepW = span->ep[0].wRecip;
|
||||
span->ep[0].stepZ = span->ep[0].z * span->ep[0].wRecip;
|
||||
span->ep[0].stepZ = span->ep[0].coord[2] * span->ep[0].wRecip;
|
||||
span->ep[0].stepR = span->ep[0].cr * span->ep[0].wRecip;
|
||||
span->ep[0].stepG = span->ep[0].cg * span->ep[0].wRecip;
|
||||
span->ep[0].stepB = span->ep[0].cb * span->ep[0].wRecip;
|
||||
|
@ -355,7 +355,7 @@ static void _createStep(struct DSGXSoftwareSpan* span) {
|
|||
span->ep[0].stepT = span->ep[0].t * span->ep[0].wRecip;
|
||||
|
||||
span->ep[1].stepW = span->ep[1].wRecip;
|
||||
span->ep[1].stepZ = span->ep[1].z * span->ep[1].wRecip;
|
||||
span->ep[1].stepZ = span->ep[1].coord[2] * span->ep[1].wRecip;
|
||||
span->ep[1].stepR = span->ep[1].cr * span->ep[1].wRecip;
|
||||
span->ep[1].stepG = span->ep[1].cg * span->ep[1].wRecip;
|
||||
span->ep[1].stepB = span->ep[1].cb * span->ep[1].wRecip;
|
||||
|
@ -365,7 +365,7 @@ static void _createStep(struct DSGXSoftwareSpan* span) {
|
|||
if (!width) {
|
||||
return;
|
||||
}
|
||||
span->step.x = span->ep[1].x - span->ep[0].x;
|
||||
span->step.coord[0] = span->ep[1].coord[0] - span->ep[0].coord[0];
|
||||
span->step.stepW = (span->ep[1].stepW - span->ep[0].stepW) / width;
|
||||
span->step.stepZ = (span->ep[1].stepZ - span->ep[0].stepZ) / width;
|
||||
span->step.stepR = (span->ep[1].stepR - span->ep[0].stepR) / width;
|
||||
|
@ -377,32 +377,32 @@ static void _createStep(struct DSGXSoftwareSpan* span) {
|
|||
|
||||
static void _stepEndpoint(struct DSGXSoftwareSpan* span) {
|
||||
int i = 28;
|
||||
int32_t nextX = (span->ep[0].x & ~0xFFF) + 0x1000;
|
||||
span->ep[0].x += 0x80 * i;
|
||||
while (span->ep[0].x < nextX) {
|
||||
span->ep[0].x += 0x80;
|
||||
int32_t nextX = (span->ep[0].coord[0] & ~0xFFF) + 0x1000;
|
||||
span->ep[0].coord[0] += 0x80 * i;
|
||||
while (span->ep[0].coord[0] < nextX) {
|
||||
span->ep[0].coord[0] += 0x80;
|
||||
++i;
|
||||
}
|
||||
span->ep[0].wRecip += span->step.stepW * i;
|
||||
span->ep[0].w = (0x7FFFFFFFFFFFFFFF / span->ep[0].wRecip) + 1;
|
||||
span->ep[0].coord[3] = (0x7FFFFFFFFFFFFFFF / span->ep[0].wRecip) + 1;
|
||||
|
||||
span->ep[0].stepZ += span->step.stepZ * i;
|
||||
span->ep[0].z = _divideBy(span->ep[0].stepZ, span->ep[0].w);
|
||||
span->ep[0].coord[2] = _divideBy(span->ep[0].stepZ, span->ep[0].coord[3]);
|
||||
|
||||
span->ep[0].stepR += span->step.stepR * i;
|
||||
span->ep[0].cr = _divideBy(span->ep[0].stepR, span->ep[0].w);
|
||||
span->ep[0].cr = _divideBy(span->ep[0].stepR, span->ep[0].coord[3]);
|
||||
|
||||
span->ep[0].stepG += span->step.stepG * i;
|
||||
span->ep[0].cg = _divideBy(span->ep[0].stepG, span->ep[0].w);
|
||||
span->ep[0].cg = _divideBy(span->ep[0].stepG, span->ep[0].coord[3]);
|
||||
|
||||
span->ep[0].stepB += span->step.stepB * i;
|
||||
span->ep[0].cb = _divideBy(span->ep[0].stepB, span->ep[0].w);
|
||||
span->ep[0].cb = _divideBy(span->ep[0].stepB, span->ep[0].coord[3]);
|
||||
|
||||
span->ep[0].stepS += span->step.stepS * i;
|
||||
span->ep[0].s = _divideBy(span->ep[0].stepS, span->ep[0].w);
|
||||
span->ep[0].s = _divideBy(span->ep[0].stepS, span->ep[0].coord[3]);
|
||||
|
||||
span->ep[0].stepT += span->step.stepT * i;
|
||||
span->ep[0].t = _divideBy(span->ep[0].stepT, span->ep[0].w);
|
||||
span->ep[0].t = _divideBy(span->ep[0].stepT, span->ep[0].coord[3]);
|
||||
}
|
||||
|
||||
void DSGXSoftwareRendererCreate(struct DSGXSoftwareRenderer* renderer) {
|
||||
|
@ -475,44 +475,44 @@ static void _preparePoly(struct DSGXRenderer* renderer, struct DSGXVertex* verts
|
|||
struct DSGXVertex* v0 = &verts[poly->poly->vertIds[0]];
|
||||
struct DSGXVertex* v1;
|
||||
|
||||
int32_t v0x = (v0->vx + v0->vw) * (int64_t) (renderer->viewportWidth << 12) / (v0->vw * 2) + (renderer->viewportX << 12);
|
||||
int32_t v0y = (-v0->vy + v0->vw) * (int64_t) (renderer->viewportHeight << 12) / (v0->vw * 2) + (renderer->viewportY << 12);
|
||||
int32_t v0x = (v0->viewCoord[0] + v0->viewCoord[3]) * (int64_t) (renderer->viewportWidth << 12) / (v0->viewCoord[3] * 2) + (renderer->viewportX << 12);
|
||||
int32_t v0y = (-v0->viewCoord[1] + v0->viewCoord[3]) * (int64_t) (renderer->viewportHeight << 12) / (v0->viewCoord[3] * 2) + (renderer->viewportY << 12);
|
||||
|
||||
int v;
|
||||
for (v = 1; v < poly->poly->verts; ++v) {
|
||||
v1 = &verts[poly->poly->vertIds[v]];
|
||||
int32_t v1x = (v1->vx + v1->vw) * (int64_t) (renderer->viewportWidth << 12) / (v1->vw * 2) + (renderer->viewportX << 12);
|
||||
int32_t v1y = (-v1->vy + v1->vw) * (int64_t) (renderer->viewportHeight << 12) / (v1->vw * 2) + (renderer->viewportY << 12);
|
||||
int32_t v1x = (v1->viewCoord[0] + v1->viewCoord[3]) * (int64_t) (renderer->viewportWidth << 12) / (v1->viewCoord[3] * 2) + (renderer->viewportX << 12);
|
||||
int32_t v1y = (-v1->viewCoord[1] + v1->viewCoord[3]) * (int64_t) (renderer->viewportHeight << 12) / (v1->viewCoord[3] * 2) + (renderer->viewportY << 12);
|
||||
|
||||
if (v0y <= v1y) {
|
||||
edge->y0 = v0y;
|
||||
edge->x0 = v0x;
|
||||
edge->z0 = v0->vz;
|
||||
edge->w0 = v0->vw;
|
||||
edge->z0 = v0->viewCoord[2];
|
||||
edge->w0 = v0->viewCoord[3];
|
||||
_expandColor(v0->color, &edge->cr0, &edge->cg0, &edge->cb0);
|
||||
edge->s0 = v0->vs;
|
||||
edge->t0 = v0->vt;
|
||||
|
||||
edge->y1 = v1y;
|
||||
edge->x1 = v1x;
|
||||
edge->z1 = v1->vz;
|
||||
edge->w1 = v1->vw;
|
||||
edge->z1 = v1->viewCoord[2];
|
||||
edge->w1 = v1->viewCoord[3];
|
||||
_expandColor(v1->color, &edge->cr1, &edge->cg1, &edge->cb1);
|
||||
edge->s1 = v1->vs;
|
||||
edge->t1 = v1->vt;
|
||||
} else {
|
||||
edge->y0 = v1y;
|
||||
edge->x0 = v1x;
|
||||
edge->z0 = v1->vz;
|
||||
edge->w0 = v1->vw;
|
||||
edge->z0 = v1->viewCoord[2];
|
||||
edge->w0 = v1->viewCoord[3];
|
||||
_expandColor(v1->color, &edge->cr0, &edge->cg0, &edge->cb0);
|
||||
edge->s0 = v1->vs;
|
||||
edge->t0 = v1->vt;
|
||||
|
||||
edge->y1 = v0y;
|
||||
edge->x1 = v0x;
|
||||
edge->z1 = v0->vz;
|
||||
edge->w1 = v0->vw;
|
||||
edge->z1 = v0->viewCoord[2];
|
||||
edge->w1 = v0->viewCoord[3];
|
||||
_expandColor(v0->color, &edge->cr1, &edge->cg1, &edge->cb1);
|
||||
edge->s1 = v0->vs;
|
||||
edge->t1 = v0->vt;
|
||||
|
@ -526,38 +526,38 @@ static void _preparePoly(struct DSGXRenderer* renderer, struct DSGXVertex* verts
|
|||
}
|
||||
|
||||
v1 = &verts[poly->poly->vertIds[0]];
|
||||
int32_t v1x = (v1->vx + v1->vw) * (int64_t) (renderer->viewportWidth << 12) / (v1->vw * 2) + (renderer->viewportX << 12);
|
||||
int32_t v1y = (-v1->vy + v1->vw) * (int64_t) (renderer->viewportHeight << 12) / (v1->vw * 2) + (renderer->viewportY << 12);
|
||||
int32_t v1x = (v1->viewCoord[0] + v1->viewCoord[3]) * (int64_t) (renderer->viewportWidth << 12) / (v1->viewCoord[3] * 2) + (renderer->viewportX << 12);
|
||||
int32_t v1y = (-v1->viewCoord[1] + v1->viewCoord[3]) * (int64_t) (renderer->viewportHeight << 12) / (v1->viewCoord[3] * 2) + (renderer->viewportY << 12);
|
||||
|
||||
if (v0y <= v1y) {
|
||||
edge->y0 = v0y;
|
||||
edge->x0 = v0x;
|
||||
edge->z0 = v0->vz;
|
||||
edge->w0 = v0->vw;
|
||||
edge->z0 = v0->viewCoord[2];
|
||||
edge->w0 = v0->viewCoord[3];
|
||||
_expandColor(v0->color, &edge->cr0, &edge->cg0, &edge->cb0);
|
||||
edge->s0 = v0->vs;
|
||||
edge->t0 = v0->vt;
|
||||
|
||||
edge->y1 = v1y;
|
||||
edge->x1 = v1x;
|
||||
edge->z1 = v1->vz;
|
||||
edge->w1 = v1->vw;
|
||||
edge->z1 = v1->viewCoord[2];
|
||||
edge->w1 = v1->viewCoord[3];
|
||||
_expandColor(v1->color, &edge->cr1, &edge->cg1, &edge->cb1);
|
||||
edge->s1 = v1->vs;
|
||||
edge->t1 = v1->vt;
|
||||
} else {
|
||||
edge->y0 = v1y;
|
||||
edge->x0 = v1x;
|
||||
edge->z0 = v1->vz;
|
||||
edge->w0 = v1->vw;
|
||||
edge->z0 = v1->viewCoord[2];
|
||||
edge->w0 = v1->viewCoord[3];
|
||||
_expandColor(v1->color, &edge->cr0, &edge->cg0, &edge->cb0);
|
||||
edge->s0 = v1->vs;
|
||||
edge->t0 = v1->vt;
|
||||
|
||||
edge->y1 = v0y;
|
||||
edge->x1 = v0x;
|
||||
edge->z1 = v0->vz;
|
||||
edge->w1 = v0->vw;
|
||||
edge->z1 = v0->viewCoord[2];
|
||||
edge->w1 = v0->viewCoord[3];
|
||||
_expandColor(v0->color, &edge->cr1, &edge->cg1, &edge->cb1);
|
||||
edge->s1 = v0->vs;
|
||||
edge->t1 = v0->vt;
|
||||
|
@ -568,7 +568,7 @@ static void DSGXSoftwareRendererSetRAM(struct DSGXRenderer* renderer, struct DSG
|
|||
struct DSGXSoftwareRenderer* softwareRenderer = (struct DSGXSoftwareRenderer*) renderer;
|
||||
|
||||
softwareRenderer->flushPending = true;
|
||||
softwareRenderer->wSort = wSort;
|
||||
softwareRenderer->sort = wSort ? 3 : 2;
|
||||
softwareRenderer->verts = verts;
|
||||
DSGXSoftwarePolygonListClear(&softwareRenderer->activePolys);
|
||||
DSGXSoftwareEdgeListClear(&softwareRenderer->activeEdges);
|
||||
|
@ -631,7 +631,7 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
|||
|
||||
unsigned poly = edge->polyId;
|
||||
struct DSGXSoftwareSpan* span = softwareRenderer->bucket[poly];
|
||||
if (span && !span->ep[1].w) {
|
||||
if (span && !span->ep[1].coord[3]) {
|
||||
if (_edgeToSpan(span, edge, 1, y << 12)) {
|
||||
_createStep(span);
|
||||
softwareRenderer->bucket[poly] = NULL;
|
||||
|
@ -663,11 +663,11 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
|||
for (i = 0; i < DSGXSoftwareSpanListSize(&softwareRenderer->activeSpans); ++i) {
|
||||
struct DSGXSoftwareSpan* span = DSGXSoftwareSpanListGetPointer(&softwareRenderer->activeSpans, i);
|
||||
|
||||
int32_t x = span->ep[0].x >> 12;
|
||||
int32_t x = span->ep[0].coord[0] >> 12;
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
for (; x < (span->ep[1].x >> 12) && x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
for (; x < (span->ep[1].coord[0] >> 12) && x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
color_t color = _lookupColor(softwareRenderer, &span->ep[0], span->poly);
|
||||
_stepEndpoint(span);
|
||||
unsigned a = color >> 27;
|
||||
|
@ -682,24 +682,13 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
|||
s |= 0x40;
|
||||
}
|
||||
if (a == 0x1F) {
|
||||
if (softwareRenderer->wSort) {
|
||||
if (span->ep[0].w < softwareRenderer->depthBuffer[x]) {
|
||||
if (!(s & 0x40) || !(softwareRenderer->stencilBuffer[x] & s & 0x40)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].w;
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
}
|
||||
} else {
|
||||
if (span->ep[0].z < softwareRenderer->depthBuffer[x]) {
|
||||
if (!(s & 0x40) || !(softwareRenderer->stencilBuffer[x] & s & 0x40)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].z;
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
if (span->ep[0].coord[softwareRenderer->sort] < softwareRenderer->depthBuffer[x]) {
|
||||
if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].coord[softwareRenderer->sort];
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
}
|
||||
} else if (a) {
|
||||
// TODO: Disable alpha?
|
||||
|
@ -708,28 +697,15 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
|||
color |= ab << 27;
|
||||
}
|
||||
if (softwareRenderer->stencilBuffer[x] != s) {
|
||||
if (softwareRenderer->wSort) {
|
||||
if (span->ep[0].w < softwareRenderer->depthBuffer[x]) {
|
||||
if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
|
||||
if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].w;
|
||||
}
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
if (span->ep[0].coord[softwareRenderer->sort] < softwareRenderer->depthBuffer[x]) {
|
||||
if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
|
||||
if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].coord[softwareRenderer->sort];
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
}
|
||||
} else {
|
||||
if (span->ep[0].z < softwareRenderer->depthBuffer[x]) {
|
||||
if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
|
||||
if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) {
|
||||
softwareRenderer->depthBuffer[x] = span->ep[0].z;
|
||||
}
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
scanline[x] = color;
|
||||
s &= ~0x40;
|
||||
}
|
||||
softwareRenderer->stencilBuffer[x] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue