DS GX: Implement clear color

This commit is contained in:
Vicki Pfau 2017-04-05 23:07:31 -07:00
parent a1b30faef3
commit 372b4387c4
4 changed files with 53 additions and 2 deletions

View File

@ -139,6 +139,7 @@ struct DSGXRenderer {
void (*setRAM)(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount, bool wSort);
void (*drawScanline)(struct DSGXRenderer* renderer, int y);
void (*getScanline)(struct DSGXRenderer* renderer, int y, const color_t** output);
void (*writeRegister)(struct DSGXRenderer* renderer, uint32_t address, uint16_t value);
uint16_t* tex[4];
uint16_t* texPal[6];

View File

@ -93,6 +93,8 @@ struct DSGXSoftwareRenderer {
uint8_t* stencilBuffer;
color_t* scanlineCache;
int sort;
uint16_t clearStencil;
color_t clearColor;
bool flushPending;
struct DSGXVertex* verts;

View File

@ -20,6 +20,7 @@ static void DSGXDummyRendererInvalidateTex(struct DSGXRenderer* renderer, int sl
static void DSGXDummyRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount, bool wSort);
static void DSGXDummyRendererDrawScanline(struct DSGXRenderer* renderer, int y);
static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, const color_t** output);
static void DSGXDummyRendererWriteRegister(struct DSGXRenderer* renderer, uint32_t address, uint16_t value);
static void DSGXWriteFIFO(struct DSGX* gx, struct DSGXEntry entry);
@ -111,6 +112,7 @@ static struct DSGXRenderer dummyRenderer = {
.setRAM = DSGXDummyRendererSetRAM,
.drawScanline = DSGXDummyRendererDrawScanline,
.getScanline = DSGXDummyRendererGetScanline,
.writeRegister = DSGXDummyRendererWriteRegister,
};
static void _pullPipe(struct DSGX* gx) {
@ -1436,6 +1438,10 @@ uint16_t DSGXWriteRegister(struct DSGX* gx, uint32_t address, uint16_t value) {
case DS9_REG_DISP3DCNT:
mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
break;
case DS9_REG_CLEAR_COLOR_LO:
case DS9_REG_CLEAR_COLOR_HI:
gx->renderer->writeRegister(gx->renderer, address, value);
break;
case DS9_REG_GXSTAT_LO:
value = DSRegGXSTATIsMatrixStackError(value);
if (value) {
@ -1483,6 +1489,10 @@ uint32_t DSGXWriteRegister32(struct DSGX* gx, uint32_t address, uint32_t value)
value = (value & 0xFFFF0000) | DSGXWriteRegister(gx, DS9_REG_GXSTAT_LO, value);
value = (value & 0x0000FFFF) | (DSGXWriteRegister(gx, DS9_REG_GXSTAT_HI, value >> 16) << 16);
break;
case DS9_REG_CLEAR_COLOR_LO:
gx->renderer->writeRegister(gx->renderer, address, value);
gx->renderer->writeRegister(gx->renderer, address + 2, value >> 16);
break;
default:
if (address < DS9_REG_GXFIFO_00) {
mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%08X", address, value);
@ -1583,3 +1593,10 @@ static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, c
*output = NULL;
// Nothing to do
}
static void DSGXDummyRendererWriteRegister(struct DSGXRenderer* renderer, uint32_t address, uint16_t value) {
UNUSED(renderer);
UNUSED(address);
UNUSED(value);
// Nothing to do
}

View File

@ -6,6 +6,7 @@
#include <mgba/internal/ds/gx/software.h>
#include <mgba-util/memory.h>
#include <mgba/internal/ds/io.h>
#include "gba/renderers/software-private.h"
DEFINE_VECTOR(DSGXSoftwarePolygonList, struct DSGXSoftwarePolygon);
@ -18,6 +19,7 @@ static void DSGXSoftwareRendererInvalidateTex(struct DSGXRenderer* renderer, int
static void DSGXSoftwareRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount, bool wSort);
static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int y);
static void DSGXSoftwareRendererGetScanline(struct DSGXRenderer* renderer, int y, const color_t** output);
static void DSGXSoftwareRendererWriteRegister(struct DSGXRenderer* renderer, uint32_t address, uint16_t value);
static void _expandColor(uint16_t c15, uint8_t* r, uint8_t* g, uint8_t* b) {
*r = ((c15 << 1) & 0x3E) | 1;
@ -407,6 +409,7 @@ void DSGXSoftwareRendererCreate(struct DSGXSoftwareRenderer* renderer) {
renderer->d.setRAM = DSGXSoftwareRendererSetRAM;
renderer->d.drawScanline = DSGXSoftwareRendererDrawScanline;
renderer->d.getScanline = DSGXSoftwareRendererGetScanline;
renderer->d.writeRegister = DSGXSoftwareRendererWriteRegister;
}
static void DSGXSoftwareRendererInit(struct DSGXRenderer* renderer) {
@ -420,6 +423,8 @@ static void DSGXSoftwareRendererInit(struct DSGXRenderer* renderer) {
static void DSGXSoftwareRendererReset(struct DSGXRenderer* renderer) {
struct DSGXSoftwareRenderer* softwareRenderer = (struct DSGXSoftwareRenderer*) renderer;
softwareRenderer->clearColor = 0;
softwareRenderer->clearStencil = 0;
}
static void DSGXSoftwareRendererDeinit(struct DSGXRenderer* renderer) {
@ -705,13 +710,22 @@ static void DSGXSoftwareRendererSetRAM(struct DSGXRenderer* renderer, struct DSG
poly->polyId = DSGXSoftwarePolygonListSize(&softwareRenderer->activePolys) - 1;
}
memset(softwareRenderer->scanlineCache, 0, sizeof(color_t) * DS_VIDEO_VERTICAL_PIXELS * DS_VIDEO_HORIZONTAL_PIXELS);
memset(softwareRenderer->stencilBuffer, 0, sizeof(uint8_t) * DS_VIDEO_VERTICAL_PIXELS * DS_VIDEO_HORIZONTAL_PIXELS);
color_t clearColor = softwareRenderer->clearColor;
uint16_t clearStencil = softwareRenderer->clearStencil;
for (i = 0; i < DS_VIDEO_VERTICAL_PIXELS * DS_VIDEO_HORIZONTAL_PIXELS ; i += 4) {
softwareRenderer->depthBuffer[i] = INT32_MAX;
softwareRenderer->depthBuffer[i + 1] = INT32_MAX;
softwareRenderer->depthBuffer[i + 2] = INT32_MAX;
softwareRenderer->depthBuffer[i + 3] = INT32_MAX;
softwareRenderer->scanlineCache[i] = clearColor;
softwareRenderer->scanlineCache[i + 1] = clearColor;
softwareRenderer->scanlineCache[i + 2] = clearColor;
softwareRenderer->scanlineCache[i + 3] = clearColor;
softwareRenderer->stencilBuffer[i] = clearStencil;
softwareRenderer->stencilBuffer[i + 1] = clearStencil;
softwareRenderer->stencilBuffer[i + 2] = clearStencil;
softwareRenderer->stencilBuffer[i + 3] = clearStencil;
}
softwareRenderer->flushPending = true;
}
@ -761,3 +775,20 @@ static void DSGXSoftwareRendererGetScanline(struct DSGXRenderer* renderer, int y
struct DSGXSoftwareRenderer* softwareRenderer = (struct DSGXSoftwareRenderer*) renderer;
*output = &softwareRenderer->scanlineCache[DS_VIDEO_HORIZONTAL_PIXELS * y];
}
static void DSGXSoftwareRendererWriteRegister(struct DSGXRenderer* renderer, uint32_t address, uint16_t value) {
struct DSGXSoftwareRenderer* softwareRenderer = (struct DSGXSoftwareRenderer*) renderer;
switch (address) {
case DS9_REG_CLEAR_COLOR_LO:
softwareRenderer->clearColor &= 0xFF000000;
softwareRenderer->clearColor |= (value & 0x001F) << 3;
softwareRenderer->clearColor |= (value & 0x03E0) << 6;
softwareRenderer->clearColor |= (value & 0x7C00) << 9;
break;
case DS9_REG_CLEAR_COLOR_HI:
softwareRenderer->clearColor &= 0x00FFFFFF;
softwareRenderer->clearColor |= (value & 0x001F) << 27;
softwareRenderer->clearStencil = (value & 0x3F00) >> 8;
break;
}
}