mirror of https://github.com/mgba-emu/mgba.git
DS GX: Implement clear color
This commit is contained in:
parent
a1b30faef3
commit
372b4387c4
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
17
src/ds/gx.c
17
src/ds/gx.c
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue