DS Video: Display swapping

This commit is contained in:
Vicki Pfau 2017-02-22 10:57:48 -08:00
parent 9ecaaa5d4a
commit 2636d3a767
4 changed files with 22 additions and 5 deletions

View File

@ -21,6 +21,7 @@ struct DSVideoSoftwareRenderer {
DSRegisterDISPCNT dispcntA; DSRegisterDISPCNT dispcntA;
DSRegisterDISPCNT dispcntB; DSRegisterDISPCNT dispcntB;
DSRegisterPOWCNT1 powcnt;
color_t* outputBuffer; color_t* outputBuffer;
int outputBufferStride; int outputBufferStride;

View File

@ -58,6 +58,10 @@ DECL_BITS(DSRegisterDISPCNT, CharBase, 24, 3);
DECL_BITS(DSRegisterDISPCNT, ScreenBase, 27, 3); DECL_BITS(DSRegisterDISPCNT, ScreenBase, 27, 3);
// TODO // TODO
DECL_BITFIELD(DSRegisterPOWCNT1, uint16_t);
// TODO
DECL_BIT(DSRegisterPOWCNT1, Swap, 15);
struct DSVideoRenderer { struct DSVideoRenderer {
void (*init)(struct DSVideoRenderer* renderer); void (*init)(struct DSVideoRenderer* renderer);
void (*reset)(struct DSVideoRenderer* renderer); void (*reset)(struct DSVideoRenderer* renderer);

View File

@ -440,6 +440,11 @@ void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
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;
// High Video
case DS9_REG_POWCNT1:
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
break;
default: default:
{ {
uint32_t v2 = DSIOWrite(&ds->ds9, address, value); uint32_t v2 = DSIOWrite(&ds->ds9, address, value);

View File

@ -42,9 +42,11 @@ static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
softwareRenderer->engA.d.palette = &renderer->palette[0]; softwareRenderer->engA.d.palette = &renderer->palette[0];
softwareRenderer->engA.d.oam = &renderer->oam->oam[0]; softwareRenderer->engA.d.oam = &renderer->oam->oam[0];
softwareRenderer->engA.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS; softwareRenderer->engA.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS;
softwareRenderer->engA.outputBufferStride = softwareRenderer->outputBufferStride;
softwareRenderer->engB.d.palette = &renderer->palette[512]; softwareRenderer->engB.d.palette = &renderer->palette[512];
softwareRenderer->engB.d.oam = &renderer->oam->oam[1]; softwareRenderer->engB.d.oam = &renderer->oam->oam[1];
softwareRenderer->engB.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS; softwareRenderer->engB.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS;
softwareRenderer->engB.outputBufferStride = softwareRenderer->outputBufferStride;
DSVideoSoftwareRendererReset(renderer); DSVideoSoftwareRendererReset(renderer);
} }
@ -113,6 +115,9 @@ static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer
softwareRenderer->dispcntB |= value << 16; softwareRenderer->dispcntB |= value << 16;
GBAVideoSoftwareRendererUpdateDISPCNTB(softwareRenderer); GBAVideoSoftwareRendererUpdateDISPCNTB(softwareRenderer);
break; break;
case DS9_REG_POWCNT1:
value &= 0x810F;
softwareRenderer->powcnt = value;
} }
return value; return value;
} }
@ -222,11 +227,13 @@ static void _drawScanlineB(struct DSVideoSoftwareRenderer* softwareRenderer, int
static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y) { static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y) {
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer; struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
softwareRenderer->engA.outputBuffer = softwareRenderer->outputBuffer; if (!DSRegisterPOWCNT1IsSwap(softwareRenderer->powcnt)) {
softwareRenderer->engB.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS]; softwareRenderer->engA.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS];
softwareRenderer->engA.outputBufferStride = softwareRenderer->outputBufferStride; softwareRenderer->engB.outputBuffer = softwareRenderer->outputBuffer;
softwareRenderer->engB.outputBufferStride = softwareRenderer->outputBufferStride; } else {
softwareRenderer->engA.outputBuffer = softwareRenderer->outputBuffer;
softwareRenderer->engB.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS];
}
_drawScanlineA(softwareRenderer, y); _drawScanlineA(softwareRenderer, y);
_drawScanlineB(softwareRenderer, y); _drawScanlineB(softwareRenderer, y);