mirror of https://github.com/mgba-emu/mgba.git
DS Video: Start hooking up GBA video
This commit is contained in:
parent
5ad7092567
commit
e0518fdf30
|
@ -19,6 +19,9 @@ struct DSVideoSoftwareRenderer {
|
|||
struct GBAVideoSoftwareRenderer engA;
|
||||
struct GBAVideoSoftwareRenderer engB;
|
||||
|
||||
DSRegisterDISPCNT dispcntA;
|
||||
DSRegisterDISPCNT dispcntB;
|
||||
|
||||
color_t* outputBuffer;
|
||||
int outputBufferStride;
|
||||
|
||||
|
|
|
@ -35,12 +35,32 @@ union DSOAM {
|
|||
uint16_t raw[1024];
|
||||
};
|
||||
|
||||
DECL_BITFIELD(DSRegisterDISPCNT, uint32_t);
|
||||
DECL_BITS(DSRegisterDISPCNT, Mode, 0, 3);
|
||||
DECL_BIT(DSRegisterDISPCNT, 3D, 3);
|
||||
DECL_BIT(DSRegisterDISPCNT, TileObjMapping, 4);
|
||||
DECL_BIT(DSRegisterDISPCNT, BitmapObj2D, 5);
|
||||
DECL_BIT(DSRegisterDISPCNT, BitmapObjMapping, 6);
|
||||
DECL_BIT(DSRegisterDISPCNT, ForcedBlank, 7);
|
||||
DECL_BIT(DSRegisterDISPCNT, Bg0Enable, 8);
|
||||
DECL_BIT(DSRegisterDISPCNT, Bg1Enable, 9);
|
||||
DECL_BIT(DSRegisterDISPCNT, Bg2Enable, 10);
|
||||
DECL_BIT(DSRegisterDISPCNT, Bg3Enable, 11);
|
||||
DECL_BIT(DSRegisterDISPCNT, ObjEnable, 12);
|
||||
DECL_BIT(DSRegisterDISPCNT, Win0Enable, 13);
|
||||
DECL_BIT(DSRegisterDISPCNT, Win1Enable, 14);
|
||||
DECL_BIT(DSRegisterDISPCNT, ObjwinEnable, 15);
|
||||
DECL_BITS(DSRegisterDISPCNT, DispMode, 16, 2);
|
||||
DECL_BITS(DSRegisterDISPCNT, VRAMBlock, 18, 2);
|
||||
// TODO
|
||||
|
||||
struct DSVideoRenderer {
|
||||
void (*init)(struct DSVideoRenderer* renderer);
|
||||
void (*reset)(struct DSVideoRenderer* renderer);
|
||||
void (*deinit)(struct DSVideoRenderer* renderer);
|
||||
|
||||
uint16_t (*writeVideoRegister)(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
void (*writePalette)(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
void (*drawScanline)(struct DSVideoRenderer* renderer, int y);
|
||||
void (*finishFrame)(struct DSVideoRenderer* renderer);
|
||||
|
||||
|
@ -49,6 +69,10 @@ struct DSVideoRenderer {
|
|||
|
||||
uint16_t* palette;
|
||||
uint16_t* vram;
|
||||
uint16_t* vramABG[32];
|
||||
uint16_t* vramAOBJ[32];
|
||||
uint16_t* vramBBG[32];
|
||||
uint16_t* vramBOBJ[32];
|
||||
union DSOAM* oam;
|
||||
};
|
||||
|
||||
|
@ -64,6 +88,10 @@ struct DSVideo {
|
|||
|
||||
uint16_t palette[1024];
|
||||
uint16_t* vram;
|
||||
uint16_t* vramABG[32];
|
||||
uint16_t* vramAOBJ[32];
|
||||
uint16_t* vramBBG[32];
|
||||
uint16_t* vramBOBJ[32];
|
||||
union DSOAM oam;
|
||||
|
||||
int32_t frameCounter;
|
||||
|
@ -80,7 +108,7 @@ struct DSCommon;
|
|||
void DSVideoWriteDISPSTAT(struct DSCommon* dscore, uint16_t value);
|
||||
|
||||
struct DSMemory;
|
||||
void DSVideoConfigureVRAM(struct DSMemory* memory, int index, uint8_t value);
|
||||
void DSVideoConfigureVRAM(struct DS* ds, int index, uint8_t value);
|
||||
|
||||
CXX_GUARD_START
|
||||
|
||||
|
|
14
src/ds/io.c
14
src/ds/io.c
|
@ -386,9 +386,9 @@ void DS9IOInit(struct DS* ds) {
|
|||
}
|
||||
|
||||
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
|
||||
if (address <= DS9_REG_A_BLDY && (address > DS_REG_VCOUNT || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_B_DISPCNT_LO)) {
|
||||
if (address <= DS9_REG_A_BLDY && (address > DS_REG_VCOUNT || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_A_DISPCNT_HI)) {
|
||||
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
|
||||
} else if (address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY && (address == DS9_REG_B_DISPCNT_LO || address == DS9_REG_B_DISPCNT_LO)) {
|
||||
} else if (address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) {
|
||||
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
|
||||
} else {
|
||||
switch (address) {
|
||||
|
@ -397,18 +397,18 @@ void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
|
|||
case DS9_REG_VRAMCNT_C:
|
||||
case DS9_REG_VRAMCNT_E:
|
||||
value &= 0x9F9F;
|
||||
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A, value & 0xFF);
|
||||
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A + 1, value >> 8);
|
||||
DSVideoConfigureVRAM(ds, address - DS9_REG_VRAMCNT_A, value & 0xFF);
|
||||
DSVideoConfigureVRAM(ds, address - DS9_REG_VRAMCNT_A + 1, value >> 8);
|
||||
break;
|
||||
case DS9_REG_VRAMCNT_G:
|
||||
value &= 0x9F03;
|
||||
DSVideoConfigureVRAM(&ds->memory, 6, value & 0xFF);
|
||||
DSVideoConfigureVRAM(ds, 6, value & 0xFF);
|
||||
DSConfigureWRAM(&ds->memory, value >> 8);
|
||||
break;
|
||||
case DS9_REG_VRAMCNT_H:
|
||||
value &= 0x9F9F;
|
||||
DSVideoConfigureVRAM(&ds->memory, 7, value & 0xFF);
|
||||
DSVideoConfigureVRAM(&ds->memory, 8, value >> 8);
|
||||
DSVideoConfigureVRAM(ds, 7, value & 0xFF);
|
||||
DSVideoConfigureVRAM(ds, 8, value >> 8);
|
||||
break;
|
||||
|
||||
case DS9_REG_EXMEMCNT:
|
||||
|
|
|
@ -181,15 +181,15 @@ void DSMemoryReset(struct DS* ds) {
|
|||
ds->ds7.memory.slot1Access = true;
|
||||
ds->ds9.memory.slot1Access = false;
|
||||
|
||||
DSVideoConfigureVRAM(&ds->memory, 0, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 1, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 2, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 3, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 4, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 5, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 6, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 7, 0);
|
||||
DSVideoConfigureVRAM(&ds->memory, 8, 0);
|
||||
DSVideoConfigureVRAM(ds, 0, 0);
|
||||
DSVideoConfigureVRAM(ds, 1, 0);
|
||||
DSVideoConfigureVRAM(ds, 2, 0);
|
||||
DSVideoConfigureVRAM(ds, 3, 0);
|
||||
DSVideoConfigureVRAM(ds, 4, 0);
|
||||
DSVideoConfigureVRAM(ds, 5, 0);
|
||||
DSVideoConfigureVRAM(ds, 6, 0);
|
||||
DSVideoConfigureVRAM(ds, 7, 0);
|
||||
DSVideoConfigureVRAM(ds, 8, 0);
|
||||
DSConfigureWRAM(&ds->memory, 3);
|
||||
|
||||
if (!ds->memory.wram || !ds->memory.wram7 || !ds->memory.ram || !ds->memory.itcm || !ds->memory.dtcm) {
|
||||
|
@ -940,6 +940,8 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
|
|||
break;
|
||||
case DS9_REGION_PALETTE_RAM:
|
||||
STORE_32(value, address & (DS9_SIZE_PALETTE_RAM - 4), ds->video.palette);
|
||||
ds->video.renderer->writePalette(ds->video.renderer, (address & (DS9_SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
|
||||
ds->video.renderer->writePalette(ds->video.renderer, address & (DS9_SIZE_PALETTE_RAM - 4), value);
|
||||
break;
|
||||
case DS_REGION_VRAM: {
|
||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||
|
@ -1006,6 +1008,7 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
|||
break;
|
||||
case DS9_REGION_PALETTE_RAM:
|
||||
STORE_16(value, address & (DS9_SIZE_PALETTE_RAM - 2), ds->video.palette);
|
||||
ds->video.renderer->writePalette(ds->video.renderer, address & (DS9_SIZE_PALETTE_RAM - 2), value);
|
||||
break;
|
||||
case DS_REGION_VRAM: {
|
||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||
|
@ -1228,7 +1231,9 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
|
|||
});
|
||||
break;
|
||||
case DS9_REGION_PALETTE_RAM:
|
||||
STM_LOOP(STORE_32(value, address & (DS9_SIZE_PALETTE_RAM - 1), ds->video.palette));
|
||||
STM_LOOP(STORE_32(value, address & (DS9_SIZE_PALETTE_RAM - 1), ds->video.palette);
|
||||
ds->video.renderer->writePalette(ds->video.renderer, (address & (DS9_SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
|
||||
ds->video.renderer->writePalette(ds->video.renderer, address & (DS9_SIZE_PALETTE_RAM - 4), value));
|
||||
break;
|
||||
case DS_REGION_VRAM:
|
||||
STM_LOOP(unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/internal/ds/renderers/software.h>
|
||||
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/ds/io.h>
|
||||
|
||||
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererReset(struct DSVideoRenderer* renderer);
|
||||
static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoSoftwareRendererWritePalette(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y);
|
||||
static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
|
@ -19,6 +23,7 @@ void DSVideoSoftwareRendererCreate(struct DSVideoSoftwareRenderer* renderer) {
|
|||
renderer->d.reset = DSVideoSoftwareRendererReset;
|
||||
renderer->d.deinit = DSVideoSoftwareRendererDeinit;
|
||||
renderer->d.writeVideoRegister = DSVideoSoftwareRendererWriteVideoRegister;
|
||||
renderer->d.writePalette = DSVideoSoftwareRendererWritePalette;
|
||||
renderer->d.drawScanline = DSVideoSoftwareRendererDrawScanline;
|
||||
renderer->d.finishFrame = DSVideoSoftwareRendererFinishFrame;
|
||||
renderer->d.getPixels = DSVideoSoftwareRendererGetPixels;
|
||||
|
@ -55,17 +60,155 @@ static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer) {
|
|||
}
|
||||
|
||||
static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
mLOG(DS_VIDEO, STUB, "Stub video register write: %04X:%04X", address, value);
|
||||
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||
if (address <= DS9_REG_A_BLDY) {
|
||||
value = softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, address, value);
|
||||
} else if (address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) {
|
||||
value = softwareRenderer->engB.d.writeVideoRegister(&softwareRenderer->engB.d, address & 0xFF, value);
|
||||
} else {
|
||||
mLOG(DS_VIDEO, STUB, "Stub video register write: %04X:%04X", address, value);
|
||||
}
|
||||
switch (address) {
|
||||
case DS9_REG_A_DISPCNT_LO:
|
||||
softwareRenderer->dispcntA &= 0xFFFF0000;
|
||||
softwareRenderer->dispcntA |= value;
|
||||
break;
|
||||
case DS9_REG_A_DISPCNT_HI:
|
||||
softwareRenderer->dispcntA &= 0x0000FFFF;
|
||||
softwareRenderer->dispcntA |= value << 16;
|
||||
break;
|
||||
case DS9_REG_B_DISPCNT_LO:
|
||||
softwareRenderer->dispcntB &= 0xFFFF0000;
|
||||
softwareRenderer->dispcntB |= value;
|
||||
break;
|
||||
case DS9_REG_B_DISPCNT_HI:
|
||||
softwareRenderer->dispcntB &= 0x0000FFFF;
|
||||
softwareRenderer->dispcntB |= value << 16;
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererWritePalette(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||
if (address < 0x200) {
|
||||
softwareRenderer->engA.d.writePalette(&softwareRenderer->engA.d, address & 0x1FF, value);
|
||||
} else {
|
||||
softwareRenderer->engB.d.writePalette(&softwareRenderer->engB.d, address & 0x1FF, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void _drawScanlineA(struct DSVideoSoftwareRenderer* softwareRenderer, int y) {
|
||||
memcpy(softwareRenderer->engA.d.vramBG, softwareRenderer->d.vramABG, sizeof(softwareRenderer->engA.d.vramBG));
|
||||
memcpy(softwareRenderer->engA.d.vramOBJ, softwareRenderer->d.vramAOBJ, sizeof(softwareRenderer->engA.d.vramOBJ));
|
||||
color_t* row = &softwareRenderer->engA.outputBuffer[softwareRenderer->outputBufferStride * y];
|
||||
|
||||
int x;
|
||||
switch (DSRegisterDISPCNTGetDispMode(softwareRenderer->dispcntA)) {
|
||||
case 0:
|
||||
for (x = 0; x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
row[x] = GBA_COLOR_WHITE;
|
||||
}
|
||||
return;
|
||||
case 1:
|
||||
softwareRenderer->engA.d.drawScanline(&softwareRenderer->engA.d, y);
|
||||
return;
|
||||
case 2: {
|
||||
uint16_t* vram = &softwareRenderer->d.vram[0x10000 * DSRegisterDISPCNTGetVRAMBlock(softwareRenderer->dispcntA)];
|
||||
for (x = 0; x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
color_t color;
|
||||
LOAD_16(color, (x + y * DS_VIDEO_HORIZONTAL_PIXELS) * 2, vram);
|
||||
#ifndef COLOR_16_BIT
|
||||
unsigned color32 = 0;
|
||||
color32 |= (color << 9) & 0xF80000;
|
||||
color32 |= (color << 3) & 0xF8;
|
||||
color32 |= (color << 6) & 0xF800;
|
||||
color32 |= (color32 >> 5) & 0x070707;
|
||||
color = color32;
|
||||
#elif COLOR_5_6_5
|
||||
uint16_t color16 = 0;
|
||||
color16 |= (color & 0x001F) << 11;
|
||||
color16 |= (color & 0x03E0) << 1;
|
||||
color16 |= (color & 0x7C00) >> 10;
|
||||
color = color16;
|
||||
#endif
|
||||
softwareRenderer->row[x] = color;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COLOR_16_BIT
|
||||
#if defined(__ARM_NEON) && !defined(__APPLE__)
|
||||
_to16Bit(row, softwareRenderer->row, DS_VIDEO_HORIZONTAL_PIXELS);
|
||||
#else
|
||||
for (x = 0; x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
row[x] = softwareRenderer->row[x];
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
memcpy(row, softwareRenderer->row, DS_VIDEO_HORIZONTAL_PIXELS * sizeof(*row));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _drawScanlineB(struct DSVideoSoftwareRenderer* softwareRenderer, int y) {
|
||||
memcpy(softwareRenderer->engB.d.vramBG, softwareRenderer->d.vramBBG, sizeof(softwareRenderer->engB.d.vramBG));
|
||||
memcpy(softwareRenderer->engB.d.vramOBJ, softwareRenderer->d.vramBOBJ, sizeof(softwareRenderer->engB.d.vramOBJ));
|
||||
color_t* row = &softwareRenderer->engB.outputBuffer[softwareRenderer->outputBufferStride * y];
|
||||
|
||||
int x;
|
||||
switch (DSRegisterDISPCNTGetDispMode(softwareRenderer->dispcntB)) {
|
||||
case 0:
|
||||
for (x = 0; x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
row[x] = GBA_COLOR_WHITE;
|
||||
}
|
||||
return;
|
||||
case 1:
|
||||
softwareRenderer->engB.d.drawScanline(&softwareRenderer->engB.d, y);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef COLOR_16_BIT
|
||||
#if defined(__ARM_NEON) && !defined(__APPLE__)
|
||||
_to16Bit(row, softwareRenderer->row, DS_VIDEO_HORIZONTAL_PIXELS);
|
||||
#else
|
||||
for (x = 0; x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {
|
||||
row[x] = softwareRenderer->row[x];
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
memcpy(row, softwareRenderer->row, DS_VIDEO_HORIZONTAL_PIXELS * sizeof(*row));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y) {
|
||||
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||
softwareRenderer->engA.outputBuffer = softwareRenderer->outputBuffer;
|
||||
softwareRenderer->engB.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS];
|
||||
softwareRenderer->engA.outputBufferStride = softwareRenderer->outputBufferStride;
|
||||
softwareRenderer->engB.outputBufferStride = softwareRenderer->outputBufferStride;
|
||||
|
||||
|
||||
_drawScanlineA(softwareRenderer, y);
|
||||
_drawScanlineB(softwareRenderer, y);
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer) {
|
||||
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||
softwareRenderer->engA.d.finishFrame(&softwareRenderer->engA.d);
|
||||
softwareRenderer->engB.d.finishFrame(&softwareRenderer->engB.d);
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels) {
|
||||
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||
#ifdef COLOR_16_BIT
|
||||
#error Not yet supported
|
||||
#else
|
||||
*stride = softwareRenderer->outputBufferStride;
|
||||
*pixels = softwareRenderer->outputBuffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels) {
|
||||
|
|
|
@ -18,6 +18,7 @@ static void DSVideoDummyRendererInit(struct DSVideoRenderer* renderer);
|
|||
static void DSVideoDummyRendererReset(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoDummyRendererDeinit(struct DSVideoRenderer* renderer);
|
||||
static uint16_t DSVideoDummyRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoDummyRendererWritePalette(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, int y);
|
||||
static void DSVideoDummyRendererFinishFrame(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoDummyRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
|
@ -102,6 +103,7 @@ static struct DSVideoRenderer dummyRenderer = {
|
|||
.reset = DSVideoDummyRendererReset,
|
||||
.deinit = DSVideoDummyRendererDeinit,
|
||||
.writeVideoRegister = DSVideoDummyRendererWriteVideoRegister,
|
||||
.writePalette = DSVideoDummyRendererWritePalette,
|
||||
.drawScanline = DSVideoDummyRendererDrawScanline,
|
||||
.finishFrame = DSVideoDummyRendererFinishFrame,
|
||||
.getPixels = DSVideoDummyRendererGetPixels,
|
||||
|
@ -160,6 +162,10 @@ void DSVideoAssociateRenderer(struct DSVideo* video, struct DSVideoRenderer* ren
|
|||
video->renderer = renderer;
|
||||
renderer->palette = video->palette;
|
||||
renderer->vram = video->vram;
|
||||
memcpy(renderer->vramABG, video->vramABG, sizeof(renderer->vramABG));
|
||||
memcpy(renderer->vramAOBJ, video->vramAOBJ, sizeof(renderer->vramAOBJ));
|
||||
memcpy(renderer->vramBBG, video->vramBBG, sizeof(renderer->vramBBG));
|
||||
memcpy(renderer->vramBOBJ, video->vramBOBJ, sizeof(renderer->vramBOBJ));
|
||||
renderer->oam = &video->oam;
|
||||
video->renderer->init(video->renderer);
|
||||
}
|
||||
|
@ -292,7 +298,8 @@ void DSVideoWriteDISPSTAT(struct DSCommon* dscore, uint16_t value) {
|
|||
// TODO: Does a VCounter IRQ trigger on write?
|
||||
}
|
||||
|
||||
void DSVideoConfigureVRAM(struct DSMemory* memory, int index, uint8_t value) {
|
||||
void DSVideoConfigureVRAM(struct DS* ds, int index, uint8_t value) {
|
||||
struct DSMemory* memory = &ds->memory;
|
||||
struct DSVRAMBankInfo info = _vramInfo[index][value & 0x7];
|
||||
memset(&memory->vramMirror[index], 0, sizeof(memory->vramMirror[index]));
|
||||
memset(&memory->vramMode[index], 0, sizeof(memory->vramMode[index]));
|
||||
|
@ -308,6 +315,32 @@ void DSVideoConfigureVRAM(struct DSMemory* memory, int index, uint8_t value) {
|
|||
memory->vramMirror[index][i + j] = 1 << index;
|
||||
}
|
||||
}
|
||||
switch (info.mode) {
|
||||
case 0:
|
||||
for (i = 0; i < size; ++i) {
|
||||
ds->video.vramABG[offset + i] = &memory->vramBank[index][i << (DS_VRAM_OFFSET - 1)];
|
||||
ds->video.renderer->vramABG[offset + i] = ds->video.vramABG[offset + i];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (i = 0; i < size; ++i) {
|
||||
ds->video.vramBBG[offset + i] = &memory->vramBank[index][i << (DS_VRAM_OFFSET - 1)];
|
||||
ds->video.renderer->vramBBG[offset + i] = ds->video.vramBBG[offset + i];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < size; ++i) {
|
||||
ds->video.vramAOBJ[offset + i] = &memory->vramBank[index][i << (DS_VRAM_OFFSET - 1)];
|
||||
ds->video.renderer->vramAOBJ[offset + i] = ds->video.vramAOBJ[offset + i];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (i = 0; i < size; ++i) {
|
||||
ds->video.vramBOBJ[offset + i] = &memory->vramBank[index][i << (DS_VRAM_OFFSET - 1)];
|
||||
ds->video.renderer->vramBOBJ[offset + i] = ds->video.vramBOBJ[offset + i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererInit(struct DSVideoRenderer* renderer) {
|
||||
|
@ -330,6 +363,12 @@ static uint16_t DSVideoDummyRendererWriteVideoRegister(struct DSVideoRenderer* r
|
|||
return value;
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererWritePalette(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
UNUSED(value);
|
||||
UNUSED(address);
|
||||
UNUSED(value);
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, int y) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(y);
|
||||
|
|
|
@ -108,7 +108,7 @@ int main(int argc, char** argv) {
|
|||
free(perfOpts.savestate);
|
||||
}
|
||||
|
||||
_outputBuffer = malloc(256 * 256 * 4);
|
||||
_outputBuffer = malloc(256 * 384 * 4);
|
||||
if (perfOpts.csv) {
|
||||
puts("game_code,frames,duration,renderer");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue