mirror of https://github.com/mgba-emu/mgba.git
DS GX: Vector result (fixes #562)
This commit is contained in:
parent
8337786b64
commit
8a6742de4b
1
CHANGES
1
CHANGES
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
30
src/ds/gx.c
30
src/ds/gx.c
|
@ -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);
|
||||||
|
|
22
src/ds/io.c
22
src/ds/io.c
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue