mirror of https://github.com/mgba-emu/mgba.git
DS GX: Implement MTX_STORE/MTX_RESTORE and fix coordinates
This commit is contained in:
parent
d5d7349259
commit
2b64d45906
82
src/ds/gx.c
82
src/ds/gx.c
|
@ -315,7 +315,6 @@ 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;
|
||||||
}
|
}
|
||||||
_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];
|
||||||
|
@ -342,6 +341,45 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
_updateClipMatrix(gx);
|
_updateClipMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS_GX_CMD_MTX_STORE: {
|
||||||
|
int8_t offset = entry.params[0] & 0x1F;
|
||||||
|
// TODO: overflow
|
||||||
|
switch (gx->mtxMode) {
|
||||||
|
case 0:
|
||||||
|
memcpy(&gx->projMatrixStack, &gx->projMatrix, sizeof(gx->projMatrixStack));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
memcpy(&gx->posMatrixStack[offset], &gx->posMatrix, sizeof(gx->posMatrix));
|
||||||
|
// Fall through
|
||||||
|
case 2:
|
||||||
|
memcpy(&gx->vecMatrixStack[offset], &gx->vecMatrix, sizeof(gx->vecMatrix));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mLOG(DS_GX, STUB, "Unimplemented GX MTX_STORE mode");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_MTX_RESTORE: {
|
||||||
|
int8_t offset = entry.params[0] & 0x1F;
|
||||||
|
// TODO: overflow
|
||||||
|
switch (gx->mtxMode) {
|
||||||
|
case 0:
|
||||||
|
memcpy(&gx->projMatrix, &gx->projMatrixStack, sizeof(gx->projMatrix));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
memcpy(&gx->posMatrix, &gx->posMatrixStack[offset], sizeof(gx->posMatrix));
|
||||||
|
// Fall through
|
||||||
|
case 2:
|
||||||
|
memcpy(&gx->vecMatrix, &gx->vecMatrixStack[offset], sizeof(gx->vecMatrix));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mLOG(DS_GX, STUB, "Unimplemented GX MTX_RESTORE mode");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_updateClipMatrix(gx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DS_GX_CMD_MTX_IDENTITY:
|
case DS_GX_CMD_MTX_IDENTITY:
|
||||||
switch (gx->mtxMode) {
|
switch (gx->mtxMode) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -587,10 +625,10 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_VTX_10: {
|
case DS_GX_CMD_VTX_10: {
|
||||||
int32_t xyz = gx->activeEntries[0].params[0];
|
int32_t xyz = entry.params[0];
|
||||||
xyz |= gx->activeEntries[0].params[1] << 8;
|
xyz |= entry.params[1] << 8;
|
||||||
xyz |= gx->activeEntries[0].params[2] << 16;
|
xyz |= entry.params[2] << 16;
|
||||||
xyz |= gx->activeEntries[0].params[3] << 24;
|
xyz |= entry.params[3] << 24;
|
||||||
int16_t x = (xyz << 6) & 0xFFC0;
|
int16_t x = (xyz << 6) & 0xFFC0;
|
||||||
int16_t y = (xyz >> 4) & 0xFFC0;
|
int16_t y = (xyz >> 4) & 0xFFC0;
|
||||||
int16_t z = (xyz >> 14) & 0xFFC0;
|
int16_t z = (xyz >> 14) & 0xFFC0;
|
||||||
|
@ -598,29 +636,39 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_VTX_XY: {
|
case DS_GX_CMD_VTX_XY: {
|
||||||
int16_t x = gx->activeEntries[0].params[0];
|
int16_t x = entry.params[0];
|
||||||
x |= gx->activeEntries[0].params[1] << 8;
|
x |= entry.params[1] << 8;
|
||||||
int16_t y = gx->activeEntries[0].params[2];
|
int16_t y = entry.params[2];
|
||||||
y |= gx->activeEntries[0].params[3] << 8;
|
y |= entry.params[3] << 8;
|
||||||
_emitVertex(gx, x, y, gx->currentVertex.z);
|
_emitVertex(gx, x, y, gx->currentVertex.z);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_VTX_XZ: {
|
case DS_GX_CMD_VTX_XZ: {
|
||||||
int16_t x = gx->activeEntries[0].params[0];
|
int16_t x = entry.params[0];
|
||||||
x |= gx->activeEntries[0].params[1] << 8;
|
x |= entry.params[1] << 8;
|
||||||
int16_t z = gx->activeEntries[0].params[2];
|
int16_t z = entry.params[2];
|
||||||
z |= gx->activeEntries[0].params[3] << 8;
|
z |= entry.params[3] << 8;
|
||||||
_emitVertex(gx, x, gx->currentVertex.y, z);
|
_emitVertex(gx, x, gx->currentVertex.y, z);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_VTX_YZ: {
|
case DS_GX_CMD_VTX_YZ: {
|
||||||
int16_t y = gx->activeEntries[0].params[0];
|
int16_t y = entry.params[0];
|
||||||
y |= gx->activeEntries[0].params[1] << 8;
|
y |= entry.params[1] << 8;
|
||||||
int16_t z = gx->activeEntries[0].params[2];
|
int16_t z = entry.params[2];
|
||||||
z |= gx->activeEntries[0].params[3] << 8;
|
z |= entry.params[3] << 8;
|
||||||
_emitVertex(gx, gx->currentVertex.x, y, z);
|
_emitVertex(gx, gx->currentVertex.x, y, z);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS_GX_CMD_VTX_DIFF: {
|
||||||
|
int32_t xyz = entry.params[0];
|
||||||
|
xyz |= entry.params[1] << 8;
|
||||||
|
xyz |= entry.params[2] << 16;
|
||||||
|
xyz |= entry.params[3] << 24;
|
||||||
|
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));
|
||||||
|
}
|
||||||
case DS_GX_CMD_POLYGON_ATTR:
|
case DS_GX_CMD_POLYGON_ATTR:
|
||||||
gx->currentPoly.polyParams = entry.params[0];
|
gx->currentPoly.polyParams = entry.params[0];
|
||||||
gx->currentPoly.polyParams |= entry.params[1] << 8;
|
gx->currentPoly.polyParams |= entry.params[1] << 8;
|
||||||
|
|
Loading…
Reference in New Issue