DS GX: Allow viewport to change in the middle of a frame

This commit is contained in:
Vicki Pfau 2017-04-12 21:07:39 -07:00
parent 1882b15567
commit 516143b170
4 changed files with 16 additions and 15 deletions

View File

@ -18,6 +18,7 @@ Bugfixes:
- DS Video: Fix affine transformations in video capture
- DS GX: Fix bitmap textures when no palette is mapped (fixes mgba.io/i/628)
- DS GX: Don't reset state between buffer swaps (fixes mgba.io/i/642)
- DS GX: Allow viewport to change in the middle of a frame
Misc:
- DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586)
- DS Memory: Ensure DS9 I/O is 8-byte aligned

View File

@ -120,6 +120,11 @@ struct DSGXVertex {
int32_t viewCoord[4];
int16_t vs; // 12.4
int16_t vt; // 12.4
int viewportX;
int viewportY;
int viewportWidth;
int viewportHeight;
};
struct DSGXPolygon {
@ -143,11 +148,6 @@ struct DSGXRenderer {
uint16_t* tex[4];
uint16_t* texPal[6];
int viewportX;
int viewportY;
int viewportWidth;
int viewportHeight;
};
struct DSGXLight {

View File

@ -1180,10 +1180,10 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
gx->viewportY2 = (uint8_t) entry.params[3];
gx->viewportWidth = gx->viewportX2 - gx->viewportX1 + 1;
gx->viewportHeight = gx->viewportY2 - gx->viewportY1 + 1;
gx->renderer->viewportX = gx->viewportX1;
gx->renderer->viewportY = gx->viewportY1;
gx->renderer->viewportWidth = gx->viewportWidth;
gx->renderer->viewportHeight = gx->viewportHeight;
gx->currentVertex.viewportX = gx->viewportX1;
gx->currentVertex.viewportY = gx->viewportY1;
gx->currentVertex.viewportWidth = gx->viewportWidth;
gx->currentVertex.viewportHeight = gx->viewportHeight;
break;
case DS_GX_CMD_BOX_TEST:
gxstat = DSRegGXSTATClearTestBusy(gxstat);

View File

@ -487,8 +487,8 @@ static void _preparePoly(struct DSGXRenderer* renderer, struct DSGXVertex* verts
v0w = 1;
}
int32_t v0x = (v0->viewCoord[0] + v0w) * (int64_t) (renderer->viewportWidth << 12) / (v0w * 2) + (renderer->viewportX << 12);
int32_t v0y = (-v0->viewCoord[1] + v0w) * (int64_t) (renderer->viewportHeight << 12) / (v0w * 2) + (renderer->viewportY << 12);
int32_t v0x = (v0->viewCoord[0] + v0w) * (int64_t) (v0->viewportWidth << 12) / (v0w * 2) + (v0->viewportX << 12);
int32_t v0y = (-v0->viewCoord[1] + v0w) * (int64_t) (v0->viewportHeight << 12) / (v0w * 2) + (v0->viewportY << 12);
if (poly->minY > v0y >> 12) {
poly->minY = v0y >> 12;
}
@ -504,8 +504,8 @@ static void _preparePoly(struct DSGXRenderer* renderer, struct DSGXVertex* verts
if (!v1w) {
v1w = 1;
}
int32_t v1x = (v1->viewCoord[0] + v1w) * (int64_t) (renderer->viewportWidth << 12) / (v1w * 2) + (renderer->viewportX << 12);
int32_t v1y = (-v1->viewCoord[1] + v1w) * (int64_t) (renderer->viewportHeight << 12) / (v1w * 2) + (renderer->viewportY << 12);
int32_t v1x = (v1->viewCoord[0] + v1w) * (int64_t) (v1->viewportWidth << 12) / (v1w * 2) + (v1->viewportX << 12);
int32_t v1y = (-v1->viewCoord[1] + v1w) * (int64_t) (v1->viewportHeight << 12) / (v1w * 2) + (v1->viewportY << 12);
if (poly->minY > v1y >> 12) {
poly->minY = v1y >> 12;
}
@ -563,8 +563,8 @@ static void _preparePoly(struct DSGXRenderer* renderer, struct DSGXVertex* verts
if (!v1w) {
v1w = 1;
}
int32_t v1x = (v1->viewCoord[0] + v1w) * (int64_t) (renderer->viewportWidth << 12) / (v1w * 2) + (renderer->viewportX << 12);
int32_t v1y = (-v1->viewCoord[1] + v1w) * (int64_t) (renderer->viewportHeight << 12) / (v1w * 2) + (renderer->viewportY << 12);
int32_t v1x = (v1->viewCoord[0] + v1w) * (int64_t) (v1->viewportWidth << 12) / (v1w * 2) + (v1->viewportX << 12);
int32_t v1y = (-v1->viewCoord[1] + v1w) * (int64_t) (v1->viewportHeight << 12) / (v1w * 2) + (v1->viewportY << 12);
if (poly->minY > v1y >> 12) {
poly->minY = v1y >> 12;