DS GX: Update matrix transforms

This commit is contained in:
Vicki Pfau 2017-02-28 13:05:25 -08:00
parent 0d5a15380b
commit 9ad56b1b79
4 changed files with 69 additions and 52 deletions

View File

@ -153,7 +153,14 @@ struct DSGX {
struct DSGXMatrix posMatrix; struct DSGXMatrix posMatrix;
struct DSGXMatrix vecMatrix; struct DSGXMatrix vecMatrix;
struct DSGXMatrix vertexMatrix; struct DSGXMatrix clipMatrix;
int viewportX1;
int viewportY1;
int viewportX2;
int viewportY2;
int viewportWidth;
int viewportHeight;
int vertexMode; int vertexMode;
struct DSGXVertex currentVertex; struct DSGXVertex currentVertex;

View File

@ -17,7 +17,7 @@ struct DSGXMatrix {
}; };
void DSGXMtxIdentity(struct DSGXMatrix*); void DSGXMtxIdentity(struct DSGXMatrix*);
void DSGXMtxMultiply(struct DSGXMatrix*, const struct DSGXMatrix*); void DSGXMtxMultiply(struct DSGXMatrix*, const struct DSGXMatrix*, const struct DSGXMatrix*);
void DSGXMtxScale(struct DSGXMatrix*, const int32_t* m); void DSGXMtxScale(struct DSGXMatrix*, const int32_t* m);
void DSGXMtxTranslate(struct DSGXMatrix*, const int32_t* m); void DSGXMtxTranslate(struct DSGXMatrix*, const int32_t* m);

View File

