From 9ad56b1b798d1df66eaab8b7099aac4f07d11ac0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 Feb 2017 13:05:25 -0800 Subject: [PATCH] DS GX: Update matrix transforms --- include/mgba/internal/ds/gx.h | 9 ++++- include/mgba/internal/ds/matrix.h | 2 +- src/ds/gx.c | 67 ++++++++++++++++++------------- src/ds/matrix.c | 43 ++++++++++---------- 4 files changed, 69 insertions(+), 52 deletions(-) diff --git a/include/mgba/internal/ds/gx.h b/include/mgba/internal/ds/gx.h index 9e49bdb1c..857c09ce3 100644 --- a/include/mgba/internal/ds/gx.h +++ b/include/mgba/internal/ds/gx.h @@ -153,7 +153,14 @@ struct DSGX { struct DSGXMatrix posMatrix; struct DSGXMatrix vecMatrix; - struct DSGXMatrix vertexMatrix; + struct DSGXMatrix clipMatrix; + + int viewportX1; + int viewportY1; + int viewportX2; + int viewportY2; + int viewportWidth; + int viewportHeight; int vertexMode; struct DSGXVertex currentVertex; diff --git a/include/mgba/internal/ds/matrix.h b/include/mgba/internal/ds/matrix.h index 30b55cb08..ae42de340 100644 --- a/include/mgba/internal/ds/matrix.h +++ b/include/mgba/internal/ds/matrix.h @@ -17,7 +17,7 @@ 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 DSGXMtxTranslate(struct DSGXMatrix*, const int32_t* m); diff --git a/src/ds/gx.c b/src/ds/gx.c index 9bf3e58c6..e9d84ef84 100644 --- a/src/ds/gx.c +++ b/src/ds/gx.c @@ -136,9 +136,8 @@ static void _pullPipe(struct DSGX* gx) { } } -static void _updateVertexMatrix(struct DSGX* gx) { - memcpy(&gx->vertexMatrix, &gx->projMatrix, sizeof(gx->vertexMatrix)); - DSGXMtxMultiply(&gx->vertexMatrix, &gx->posMatrix); +static void _updateClipMatrix(struct DSGX* gx) { + DSGXMtxMultiply(&gx->clipMatrix, &gx->projMatrix, &gx->posMatrix); } 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.y = y; gx->currentVertex.z = z; - gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[0]); - gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[1]); - gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[2]); - gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[3]); + 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.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]; vbuf[gx->vertexIndex] = gx->currentVertex; @@ -240,7 +242,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate) if (first) { first = false; - } else if (cycles > cyclesLate) { + } else if (!gx->activeParams && cycles > cyclesLate) { break; } 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"); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; case DS_GX_CMD_MTX_POP: { 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"); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } case DS_GX_CMD_MTX_IDENTITY: @@ -334,7 +336,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate) DSGXMtxIdentity(&gx->texMatrix); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; case DS_GX_CMD_MTX_LOAD_4x4: { 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)); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } 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)); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } 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) { case 0: - DSGXMtxMultiply(&gx->projMatrix, &m); + DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix); break; case 2: - DSGXMtxMultiply(&gx->vecMatrix, &m); + DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); // Fall through case 1: - DSGXMtxMultiply(&gx->posMatrix, &m); + DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); break; case 3: - DSGXMtxMultiply(&gx->texMatrix, &m); + DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } 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; switch (gx->mtxMode) { case 0: - DSGXMtxMultiply(&gx->projMatrix, &m); + DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix); break; case 2: - DSGXMtxMultiply(&gx->vecMatrix, &m); + DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); // Fall through case 1: - DSGXMtxMultiply(&gx->posMatrix, &m); + DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); break; case 3: - DSGXMtxMultiply(&gx->texMatrix, &m); + DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } 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; switch (gx->mtxMode) { case 0: - memcpy(&gx->projMatrix, &m, sizeof(gx->projMatrix)); + DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix); break; case 2: - memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix)); + DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); // Fall through case 1: - memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix)); + DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); break; case 3: - memcpy(&gx->texMatrix, &m, sizeof(gx->projMatrix)); + DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix); break; } - _updateVertexMatrix(gx); + _updateClipMatrix(gx); break; } case DS_GX_CMD_MTX_TRANS: { @@ -666,7 +668,7 @@ void DSGXReset(struct DSGX* gx) { DSGXMtxIdentity(&gx->posMatrix); DSGXMtxIdentity(&gx->vecMatrix); - DSGXMtxIdentity(&gx->vertexMatrix); + DSGXMtxIdentity(&gx->clipMatrix); DSGXMtxIdentity(&gx->projMatrixStack); DSGXMtxIdentity(&gx->texMatrixStack); int i; @@ -682,6 +684,13 @@ void DSGXReset(struct DSGX* gx) { gx->pvMatrixPointer = 0; 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->outstandingCommand, 0, sizeof(gx->outstandingCommand)); gx->activeParams = 0; diff --git a/src/ds/matrix.c b/src/ds/matrix.c index f52556e2e..3b4b0de6b 100644 --- a/src/ds/matrix.c +++ b/src/ds/matrix.c @@ -32,25 +32,26 @@ void DSGXMtxIdentity(struct DSGXMatrix* mtx) { mtx->m[15] = MTX_ONE; } -void DSGXMtxMultiply(struct DSGXMatrix* mtx, const struct DSGXMatrix* m) { - struct DSGXMatrix out; - out.m[0] = _dot(&mtx->m[0], &m->m[0]); - out.m[1] = _dot(&mtx->m[1], &m->m[0]); - out.m[2] = _dot(&mtx->m[2], &m->m[0]); - out.m[3] = _dot(&mtx->m[3], &m->m[0]); - out.m[4] = _dot(&mtx->m[0], &m->m[4]); - out.m[5] = _dot(&mtx->m[1], &m->m[4]); - out.m[6] = _dot(&mtx->m[2], &m->m[4]); - out.m[7] = _dot(&mtx->m[3], &m->m[4]); - out.m[8] = _dot(&mtx->m[0], &m->m[8]); - out.m[9] = _dot(&mtx->m[1], &m->m[8]); - out.m[10] = _dot(&mtx->m[2], &m->m[8]); - out.m[11] = _dot(&mtx->m[3], &m->m[8]); - out.m[12] = _dot(&mtx->m[0], &m->m[12]); - out.m[13] = _dot(&mtx->m[1], &m->m[12]); - out.m[14] = _dot(&mtx->m[2], &m->m[12]); - out.m[15] = _dot(&mtx->m[3], &m->m[12]); - *mtx = out; +void DSGXMtxMultiply(struct DSGXMatrix* out, const struct DSGXMatrix* a, const struct DSGXMatrix* b) { + struct DSGXMatrix o; + // XXX: This is transposed because DS matrices are transposed + o.m[0] = _dot(&a->m[0], &b->m[0]); + o.m[1] = _dot(&a->m[1], &b->m[0]); + o.m[2] = _dot(&a->m[2], &b->m[0]); + o.m[3] = _dot(&a->m[3], &b->m[0]); + o.m[4] = _dot(&a->m[0], &b->m[4]); + o.m[5] = _dot(&a->m[1], &b->m[4]); + o.m[6] = _dot(&a->m[2], &b->m[4]); + o.m[7] = _dot(&a->m[3], &b->m[4]); + o.m[8] = _dot(&a->m[0], &b->m[8]); + o.m[9] = _dot(&a->m[1], &b->m[8]); + o.m[10] = _dot(&a->m[2], &b->m[8]); + o.m[11] = _dot(&a->m[3], &b->m[8]); + o.m[12] = _dot(&a->m[0], &b->m[12]); + o.m[13] = _dot(&a->m[1], &b->m[12]); + o.m[14] = _dot(&a->m[2], &b->m[12]); + o.m[15] = _dot(&a->m[3], &b->m[12]); + *out = o; } 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 } }; - DSGXMtxMultiply(mtx, &s); + DSGXMtxMultiply(mtx, &s, mtx); } 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 } }; - DSGXMtxMultiply(mtx, &t); + DSGXMtxMultiply(mtx, &t, mtx); }