DS GX: Clean up and unify texture mapping

This commit is contained in:
Vicki Pfau 2017-04-27 01:09:39 -07:00
parent 71916913e9
commit 78a22d6674
3 changed files with 27 additions and 28 deletions

View File

@ -3,6 +3,8 @@ Features:
- DS GX: Toon shading - DS GX: Toon shading
Bugfixes: Bugfixes:
- DS GX: Fix vertex texture transformation (fixes mgba.io/i/702) - DS GX: Fix vertex texture transformation (fixes mgba.io/i/702)
Misc:
- DS GX: Clean up and unify texture mapping
0.6.0: (Future) 0.6.0: (Future)
Features: Features:

View File

@ -113,8 +113,7 @@ struct DSGXVertex {
// Color/Texcoords // Color/Texcoords
uint16_t color; // 5.5.5 uint16_t color; // 5.5.5
int16_t s; // 12.4 int16_t st[2]; // 12.4
int16_t t; // 12.4
// Viewport coords // Viewport coords
int32_t viewCoord[4]; int32_t viewCoord[4];

View File

@ -382,17 +382,19 @@ static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) {
return sum >> 8LL; return sum >> 8LL;
} }
static int16_t _dotTexture(struct DSGXVertex* vertex, int mode, int32_t* col) { static int16_t _dotTexture(struct DSGX* gx, int16_t* input, int mode, int c) {
int64_t a; int64_t a;
int64_t b; int64_t b;
int64_t sum = 0; int64_t sum = 0;
struct DSGXVertex* vertex = &gx->currentVertex;
const int32_t* col = &gx->texMatrix.m[c];
switch (mode) { switch (mode) {
case 1: case 1:
a = col[0]; a = col[0];
b = vertex->s << 8; b = vertex->st[0] << 8;
sum = a * b; sum = a * b;
a = col[4]; a = col[4];
b = vertex->t << 8; b = vertex->st[1] << 8;
sum += a * b; sum += a * b;
a = col[8]; a = col[8];
b = MTX_ONE >> 4; b = MTX_ONE >> 4;
@ -401,22 +403,23 @@ static int16_t _dotTexture(struct DSGXVertex* vertex, int mode, int32_t* col) {
b = MTX_ONE >> 4; b = MTX_ONE >> 4;
sum += a * b; sum += a * b;
return sum >> 20; return sum >> 20;
case 2:
case 3: case 3:
a = col[0]; a = col[0];
b = vertex->coord[0]; b = input[0];
sum = a * b; sum = a * b;
a = col[4]; a = col[4];
b = vertex->coord[1]; b = input[1];
sum += a * b; sum += a * b;
a = col[8]; a = col[8];
b = vertex->coord[2]; b = input[2];
sum += a * b; sum += a * b;
a = col[12] << 12; a = vertex->st[c] << 12;
b = MTX_ONE; b = MTX_ONE;
sum += a * b; sum += a * b;
return sum >> 24; return sum >> 24;
} }
return 0; return input[c];
} }
static int32_t _dotFrac(int16_t x, int16_t y, int16_t z, int32_t* col) { static int32_t _dotFrac(int16_t x, int16_t y, int16_t z, int32_t* col) {
@ -456,17 +459,11 @@ static void _emitVertex(struct DSGX* gx, uint16_t x, uint16_t y, uint16_t z) {
gx->currentVertex.viewCoord[3] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]); gx->currentVertex.viewCoord[3] = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]);
if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 0) { if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 0) {
gx->currentVertex.vs = gx->currentVertex.s; gx->currentVertex.vs = gx->currentVertex.st[0];
gx->currentVertex.vt = gx->currentVertex.t; gx->currentVertex.vt = gx->currentVertex.st[1];
} else if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 3) { } else if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 3) {
int32_t m12 = gx->texMatrix.m[12]; gx->currentVertex.vs = _dotTexture(gx, gx->currentVertex.coord, 3, 0);
int32_t m13 = gx->texMatrix.m[13]; gx->currentVertex.vt = _dotTexture(gx, gx->currentVertex.coord, 3, 1);
gx->texMatrix.m[12] = gx->currentVertex.s;
gx->texMatrix.m[13] = gx->currentVertex.t;
gx->currentVertex.vs = _dotTexture(&gx->currentVertex, 3, &gx->texMatrix.m[0]);
gx->currentVertex.vt = _dotTexture(&gx->currentVertex, 3, &gx->texMatrix.m[1]);
gx->texMatrix.m[12] = m12;
gx->texMatrix.m[13] = m13;
} }
gx->pendingVertices[gx->pendingVertexIndex] = gx->currentVertex; gx->pendingVertices[gx->pendingVertexIndex] = gx->currentVertex;
@ -987,8 +984,9 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
y >>= 3; y >>= 3;
z >>= 3; z >>= 3;
if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 2) { if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 2) {
gx->currentVertex.vs = (_dotFrac(x, y, z, &gx->texMatrix.m[0]) + gx->currentVertex.s) >> 11; int16_t input[] = { x, y, z };
gx->currentVertex.vt = (_dotFrac(x, y, z, &gx->texMatrix.m[1]) + gx->currentVertex.t) >> 11; gx->currentVertex.vs = _dotTexture(gx, input, 2, 0);
gx->currentVertex.vt = _dotTexture(gx, input, 2, 1);
} }
int16_t nx = _dotFrac(x, y, z, &gx->vecMatrix.m[0]); int16_t nx = _dotFrac(x, y, z, &gx->vecMatrix.m[0]);
int16_t ny = _dotFrac(x, y, z, &gx->vecMatrix.m[1]); int16_t ny = _dotFrac(x, y, z, &gx->vecMatrix.m[1]);
@ -1054,13 +1052,13 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
break; break;
} }
case DS_GX_CMD_TEXCOORD: case DS_GX_CMD_TEXCOORD:
gx->currentVertex.s = entry.params[0]; gx->currentVertex.st[0] = entry.params[0];
gx->currentVertex.s |= entry.params[1] << 8; gx->currentVertex.st[0] |= entry.params[1] << 8;
gx->currentVertex.t = entry.params[2]; gx->currentVertex.st[1] = entry.params[2];
gx->currentVertex.t |= entry.params[3] << 8; gx->currentVertex.st[1] |= entry.params[3] << 8;
if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 1) { if (DSGXTexParamsGetCoordTfMode(gx->currentPoly.texParams) == 1) {
gx->currentVertex.vs = _dotTexture(&gx->currentVertex, 1, &gx->texMatrix.m[0]); gx->currentVertex.vs = _dotTexture(gx, NULL, 1, 0);
gx->currentVertex.vt = _dotTexture(&gx->currentVertex, 1, &gx->texMatrix.m[1]); gx->currentVertex.vt = _dotTexture(gx, NULL, 1, 1);
} }
break; break;
case DS_GX_CMD_VTX_16: { case DS_GX_CMD_VTX_16: {