DS GX: Implement MTX_STORE/MTX_RESTORE and fix coordinates

This commit is contained in:
Vicki Pfau 2017-03-01 02:10:51 -08:00
parent d5d7349259
commit 2b64d45906
1 changed files with 65 additions and 17 deletions

View File

@ -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;