mirror of https://github.com/mgba-emu/mgba.git
DS GX: Stub out GX renderer
This commit is contained in:
parent
2f0ab002e2
commit
e8bfc7bcca
|
@ -10,6 +10,7 @@
|
|||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
#include <mgba/core/log.h>
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba-util/circle-buffer.h>
|
||||
|
@ -80,9 +81,36 @@ struct DSGXEntry {
|
|||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct DSGXVertex {
|
||||
// Viewport coords
|
||||
int32_t x; // 16.16
|
||||
int32_t y; // 16.16
|
||||
int32_t z; // 16.16
|
||||
uint16_t color;
|
||||
// Texcoords
|
||||
int16_t s; // 12.4
|
||||
int16_t t; // 12.4
|
||||
};
|
||||
|
||||
struct DSGXPolygon {
|
||||
int verts;
|
||||
unsigned vertIds[4];
|
||||
};
|
||||
|
||||
struct DSGXRenderer {
|
||||
void (*init)(struct DSGXRenderer* renderer);
|
||||
void (*reset)(struct DSGXRenderer* renderer);
|
||||
void (*deinit)(struct DSGXRenderer* renderer);
|
||||
|
||||
void (*setRAM)(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount);
|
||||
void (*drawScanline)(struct DSGXRenderer* renderer, int y);
|
||||
void (*getScanline)(struct DSGXRenderer* renderer, int y, color_t** output);
|
||||
};
|
||||
|
||||
struct DS;
|
||||
struct DSGX {
|
||||
struct DS* p;
|
||||
struct DSGXRenderer* renderer;
|
||||
struct CircleBuffer fifo;
|
||||
struct CircleBuffer pipe;
|
||||
|
||||
|
@ -92,11 +120,15 @@ struct DSGX {
|
|||
uint8_t outstandingCommand[4];
|
||||
|
||||
bool swapBuffers;
|
||||
int bufferIndex;
|
||||
struct DSGXVertex* vertexBuffer[2];
|
||||
struct DSGXPolygon* polygonBuffer[2];
|
||||
};
|
||||
|
||||
void DSGXInit(struct DSGX*);
|
||||
void DSGXDeinit(struct DSGX*);
|
||||
void DSGXReset(struct DSGX*);
|
||||
void DSGXAssociateRenderer(struct DSGX* video, struct DSGXRenderer* renderer);
|
||||
|
||||
uint16_t DSGXWriteRegister(struct DSGX*, uint32_t address, uint16_t value);
|
||||
uint32_t DSGXWriteRegister32(struct DSGX*, uint32_t address, uint32_t value);
|
||||
|
|
|
@ -70,6 +70,7 @@ DECL_BITFIELD(DSRegisterMASTER_BRIGHT, uint16_t);
|
|||
DECL_BITS(DSRegisterMASTER_BRIGHT, Y, 0, 5);
|
||||
DECL_BITS(DSRegisterMASTER_BRIGHT, Mode, 14, 2);
|
||||
|
||||
struct DSGX;
|
||||
struct DSVideoRenderer {
|
||||
void (*init)(struct DSVideoRenderer* renderer);
|
||||
void (*reset)(struct DSVideoRenderer* renderer);
|
||||
|
@ -96,6 +97,7 @@ struct DSVideoRenderer {
|
|||
uint16_t* vramBBGExtPal[4];
|
||||
uint16_t* vramBOBJExtPal;
|
||||
union DSOAM* oam;
|
||||
struct DSGX* gx;
|
||||
};
|
||||
|
||||
struct DS;
|
||||
|
|
60
src/ds/gx.c
60
src/ds/gx.c
|
@ -13,6 +13,13 @@ mLOG_DEFINE_CATEGORY(DS_GX, "DS GX");
|
|||
#define DS_GX_FIFO_SIZE 256
|
||||
#define DS_GX_PIPE_SIZE 4
|
||||
|
||||
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer);
|
||||
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer);
|
||||
static void DSGXDummyRendererDeinit(struct DSGXRenderer* renderer);
|
||||
static void DSGXDummyRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount);
|
||||
static void DSGXDummyRendererDrawScanline(struct DSGXRenderer* renderer, int y);
|
||||
static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, color_t** output);
|
||||
|
||||
static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = {
|
||||
[DS_GX_CMD_NOP] = 0,
|
||||
[DS_GX_CMD_MTX_MODE] = 2,
|
||||
|
@ -91,6 +98,15 @@ static const int32_t _gxCommandParams[DS_GX_CMD_MAX] = {
|
|||
[DS_GX_CMD_VEC_TEST] = 1,
|
||||
};
|
||||
|
||||
static struct DSGXRenderer dummyRenderer = {
|
||||
.init = DSGXDummyRendererInit,
|
||||
.reset = DSGXDummyRendererReset,
|
||||
.deinit = DSGXDummyRendererDeinit,
|
||||
.setRAM = DSGXDummyRendererSetRAM,
|
||||
.drawScanline = DSGXDummyRendererDrawScanline,
|
||||
.getScanline = DSGXDummyRendererGetScanline,
|
||||
};
|
||||
|
||||
static void _pullPipe(struct DSGX* gx) {
|
||||
if (CircleBufferSize(&gx->fifo) >= sizeof(struct DSGXEntry)) {
|
||||
struct DSGXEntry entry = { 0 };
|
||||
|
@ -171,6 +187,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
|||
}
|
||||
|
||||
void DSGXInit(struct DSGX* gx) {
|
||||
gx->renderer = &dummyRenderer;
|
||||
CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE);
|
||||
CircleBufferInit(&gx->pipe, sizeof(struct DSGXEntry) * DS_GX_PIPE_SIZE);
|
||||
gx->fifoEvent.name = "DS GX FIFO";
|
||||
|
@ -180,6 +197,7 @@ void DSGXInit(struct DSGX* gx) {
|
|||
}
|
||||
|
||||
void DSGXDeinit(struct DSGX* gx) {
|
||||
DSGXAssociateRenderer(gx, &dummyRenderer);
|
||||
CircleBufferDeinit(&gx->fifo);
|
||||
CircleBufferDeinit(&gx->pipe);
|
||||
}
|
||||
|
@ -192,6 +210,12 @@ void DSGXReset(struct DSGX* gx) {
|
|||
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
|
||||
}
|
||||
|
||||
void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {
|
||||
gx->renderer->deinit(gx->renderer);
|
||||
gx->renderer = renderer;
|
||||
gx->renderer->init(gx->renderer);
|
||||
}
|
||||
|
||||
void DSGXUpdateGXSTAT(struct DSGX* gx) {
|
||||
uint32_t value = gx->p->memory.io9[DS9_REG_GXSTAT_HI >> 1] << 16;
|
||||
value = DSRegGXSTATIsDoIRQ(value);
|
||||
|
@ -379,3 +403,39 @@ void DSGXSwapBuffers(struct DSGX* gx) {
|
|||
mTimingSchedule(&gx->p->ds9.timing, &gx->fifoEvent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererDeinit(struct DSGXRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(verts);
|
||||
UNUSED(polys);
|
||||
UNUSED(polyCount);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererDrawScanline(struct DSGXRenderer* renderer, int y) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(y);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, color_t** output) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(y);
|
||||
*output = NULL;
|
||||
// Nothing to do
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "gba/renderers/software-private.h"
|
||||
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/ds/gx.h>
|
||||
#include <mgba/internal/ds/io.h>
|
||||
|
||||
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer);
|
||||
|
@ -354,7 +355,7 @@ static void DSVideoSoftwareRendererInvalidateExtPal(struct DSVideoRenderer* rend
|
|||
_regenerateExtPalette(softwareRenderer, obj, engB, slot);
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, int y) {
|
||||
static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, struct DSGX* gx, int y) {
|
||||
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
|
||||
|
||||
int x;
|
||||
|
@ -381,7 +382,9 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend
|
|||
GBAVideoSoftwareRendererPostprocessSprite(softwareRenderer, priority);
|
||||
}
|
||||
if (TEST_LAYER_ENABLED(0)) {
|
||||
if (DSRegisterDISPCNTIs3D(softwareRenderer->dispcnt)) {
|
||||
if (DSRegisterDISPCNTIs3D(softwareRenderer->dispcnt) && gx) {
|
||||
color_t* scanline;
|
||||
gx->renderer->getScanline(gx->renderer, y, &scanline);
|
||||
// TODO
|
||||
} else {
|
||||
GBAVideoSoftwareRendererDrawBackgroundMode0(softwareRenderer, &softwareRenderer->bg[0], y);
|
||||
|
@ -472,7 +475,7 @@ static void _drawScanlineA(struct DSVideoSoftwareRenderer* softwareRenderer, int
|
|||
}
|
||||
return;
|
||||
case 1:
|
||||
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, y);
|
||||
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, softwareRenderer->d.gx, y);
|
||||
return;
|
||||
case 2: {
|
||||
uint16_t* vram = &softwareRenderer->d.vram[0x10000 * DSRegisterDISPCNTGetVRAMBlock(softwareRenderer->dispcntA)];
|
||||
|
@ -527,7 +530,7 @@ static void _drawScanlineB(struct DSVideoSoftwareRenderer* softwareRenderer, int
|
|||
}
|
||||
return;
|
||||
case 1:
|
||||
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engB.d, y);
|
||||
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engB.d, NULL, y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue