mirror of https://github.com/mgba-emu/mgba.git
DS GX: Update matrix transforms
This commit is contained in:
parent
0d5a15380b
commit
9ad56b1b79
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
67
src/ds/gx.c
67
src/ds/gx.c
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue