mirror of https://github.com/mgba-emu/mgba.git
DS Video: Start hooking up software renderer
This commit is contained in:
parent
9f31a1cc2c
commit
5ad7092567
|
@ -12,6 +12,7 @@ CXX_GUARD_START
|
||||||
|
|
||||||
#include <mgba/core/log.h>
|
#include <mgba/core/log.h>
|
||||||
#include <mgba/core/timing.h>
|
#include <mgba/core/timing.h>
|
||||||
|
#include <mgba/internal/gba/video.h>
|
||||||
|
|
||||||
mLOG_DECLARE_CATEGORY(DS_VIDEO);
|
mLOG_DECLARE_CATEGORY(DS_VIDEO);
|
||||||
|
|
||||||
|
@ -29,6 +30,11 @@ enum {
|
||||||
DS_VIDEO_TOTAL_LENGTH = DS_VIDEO_HORIZONTAL_LENGTH * DS_VIDEO_VERTICAL_TOTAL_PIXELS,
|
DS_VIDEO_TOTAL_LENGTH = DS_VIDEO_HORIZONTAL_LENGTH * DS_VIDEO_VERTICAL_TOTAL_PIXELS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union DSOAM {
|
||||||
|
union GBAOAM oam[2];
|
||||||
|
uint16_t raw[1024];
|
||||||
|
};
|
||||||
|
|
||||||
struct DSVideoRenderer {
|
struct DSVideoRenderer {
|
||||||
void (*init)(struct DSVideoRenderer* renderer);
|
void (*init)(struct DSVideoRenderer* renderer);
|
||||||
void (*reset)(struct DSVideoRenderer* renderer);
|
void (*reset)(struct DSVideoRenderer* renderer);
|
||||||
|
@ -41,7 +47,9 @@ struct DSVideoRenderer {
|
||||||
void (*getPixels)(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
void (*getPixels)(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||||
void (*putPixels)(struct DSVideoRenderer* renderer, size_t stride, const void* pixels);
|
void (*putPixels)(struct DSVideoRenderer* renderer, size_t stride, const void* pixels);
|
||||||
|
|
||||||
|
uint16_t* palette;
|
||||||
uint16_t* vram;
|
uint16_t* vram;
|
||||||
|
union DSOAM* oam;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DS;
|
struct DS;
|
||||||
|
@ -54,7 +62,9 @@ struct DSVideo {
|
||||||
// VCOUNT
|
// VCOUNT
|
||||||
int vcount;
|
int vcount;
|
||||||
|
|
||||||
|
uint16_t palette[1024];
|
||||||
uint16_t* vram;
|
uint16_t* vram;
|
||||||
|
union DSOAM oam;
|
||||||
|
|
||||||
int32_t frameCounter;
|
int32_t frameCounter;
|
||||||
int frameskip;
|
int frameskip;
|
||||||
|
|
124
src/ds/io.c
124
src/ds/io.c
|
@ -386,71 +386,77 @@ void DS9IOInit(struct DS* ds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
|
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
|
||||||
switch (address) {
|
if (address <= DS9_REG_A_BLDY && (address > DS_REG_VCOUNT || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_B_DISPCNT_LO)) {
|
||||||
// VRAM control
|
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
|
||||||
case DS9_REG_VRAMCNT_A:
|
} 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)) {
|
||||||
case DS9_REG_VRAMCNT_C:
|
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
|
||||||
case DS9_REG_VRAMCNT_E:
|
} else {
|
||||||
value &= 0x9F9F;
|
switch (address) {
|
||||||
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A, value & 0xFF);
|
// VRAM control
|
||||||
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A + 1, value >> 8);
|
case DS9_REG_VRAMCNT_A:
|
||||||
break;
|
case DS9_REG_VRAMCNT_C:
|
||||||
case DS9_REG_VRAMCNT_G:
|
case DS9_REG_VRAMCNT_E:
|
||||||
value &= 0x9F03;
|
value &= 0x9F9F;
|
||||||
DSVideoConfigureVRAM(&ds->memory, 6, value & 0xFF);
|
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A, value & 0xFF);
|
||||||
DSConfigureWRAM(&ds->memory, value >> 8);
|
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A + 1, value >> 8);
|
||||||
break;
|
break;
|
||||||
case DS9_REG_VRAMCNT_H:
|
case DS9_REG_VRAMCNT_G:
|
||||||
value &= 0x9F9F;
|
value &= 0x9F03;
|
||||||
DSVideoConfigureVRAM(&ds->memory, 7, value & 0xFF);
|
DSVideoConfigureVRAM(&ds->memory, 6, value & 0xFF);
|
||||||
DSVideoConfigureVRAM(&ds->memory, 8, value >> 8);
|
DSConfigureWRAM(&ds->memory, value >> 8);
|
||||||
break;
|
break;
|
||||||
|
case DS9_REG_VRAMCNT_H:
|
||||||
|
value &= 0x9F9F;
|
||||||
|
DSVideoConfigureVRAM(&ds->memory, 7, value & 0xFF);
|
||||||
|
DSVideoConfigureVRAM(&ds->memory, 8, value >> 8);
|
||||||
|
break;
|
||||||
|
|
||||||
case DS9_REG_EXMEMCNT:
|
case DS9_REG_EXMEMCNT:
|
||||||
value &= 0xE8FF;
|
value &= 0xE8FF;
|
||||||
DSConfigureExternalMemory(ds, value);
|
DSConfigureExternalMemory(ds, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Math
|
// Math
|
||||||
case DS9_REG_DIVCNT:
|
case DS9_REG_DIVCNT:
|
||||||
value = _scheduleDiv(ds, value);
|
value = _scheduleDiv(ds, value);
|
||||||
break;
|
break;
|
||||||
case DS9_REG_DIV_NUMER_0:
|
case DS9_REG_DIV_NUMER_0:
|
||||||
case DS9_REG_DIV_NUMER_1:
|
case DS9_REG_DIV_NUMER_1:
|
||||||
case DS9_REG_DIV_NUMER_2:
|
case DS9_REG_DIV_NUMER_2:
|
||||||
case DS9_REG_DIV_NUMER_3:
|
case DS9_REG_DIV_NUMER_3:
|
||||||
case DS9_REG_DIV_DENOM_0:
|
case DS9_REG_DIV_DENOM_0:
|
||||||
case DS9_REG_DIV_DENOM_1:
|
case DS9_REG_DIV_DENOM_1:
|
||||||
case DS9_REG_DIV_DENOM_2:
|
case DS9_REG_DIV_DENOM_2:
|
||||||
case DS9_REG_DIV_DENOM_3:
|
case DS9_REG_DIV_DENOM_3:
|
||||||
ds->memory.io9[DS9_REG_DIVCNT >> 1] = _scheduleDiv(ds, ds->memory.io9[DS9_REG_DIVCNT >> 1]);
|
ds->memory.io9[DS9_REG_DIVCNT >> 1] = _scheduleDiv(ds, ds->memory.io9[DS9_REG_DIVCNT >> 1]);
|
||||||
break;
|
break;
|
||||||
case DS9_REG_SQRTCNT:
|
case DS9_REG_SQRTCNT:
|
||||||
value = _scheduleSqrt(ds, value);
|
value = _scheduleSqrt(ds, value);
|
||||||
break;
|
break;
|
||||||
case DS9_REG_SQRT_PARAM_0:
|
case DS9_REG_SQRT_PARAM_0:
|
||||||
case DS9_REG_SQRT_PARAM_1:
|
case DS9_REG_SQRT_PARAM_1:
|
||||||
case DS9_REG_SQRT_PARAM_2:
|
case DS9_REG_SQRT_PARAM_2:
|
||||||
case DS9_REG_SQRT_PARAM_3:
|
case DS9_REG_SQRT_PARAM_3:
|
||||||
ds->memory.io9[DS9_REG_SQRTCNT >> 1] = _scheduleSqrt(ds, ds->memory.io9[DS9_REG_SQRTCNT >> 1]);
|
ds->memory.io9[DS9_REG_SQRTCNT >> 1] = _scheduleSqrt(ds, ds->memory.io9[DS9_REG_SQRTCNT >> 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
uint32_t v2 = DSIOWrite(&ds->ds9, address, value);
|
uint32_t v2 = DSIOWrite(&ds->ds9, address, value);
|
||||||
if (v2 & 0x10000) {
|
if (v2 & 0x10000) {
|
||||||
value = v2;
|
value = v2;
|
||||||
break;
|
break;
|
||||||
} else if (v2 & 0x20000) {
|
} else if (v2 & 0x20000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mLOG(DS_IO, STUB, "Stub DS9 I/O register write: %06X:%04X", address, value);
|
||||||
|
if (address >= DS7_REG_MAX) {
|
||||||
|
mLOG(DS_IO, GAME_ERROR, "Write to unused DS9 I/O register: %06X:%04X", address, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mLOG(DS_IO, STUB, "Stub DS9 I/O register write: %06X:%04X", address, value);
|
|
||||||
if (address >= DS7_REG_MAX) {
|
|
||||||
mLOG(DS_IO, GAME_ERROR, "Write to unused DS9 I/O register: %06X:%04X", address, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
ds->memory.io9[address >> 1] = value;
|
ds->memory.io9[address >> 1] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -526,8 +526,6 @@ void DS7Store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t DS7LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
|
uint32_t DS7LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
|
||||||
struct DS* ds = (struct DS*) cpu->master;
|
struct DS* ds = (struct DS*) cpu->master;
|
||||||
struct DSMemory* memory = &ds->memory;
|
struct DSMemory* memory = &ds->memory;
|
||||||
|
@ -590,7 +588,6 @@ uint32_t DS7LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
|
||||||
return address | addressMisalign;
|
return address | addressMisalign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t DS7StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
|
uint32_t DS7StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
|
||||||
struct DS* ds = (struct DS*) cpu->master;
|
struct DS* ds = (struct DS*) cpu->master;
|
||||||
struct DSMemory* memory = &ds->memory;
|
struct DSMemory* memory = &ds->memory;
|
||||||
|
@ -733,6 +730,9 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
value = DS9IORead32(ds, address & 0x00FFFFFC);
|
value = DS9IORead32(ds, address & 0x00FFFFFC);
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
LOAD_32(value, address & (DS9_SIZE_PALETTE_RAM - 4), ds->video.palette);
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM: {
|
case DS_REGION_VRAM: {
|
||||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -745,6 +745,9 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
LOAD_32(value, address & (DS9_SIZE_OAM - 4), ds->video.oam.raw);
|
||||||
|
break;
|
||||||
case DS9_REGION_BIOS:
|
case DS9_REGION_BIOS:
|
||||||
// TODO: Fix undersized BIOS
|
// TODO: Fix undersized BIOS
|
||||||
// TODO: Fix masking
|
// TODO: Fix masking
|
||||||
|
@ -803,6 +806,9 @@ uint32_t DS9Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
value = DS9IORead(ds, address & DS_OFFSET_MASK);
|
value = DS9IORead(ds, address & DS_OFFSET_MASK);
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
LOAD_16(value, address & (DS9_SIZE_PALETTE_RAM - 2), ds->video.palette);
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM: {
|
case DS_REGION_VRAM: {
|
||||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -815,6 +821,9 @@ uint32_t DS9Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
LOAD_16(value, address & (DS9_SIZE_OAM - 2), ds->video.oam.raw);
|
||||||
|
break;
|
||||||
case DS9_REGION_BIOS:
|
case DS9_REGION_BIOS:
|
||||||
// TODO: Fix undersized BIOS
|
// TODO: Fix undersized BIOS
|
||||||
// TODO: Fix masking
|
// TODO: Fix masking
|
||||||
|
@ -929,6 +938,9 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
DS9IOWrite32(ds, address & DS_OFFSET_MASK, value);
|
DS9IOWrite32(ds, address & DS_OFFSET_MASK, value);
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
STORE_32(value, address & (DS9_SIZE_PALETTE_RAM - 4), ds->video.palette);
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM: {
|
case DS_REGION_VRAM: {
|
||||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -939,6 +951,9 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
STORE_32(value, address & (DS9_SIZE_OAM - 4), ds->video.oam.raw);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
||||||
STORE_32(value, address & (DS9_SIZE_DTCM - 4), memory->dtcm);
|
STORE_32(value, address & (DS9_SIZE_DTCM - 4), memory->dtcm);
|
||||||
|
@ -989,6 +1004,9 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
DS9IOWrite(ds, address & DS_OFFSET_MASK, value);
|
DS9IOWrite(ds, address & DS_OFFSET_MASK, value);
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
STORE_16(value, address & (DS9_SIZE_PALETTE_RAM - 2), ds->video.palette);
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM: {
|
case DS_REGION_VRAM: {
|
||||||
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -999,6 +1017,9 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
STORE_16(value, address & (DS9_SIZE_OAM - 2), ds->video.oam.raw);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
||||||
STORE_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
STORE_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
||||||
|
@ -1114,6 +1135,9 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
LDM_LOOP(value = DS9IORead32(ds, address));
|
LDM_LOOP(value = DS9IORead32(ds, address));
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
LDM_LOOP(LOAD_32(value, address & (DS9_SIZE_PALETTE_RAM - 1), ds->video.palette));
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM:
|
case DS_REGION_VRAM:
|
||||||
LDM_LOOP(unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
LDM_LOOP(unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
value = 0;
|
value = 0;
|
||||||
|
@ -1126,6 +1150,9 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
LDM_LOOP(LOAD_32(value, address & (DS9_SIZE_OAM - 1), ds->video.oam.raw));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
||||||
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
||||||
|
@ -1200,6 +1227,9 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
|
||||||
mLOG(DS_MEM, STUB, "Unimplemented DS9 STM: %08X", address);
|
mLOG(DS_MEM, STUB, "Unimplemented DS9 STM: %08X", address);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_PALETTE_RAM:
|
||||||
|
STM_LOOP(STORE_32(value, address & (DS9_SIZE_PALETTE_RAM - 1), ds->video.palette));
|
||||||
|
break;
|
||||||
case DS_REGION_VRAM:
|
case DS_REGION_VRAM:
|
||||||
STM_LOOP(unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
STM_LOOP(unsigned mask = _selectVRAM(memory, address >> DS_VRAM_OFFSET);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -1209,6 +1239,9 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case DS9_REGION_OAM:
|
||||||
|
STM_LOOP(STORE_32(value, address & (DS9_SIZE_OAM - 1), ds->video.oam.raw));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
STM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
STM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
|
||||||
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
|
||||||
|
|
|
@ -18,22 +18,44 @@ void DSVideoSoftwareRendererCreate(struct DSVideoSoftwareRenderer* renderer) {
|
||||||
renderer->d.init = DSVideoSoftwareRendererInit;
|
renderer->d.init = DSVideoSoftwareRendererInit;
|
||||||
renderer->d.reset = DSVideoSoftwareRendererReset;
|
renderer->d.reset = DSVideoSoftwareRendererReset;
|
||||||
renderer->d.deinit = DSVideoSoftwareRendererDeinit;
|
renderer->d.deinit = DSVideoSoftwareRendererDeinit;
|
||||||
|
renderer->d.writeVideoRegister = DSVideoSoftwareRendererWriteVideoRegister;
|
||||||
renderer->d.drawScanline = DSVideoSoftwareRendererDrawScanline;
|
renderer->d.drawScanline = DSVideoSoftwareRendererDrawScanline;
|
||||||
renderer->d.finishFrame = DSVideoSoftwareRendererFinishFrame;
|
renderer->d.finishFrame = DSVideoSoftwareRendererFinishFrame;
|
||||||
renderer->d.getPixels = DSVideoSoftwareRendererGetPixels;
|
renderer->d.getPixels = DSVideoSoftwareRendererGetPixels;
|
||||||
renderer->d.putPixels = DSVideoSoftwareRendererPutPixels;
|
renderer->d.putPixels = DSVideoSoftwareRendererPutPixels;
|
||||||
|
|
||||||
|
renderer->engA.d.cache = NULL;
|
||||||
|
GBAVideoSoftwareRendererCreate(&renderer->engA);
|
||||||
|
renderer->engB.d.cache = NULL;
|
||||||
|
GBAVideoSoftwareRendererCreate(&renderer->engB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
|
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
|
||||||
|
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||||
|
softwareRenderer->engA.d.palette = &renderer->palette[0];
|
||||||
|
softwareRenderer->engA.d.oam = &renderer->oam->oam[0];
|
||||||
|
// TODO: VRAM
|
||||||
|
softwareRenderer->engB.d.palette = &renderer->palette[512];
|
||||||
|
softwareRenderer->engB.d.oam = &renderer->oam->oam[1];
|
||||||
|
// TODO: VRAM
|
||||||
|
|
||||||
|
DSVideoSoftwareRendererReset(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSVideoSoftwareRendererReset(struct DSVideoRenderer* renderer) {
|
static void DSVideoSoftwareRendererReset(struct DSVideoRenderer* renderer) {
|
||||||
|
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||||
|
softwareRenderer->engA.d.reset(&softwareRenderer->engA.d);
|
||||||
|
softwareRenderer->engB.d.reset(&softwareRenderer->engB.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer) {
|
static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer) {
|
||||||
|
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
|
||||||
|
softwareRenderer->engA.d.deinit(&softwareRenderer->engA.d);
|
||||||
|
softwareRenderer->engB.d.deinit(&softwareRenderer->engB.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
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);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,9 @@ void DSVideoReset(struct DSVideo* video) {
|
||||||
void DSVideoAssociateRenderer(struct DSVideo* video, struct DSVideoRenderer* renderer) {
|
void DSVideoAssociateRenderer(struct DSVideo* video, struct DSVideoRenderer* renderer) {
|
||||||
video->renderer->deinit(video->renderer);
|
video->renderer->deinit(video->renderer);
|
||||||
video->renderer = renderer;
|
video->renderer = renderer;
|
||||||
|
renderer->palette = video->palette;
|
||||||
renderer->vram = video->vram;
|
renderer->vram = video->vram;
|
||||||
|
renderer->oam = &video->oam;
|
||||||
video->renderer->init(video->renderer);
|
video->renderer->init(video->renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue