DS GX: Vector result (fixes #562)

This commit is contained in:
Vicki Pfau 2022-05-29 23:36:26 -07:00
parent 8337786b64
commit 8a6742de4b
4 changed files with 51 additions and 3 deletions

View File

@ -3,6 +3,7 @@ Features:
- DS GX: Toon shading - DS GX: Toon shading
- DS GX: Clear depth - DS GX: Clear depth
- DS GX: Position test - DS GX: Position test
- DS GX: Vector result
Bugfixes: Bugfixes:
- DS GX: Fix vertex texture transformation (fixes mgba.io/i/702) - DS GX: Fix vertex texture transformation (fixes mgba.io/i/702)
- DS GX: Automatically normalize winding culling calculations (fixes mgba.io/i/699) - DS GX: Automatically normalize winding culling calculations (fixes mgba.io/i/699)

View File

@ -555,7 +555,6 @@ enum DS9IORegisters {
DS9_REG_VECMTX_RESULT_0F = 0x69E, DS9_REG_VECMTX_RESULT_0F = 0x69E,
DS9_REG_VECMTX_RESULT_10 = 0x6A0, DS9_REG_VECMTX_RESULT_10 = 0x6A0,
DS9_REG_VECMTX_RESULT_11 = 0x6A2, DS9_REG_VECMTX_RESULT_11 = 0x6A2,
DS9_REG_VECMTX_RESULT_12 = 0x6A4,
DS9_REG_MAX = 0x106E, DS9_REG_MAX = 0x106E,

View File

@ -162,6 +162,27 @@ static void _updateClipMatrix(struct DSGX* gx) {
gx->p->memory.io9[DS9_REG_CLIPMTX_RESULT_1F >> 1] = gx->clipMatrix.m[15] >> 16; gx->p->memory.io9[DS9_REG_CLIPMTX_RESULT_1F >> 1] = gx->clipMatrix.m[15] >> 16;
} }
static void _updateVecMatrix(struct DSGX* gx) {
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_00 >> 1] = gx->vecMatrix.m[0];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_01 >> 1] = gx->vecMatrix.m[0] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_02 >> 1] = gx->vecMatrix.m[1];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_03 >> 1] = gx->vecMatrix.m[1] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_04 >> 1] = gx->vecMatrix.m[2];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_05 >> 1] = gx->vecMatrix.m[2] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_06 >> 1] = gx->vecMatrix.m[4];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_07 >> 1] = gx->vecMatrix.m[4] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_08 >> 1] = gx->vecMatrix.m[5];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_09 >> 1] = gx->vecMatrix.m[5] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0A >> 1] = gx->vecMatrix.m[6];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0B >> 1] = gx->vecMatrix.m[6] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0C >> 1] = gx->vecMatrix.m[8];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0D >> 1] = gx->vecMatrix.m[8] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0E >> 1] = gx->vecMatrix.m[9];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_0F >> 1] = gx->vecMatrix.m[9] >> 16;
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_10 >> 1] = gx->vecMatrix.m[10];
gx->p->memory.io9[DS9_REG_VECMTX_RESULT_11 >> 1] = gx->vecMatrix.m[10] >> 16;
}
static inline int32_t _lerp(int32_t x0, int32_t x1, int32_t q, int64_t r) { static inline int32_t _lerp(int32_t x0, int32_t x1, int32_t q, int64_t r) {
int64_t x = x1 - x0; int64_t x = x1 - x0;
x *= q; x *= q;
@ -743,6 +764,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
gx->pvMatrixPointer -= offset; gx->pvMatrixPointer -= offset;
memcpy(&gx->vecMatrix, &gx->vecMatrixStack[gx->pvMatrixPointer & 0x1F], sizeof(gx->vecMatrix)); memcpy(&gx->vecMatrix, &gx->vecMatrixStack[gx->pvMatrixPointer & 0x1F], sizeof(gx->vecMatrix));
memcpy(&gx->posMatrix, &gx->posMatrixStack[gx->pvMatrixPointer & 0x1F], sizeof(gx->posMatrix)); memcpy(&gx->posMatrix, &gx->posMatrixStack[gx->pvMatrixPointer & 0x1F], sizeof(gx->posMatrix));
_updateVecMatrix(gx);
break; break;
case 3: case 3:
mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode"); mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode");
@ -780,6 +802,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
case 2: case 2:
memcpy(&gx->vecMatrix, &gx->vecMatrixStack[offset], sizeof(gx->vecMatrix)); memcpy(&gx->vecMatrix, &gx->vecMatrixStack[offset], sizeof(gx->vecMatrix));
memcpy(&gx->posMatrix, &gx->posMatrixStack[offset], sizeof(gx->posMatrix)); memcpy(&gx->posMatrix, &gx->posMatrixStack[offset], sizeof(gx->posMatrix));
_updateVecMatrix(gx);
break; break;
case 3: case 3:
mLOG(DS_GX, STUB, "Unimplemented GX MTX_RESTORE mode"); mLOG(DS_GX, STUB, "Unimplemented GX MTX_RESTORE mode");
@ -795,6 +818,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
DSGXMtxIdentity(&gx->vecMatrix); DSGXMtxIdentity(&gx->vecMatrix);
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
DSGXMtxIdentity(&gx->posMatrix); DSGXMtxIdentity(&gx->posMatrix);
@ -820,6 +844,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix)); memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix));
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix)); memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix));
@ -850,6 +875,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix)); memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix));
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix)); memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix));
@ -876,6 +902,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
@ -906,6 +933,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
@ -939,6 +967,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix); DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix); DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
@ -970,6 +999,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
case 2: case 2:
DSGXMtxTranslate(&gx->vecMatrix, m); DSGXMtxTranslate(&gx->vecMatrix, m);
_updateVecMatrix(gx);
// Fall through // Fall through
case 1: case 1:
DSGXMtxTranslate(&gx->posMatrix, m); DSGXMtxTranslate(&gx->posMatrix, m);