@ -136,9 +136,8 @@ static void _pullPipe(struct DSGX* gx) {
} }
} }
static void _updateVertexMatrix(struct DSGX* gx) { static void _updateClipMatrix(struct DSGX* gx) {
memcpy(&gx->vertexMatrix, &gx->projMatrix, sizeof(gx->vertexMatrix)); DSGXMtxMultiply(&gx->clipMatrix, &gx->projMatrix, &gx->posMatrix);
DSGXMtxMultiply(&gx->vertexMatrix, &gx->posMatrix);
} }
static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) { static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) {
@ -167,10 +166,13 @@ static void _emitVertex(struct DSGX* gx, uint16_t x, uint16_t y, uint16_t z) {
gx->currentVertex.x = x; gx->currentVertex.x = x;
gx->currentVertex.y = y; gx->currentVertex.y = y;
gx->currentVertex.z = z; gx->currentVertex.z = z;
gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[0]); gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[0]);
gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[1]); gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[1]);
gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[2]); gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[2]);
gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[3]); gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]);
gx->currentVertex.vx = (gx->currentVertex.vx + gx->currentVertex.vw) * gx->viewportWidth / (gx->currentVertex.vw * 2) + gx->viewportX1;
gx->currentVertex.vy = (gx->currentVertex.vy + gx->currentVertex.vw) * gx->viewportHeight / (gx->currentVertex.vw * 2) + gx->viewportY1;
struct DSGXVertex* vbuf = gx->vertexBuffer[gx->bufferIndex]; struct DSGXVertex* vbuf = gx->vertexBuffer[gx->bufferIndex];
vbuf[gx->vertexIndex] = gx->currentVertex; vbuf[gx->vertexIndex] = gx->currentVertex;
@ -240,7 +242,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
if (first) { if (first) {
first = false; first = false;
} else if (cycles > cyclesLate) { } else if (!gx->activeParams && cycles > cyclesLate) {
break; break;
} }
CircleBufferRead8(&gx->pipe, (int8_t*) &entry.command); CircleBufferRead8(&gx->pipe, (int8_t*) &entry.command);
@ -292,7 +294,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
mLOG(DS_GX, STUB, "Unimplemented GX MTX_PUSH mode"); mLOG(DS_GX, STUB, "Unimplemented GX MTX_PUSH mode");
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
case DS_GX_CMD_MTX_POP: { case DS_GX_CMD_MTX_POP: {
int8_t offset = entry.params[0]; int8_t offset = entry.params[0];
@ -316,7 +318,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode"); mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode");
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_IDENTITY: case DS_GX_CMD_MTX_IDENTITY:
@ -334,7 +336,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
DSGXMtxIdentity(&gx->texMatrix); DSGXMtxIdentity(&gx->texMatrix);
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
case DS_GX_CMD_MTX_LOAD_4x4: { case DS_GX_CMD_MTX_LOAD_4x4: {
struct DSGXMatrix m; struct DSGXMatrix m;
@ -359,7 +361,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix)); memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_LOAD_4x3: { case DS_GX_CMD_MTX_LOAD_4x3: {
@ -389,7 +391,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix)); memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_MULT_4x4: { case DS_GX_CMD_MTX_MULT_4x4: {
@ -403,19 +405,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
} }
switch (gx->mtxMode) { switch (gx->mtxMode) {
case 0: case 0:
DSGXMtxMultiply(&gx->projMatrix, &m); DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break; break;
case 2: case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through // Fall through
case 1: case 1:
DSGXMtxMultiply(&gx->posMatrix, &m); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break; break;
case 3: case 3:
DSGXMtxMultiply(&gx->texMatrix, &m); DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_MULT_4x3: { case DS_GX_CMD_MTX_MULT_4x3: {
@ -433,19 +435,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
m.m[15] = MTX_ONE; m.m[15] = MTX_ONE;
switch (gx->mtxMode) { switch (gx->mtxMode) {
case 0: case 0:
DSGXMtxMultiply(&gx->projMatrix, &m); DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break; break;
case 2: case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through // Fall through
case 1: case 1:
DSGXMtxMultiply(&gx->posMatrix, &m); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break; break;
case 3: case 3:
DSGXMtxMultiply(&gx->texMatrix, &m); DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_MULT_3x3: { case DS_GX_CMD_MTX_MULT_3x3: {
@ -466,19 +468,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
m.m[15] = MTX_ONE; m.m[15] = MTX_ONE;
switch (gx->mtxMode) { switch (gx->mtxMode) {
case 0: case 0:
memcpy(&gx->projMatrix, &m, sizeof(gx->projMatrix)); DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break; break;
case 2: case 2:
memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix)); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through // Fall through
case 1: case 1:
memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix)); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break; break;
case 3: case 3:
memcpy(&gx->texMatrix, &m, sizeof(gx->projMatrix)); DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break; break;
} }
_updateVertexMatrix(gx); _updateClipMatrix(gx);
break; break;
} }
case DS_GX_CMD_MTX_TRANS: { case DS_GX_CMD_MTX_TRANS: {
@ -666,7 +668,7 @@ void DSGXReset(struct DSGX* gx) {
DSGXMtxIdentity(&gx->posMatrix); DSGXMtxIdentity(&gx->posMatrix);
DSGXMtxIdentity(&gx->vecMatrix); DSGXMtxIdentity(&gx->vecMatrix);
DSGXMtxIdentity(&gx->vertexMatrix); DSGXMtxIdentity(&gx->clipMatrix);
DSGXMtxIdentity(&gx->projMatrixStack); DSGXMtxIdentity(&gx->projMatrixStack);
DSGXMtxIdentity(&gx->texMatrixStack); DSGXMtxIdentity(&gx->texMatrixStack);
int i; int i;
@ -682,6 +684,13 @@ void DSGXReset(struct DSGX* gx) {
gx->pvMatrixPointer = 0; gx->pvMatrixPointer = 0;
gx->vertexMode = -1; gx->vertexMode = -1;
gx->viewportX1 = 0;
gx->viewportY1 = 0;
gx->viewportX2 = DS_VIDEO_HORIZONTAL_PIXELS - 1;
gx->viewportY2 = DS_VIDEO_VERTICAL_PIXELS - 1;
gx->viewportWidth = gx->viewportX2 - gx->viewportX1;
gx->viewportHeight = gx->viewportY2 - gx->viewportY1;
memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams)); memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams));
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand)); memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
gx->activeParams = 0; gx->activeParams = 0;

View File

@ -32,25 +32,26 @@ void DSGXMtxIdentity(struct DSGXMatrix* mtx) {
mtx->m[15] = MTX_ONE; mtx->m[15] = MTX_ONE;
} }
void DSGXMtxMultiply(struct DSGXMatrix* mtx, const struct DSGXMatrix* m) { void DSGXMtxMultiply(struct DSGXMatrix* out, const struct DSGXMatrix* a, const struct DSGXMatrix* b) {
struct DSGXMatrix out; struct DSGXMatrix o;
out.m[0] = _dot(&mtx->m[0], &m->m[0]); // XXX: This is transposed because DS matrices are transposed
out.m[1] = _dot(&mtx->m[1], &m->m[0]); o.m[0] = _dot(&a->m[0], &b->m[0]);
out.m[2] = _dot(&mtx->m[2], &m->m[0]); o.m[1] = _dot(&a->m[1], &b->m[0]);
out.m[3] = _dot(&mtx->m[3], &m->m[0]); o.m[2] = _dot(&a->m[2], &b->m[0]);
out.m[4] = _dot(&mtx->m[0], &m->m[4]); o.m[3] = _dot(&a->m[3], &b->m[0]);
out.m[5] = _dot(&mtx->m[1], &m->m[4]); o.m[4] = _dot(&a->m[0], &b->m[4]);
out.m[6] = _dot(&mtx->m[2], &m->m[4]); o.m[5] = _dot(&a->m[1], &b->m[4]);
out.m[7] = _dot(&mtx->m[3], &m->m[4]); o.m[6] = _dot(&a->m[2], &b->m[4]);
out.m[8] = _dot(&mtx->m[0], &m->m[8]); o.m[7] = _dot(&a->m[3], &b->m[4]);
out.m[9] = _dot(&mtx->m[1], &m->m[8]); o.m[8] = _dot(&a->m[0], &b->m[8]);
out.m[10] = _dot(&mtx->m[2], &m->m[8]); o.m[9] = _dot(&a->m[1], &b->m[8]);
out.m[11] = _dot(&mtx->m[3], &m->m[8]); o.m[10] = _dot(&a->m[2], &b->m[8]);
out.m[12] = _dot(&mtx->m[0], &m->m[12]); o.m[11] = _dot(&a->m[3], &b->m[8]);
out.m[13] = _dot(&mtx->m[1], &m->m[12]); o.m[12] = _dot(&a->m[0], &b->m[12]);
out.m[14] = _dot(&mtx->m[2], &m->m[12]); o.m[13] = _dot(&a->m[1], &b->m[12]);
out.m[15] = _dot(&mtx->m[3], &m->m[12]); o.m[14] = _dot(&a->m[2], &b->m[12]);
*mtx = out; o.m[15] = _dot(&a->m[3], &b->m[12]);
*out = o;
} }
void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) { void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) {
@ -62,7 +63,7 @@ void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) {
0, 0, 0, MTX_ONE 0, 0, 0, MTX_ONE
} }
}; };
DSGXMtxMultiply(mtx, &s); DSGXMtxMultiply(mtx, &s, mtx);
} }
void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) { void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) {
@ -74,5 +75,5 @@ void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) {
m[0], m[1], m[2], MTX_ONE m[0], m[1], m[2], MTX_ONE
} }
}; };
DSGXMtxMultiply(mtx, &t); DSGXMtxMultiply(mtx, &t, mtx);
} }