DS Video: Display swapping
Vicki Pfau vi@endrift.com
Wed, 22 Feb 2017 10:57:48 -0800
4 files changed,
22 insertions(+),
5 deletions(-)
M
include/mgba/internal/ds/renderers/software.h
→
include/mgba/internal/ds/renderers/software.h
@@ -21,6 +21,7 @@ struct GBAVideoSoftwareRenderer engB;
DSRegisterDISPCNT dispcntA; DSRegisterDISPCNT dispcntB; + DSRegisterPOWCNT1 powcnt; color_t* outputBuffer; int outputBufferStride;
M
include/mgba/internal/ds/video.h
→
include/mgba/internal/ds/video.h
@@ -58,6 +58,10 @@ DECL_BITS(DSRegisterDISPCNT, CharBase, 24, 3);
DECL_BITS(DSRegisterDISPCNT, ScreenBase, 27, 3); // TODO +DECL_BITFIELD(DSRegisterPOWCNT1, uint16_t); +// TODO +DECL_BIT(DSRegisterPOWCNT1, Swap, 15); + struct DSVideoRenderer { void (*init)(struct DSVideoRenderer* renderer); void (*reset)(struct DSVideoRenderer* renderer);
M
src/ds/io.c
→
src/ds/io.c
@@ -440,6 +440,11 @@ case DS9_REG_SQRT_PARAM_3:
ds->memory.io9[DS9_REG_SQRTCNT >> 1] = _scheduleSqrt(ds, ds->memory.io9[DS9_REG_SQRTCNT >> 1]); break; + // High Video + case DS9_REG_POWCNT1: + value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); + break; + default: { uint32_t v2 = DSIOWrite(&ds->ds9, address, value);
M
src/ds/renderers/software.c
→
src/ds/renderers/software.c
@@ -42,9 +42,11 @@ struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
softwareRenderer->engA.d.palette = &renderer->palette[0]; softwareRenderer->engA.d.oam = &renderer->oam->oam[0]; softwareRenderer->engA.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS; + softwareRenderer->engA.outputBufferStride = softwareRenderer->outputBufferStride; softwareRenderer->engB.d.palette = &renderer->palette[512]; softwareRenderer->engB.d.oam = &renderer->oam->oam[1]; softwareRenderer->engB.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS; + softwareRenderer->engB.outputBufferStride = softwareRenderer->outputBufferStride; DSVideoSoftwareRendererReset(renderer); }@@ -113,6 +115,9 @@ softwareRenderer->dispcntB &= 0x0000FFFF;
softwareRenderer->dispcntB |= value << 16; GBAVideoSoftwareRendererUpdateDISPCNTB(softwareRenderer); break; + case DS9_REG_POWCNT1: + value &= 0x810F; + softwareRenderer->powcnt = value; } return value; }@@ -222,11 +227,13 @@ }
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; - + if (!DSRegisterPOWCNT1IsSwap(softwareRenderer->powcnt)) { + softwareRenderer->engA.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS]; + softwareRenderer->engB.outputBuffer = softwareRenderer->outputBuffer; + } else { + softwareRenderer->engA.outputBuffer = softwareRenderer->outputBuffer; + softwareRenderer->engB.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS]; + } _drawScanlineA(softwareRenderer, y); _drawScanlineB(softwareRenderer, y);