From faf99ac304cdf16e09e0d85536866f7f84819ab6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 Mar 2017 21:52:25 -0800 Subject: [PATCH] DS Video: Allow capture of 2D engine --- include/mgba/internal/ds/video.h | 2 ++ src/ds/renderers/software.c | 13 +++++++++++++ src/ds/video.c | 20 ++++++++++++++------ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/mgba/internal/ds/video.h b/include/mgba/internal/ds/video.h index e0cff70ed..521de023b 100644 --- a/include/mgba/internal/ds/video.h +++ b/include/mgba/internal/ds/video.h @@ -10,6 +10,7 @@ CXX_GUARD_START +#include #include #include #include @@ -95,6 +96,7 @@ struct DSVideoRenderer { void (*writeOAM)(struct DSVideoRenderer* renderer, uint32_t oam); void (*invalidateExtPal)(struct DSVideoRenderer* renderer, bool obj, bool engB, int slot); void (*drawScanline)(struct DSVideoRenderer* renderer, int y); + void (*drawScanlineDirectly)(struct DSVideoRenderer* renderer, int y, color_t* scanline); void (*finishFrame)(struct DSVideoRenderer* renderer); void (*getPixels)(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels); diff --git a/src/ds/renderers/software.c b/src/ds/renderers/software.c index 4bfa0c1e9..bcadfe642 100644 --- a/src/ds/renderers/software.c +++ b/src/ds/renderers/software.c @@ -18,6 +18,7 @@ static void DSVideoSoftwareRendererWritePalette(struct DSVideoRenderer* renderer static void DSVideoSoftwareRendererWriteOAM(struct DSVideoRenderer* renderer, uint32_t oam); static void DSVideoSoftwareRendererInvalidateExtPal(struct DSVideoRenderer* renderer, bool obj, bool engB, int slot); static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y); +static void DSVideoSoftwareRendererDrawScanlineDirectly(struct DSVideoRenderer* renderer, int y, color_t* scanline); static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer); static void DSVideoSoftwareRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels); static void DSVideoSoftwareRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels); @@ -139,6 +140,7 @@ void DSVideoSoftwareRendererCreate(struct DSVideoSoftwareRenderer* renderer) { renderer->d.writeOAM = DSVideoSoftwareRendererWriteOAM; renderer->d.invalidateExtPal = DSVideoSoftwareRendererInvalidateExtPal; renderer->d.drawScanline = DSVideoSoftwareRendererDrawScanline; + renderer->d.drawScanlineDirectly = DSVideoSoftwareRendererDrawScanlineDirectly; renderer->d.finishFrame = DSVideoSoftwareRendererFinishFrame; renderer->d.getPixels = DSVideoSoftwareRendererGetPixels; renderer->d.putPixels = DSVideoSoftwareRendererPutPixels; @@ -578,6 +580,17 @@ static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer _drawScanlineB(softwareRenderer, y); } +static void DSVideoSoftwareRendererDrawScanlineDirectly(struct DSVideoRenderer* renderer, int y, color_t* scanline) { + struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer; + if (!DSRegisterPOWCNT1IsSwap(softwareRenderer->powcnt)) { + softwareRenderer->engA.outputBuffer = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * DS_VIDEO_VERTICAL_PIXELS]; + } else { + softwareRenderer->engA.outputBuffer = softwareRenderer->outputBuffer; + } + + DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, softwareRenderer->d.gx, y); +} + static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer) { struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer; softwareRenderer->engA.d.finishFrame(&softwareRenderer->engA.d); diff --git a/src/ds/video.c b/src/ds/video.c index 1f7424a2f..2251810df 100644 --- a/src/ds/video.c +++ b/src/ds/video.c @@ -23,6 +23,7 @@ static void DSVideoDummyRendererWritePalette(struct DSVideoRenderer* renderer, u static void DSVideoDummyRendererWriteOAM(struct DSVideoRenderer* renderer, uint32_t oam); static void DSVideoDummyRendererInvalidateExtPal(struct DSVideoRenderer* renderer, bool obj, bool engB, int slot); static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, int y); +static void DSVideoDummyRendererDrawScanlineDirectly(struct DSVideoRenderer* renderer, int y, color_t* scanline); static void DSVideoDummyRendererFinishFrame(struct DSVideoRenderer* renderer); static void DSVideoDummyRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels); static void DSVideoDummyRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels); @@ -136,6 +137,7 @@ static struct DSVideoRenderer dummyRenderer = { .writeOAM = DSVideoDummyRendererWriteOAM, .invalidateExtPal = DSVideoDummyRendererInvalidateExtPal, .drawScanline = DSVideoDummyRendererDrawScanline, + .drawScanlineDirectly = DSVideoDummyRendererDrawScanlineDirectly, .finishFrame = DSVideoDummyRendererFinishFrame, .getPixels = DSVideoDummyRendererGetPixels, .putPixels = DSVideoDummyRendererPutPixels, @@ -221,6 +223,7 @@ static void _performCapture(struct DSVideo* video, int y) { } uint16_t* vram = &video->vram[0x10000 * block + DSRegisterDISPCAPCNTGetWriteOffset(dispcap) * 0x4000]; const color_t* pixelsA; + color_t pixels[DS_VIDEO_VERTICAL_PIXELS]; int width = DS_VIDEO_HORIZONTAL_PIXELS; switch (DSRegisterDISPCAPCNTGetCaptureSize(dispcap)) { case 0: @@ -239,15 +242,13 @@ static void _performCapture(struct DSVideo* video, int y) { } video->p->gx.renderer->getScanline(video->p->gx.renderer, y, &pixelsA); - /*if (DSRegisterDISPCAPCNTIsSourceA(dispcap)) { + if (DSRegisterDISPCAPCNTIsSourceA(dispcap)) { // TODO: Process scanline regardless of output type video->p->gx.renderer->getScanline(video->p->gx.renderer, y, &pixelsA); } else { - size_t stride; - const void* pixels; - video->renderer->getPixels(video->renderer, &stride, &pixels); - pixelsA = &((const color_t*) pixels)[stride * y]; - }*/ + video->renderer->drawScanlineDirectly(video->renderer, y, pixels); + pixelsA = pixels; + } uint16_t pixel; int x; @@ -636,6 +637,13 @@ static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, i // Nothing to do } +static void DSVideoDummyRendererDrawScanlineDirectly(struct DSVideoRenderer* renderer, int y, color_t* scanline) { + UNUSED(renderer); + UNUSED(y); + UNUSED(scanline); + // Nothing to do +} + static void DSVideoDummyRendererFinishFrame(struct DSVideoRenderer* renderer) { UNUSED(renderer); // Nothing to do