all repos — mgba @ 372b4387c46e731ec735d2d5b147603e0f40a34e

mGBA Game Boy Advance Emulator

DS GX: Implement clear color
Vicki Pfau vi@endrift.com
Wed, 05 Apr 2017 23:07:31 -0700
commit

372b4387c46e731ec735d2d5b147603e0f40a34e

parent

a1b30faef39beac5d9dd9486784973e7ce9c4a8e

M include/mgba/internal/ds/gx.hinclude/mgba/internal/ds/gx.h

@@ -139,6 +139,7 @@ void (*invalidateTex)(struct DSGXRenderer* renderer, int slot);

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];
M include/mgba/internal/ds/gx/software.hinclude/mgba/internal/ds/gx/software.h

@@ -93,6 +93,8 @@ int32_t* depthBuffer;

uint8_t* stencilBuffer; color_t* scanlineCache; int sort; + uint16_t clearStencil; + color_t clearColor; bool flushPending; struct DSGXVertex* verts;
M src/ds/gx.csrc/ds/gx.c

@@ -20,6 +20,7 @@ static void DSGXDummyRendererInvalidateTex(struct DSGXRenderer* renderer, int slot);

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 @@ .invalidateTex = DSGXDummyRendererInvalidateTex,

.setRAM = DSGXDummyRendererSetRAM, .drawScanline = DSGXDummyRendererDrawScanline, .getScanline = DSGXDummyRendererGetScanline, + .writeRegister = DSGXDummyRendererWriteRegister, }; static void _pullPipe(struct DSGX* gx) {

@@ -1436,6 +1438,10 @@ switch (address) {

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) {

@@ -1482,6 +1488,10 @@ break;

case DS9_REG_GXSTAT_LO: 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) {

@@ -1583,3 +1593,10 @@ UNUSED(y);

*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 +}
M src/ds/gx/software.csrc/ds/gx/software.c

@@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#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 slot);

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 @@ renderer->d.invalidateTex = DSGXSoftwareRendererInvalidateTex;

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 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 @@ poly->poly = &polys[i];

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, const color_t** output) {

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; + } +}