View File

@ -604,7 +604,7 @@ void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
} else if ((address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) || address == DS9_REG_B_MASTER_BRIGHT) { } else if ((address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) || address == DS9_REG_B_MASTER_BRIGHT) {
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
} else if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) { } else if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_11) || address == DS9_REG_DISP3DCNT) {
value = DSGXWriteRegister(&ds->gx, address, value); value = DSGXWriteRegister(&ds->gx, address, value);
} else { } else {
uint16_t oldValue; uint16_t oldValue;
@ -719,7 +719,7 @@ void DS9IOWrite8(struct DS* ds, uint32_t address, uint8_t value) {
} }
void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value) { void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value) {
if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) { if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_11) || address == DS9_REG_DISP3DCNT) {
value = DSGXWriteRegister32(&ds->gx, address, value); value = DSGXWriteRegister32(&ds->gx, address, value);
} else { } else {
switch (address) { switch (address) {
@ -900,6 +900,24 @@ uint16_t DS9IORead(struct DS* ds, uint32_t address) {
case DS9_REG_CLIPMTX_RESULT_1D: case DS9_REG_CLIPMTX_RESULT_1D:
case DS9_REG_CLIPMTX_RESULT_1E: case DS9_REG_CLIPMTX_RESULT_1E:
case DS9_REG_CLIPMTX_RESULT_1F: case DS9_REG_CLIPMTX_RESULT_1F:
case DS9_REG_VECMTX_RESULT_00:
case DS9_REG_VECMTX_RESULT_01:
case DS9_REG_VECMTX_RESULT_02:
case DS9_REG_VECMTX_RESULT_03:
case DS9_REG_VECMTX_RESULT_04:
case DS9_REG_VECMTX_RESULT_05:
case DS9_REG_VECMTX_RESULT_06:
case DS9_REG_VECMTX_RESULT_07:
case DS9_REG_VECMTX_RESULT_08:
case DS9_REG_VECMTX_RESULT_09:
case DS9_REG_VECMTX_RESULT_0A:
case DS9_REG_VECMTX_RESULT_0B:
case DS9_REG_VECMTX_RESULT_0C:
case DS9_REG_VECMTX_RESULT_0D:
case DS9_REG_VECMTX_RESULT_0E:
case DS9_REG_VECMTX_RESULT_0F:
case DS9_REG_VECMTX_RESULT_10:
case DS9_REG_VECMTX_RESULT_11:
case DS9_REG_B_BG0CNT: case DS9_REG_B_BG0CNT:
case DS9_REG_B_BG1CNT: case DS9_REG_B_BG1CNT:
case DS9_REG_B_BG2CNT: case DS9_REG_B_BG2CNT: