Add function to GBAVideoRenderer for taking screenshot
@@ -16,6 +16,7 @@ static void GBAVideoDummyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
static void GBAVideoDummyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer); +static void GBAVideoDummyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels); static struct GBAVideoRenderer dummyRenderer = { .init = GBAVideoDummyRendererInit,@@ -25,7 +26,8 @@ .writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister,
.writePalette = GBAVideoDummyRendererWritePalette, .writeOAM = GBAVideoDummyRendererWriteOAM, .drawScanline = GBAVideoDummyRendererDrawScanline, - .finishFrame = GBAVideoDummyRendererFinishFrame + .finishFrame = GBAVideoDummyRendererFinishFrame, + .getPixels = GBAVideoDummyRendererGetPixels }; void GBAVideoInit(struct GBAVideo* video) {@@ -218,6 +220,14 @@ static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer) {
UNUSED(renderer); // Nothing to do } + +static void GBAVideoDummyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels) { + UNUSED(renderer); + UNUSED(stride); + UNUSED(pixels); + // Nothing to do +} + void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state) { memcpy(state->vram, video->renderer->vram, SIZE_VRAM);
@@ -178,6 +178,8 @@ void (*writeOAM)(struct GBAVideoRenderer* renderer, uint32_t oam);
void (*drawScanline)(struct GBAVideoRenderer* renderer, int y); void (*finishFrame)(struct GBAVideoRenderer* renderer); + void (*getPixels)(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels); + uint16_t* palette; uint16_t* vram; union GBAOAM* oam;
@@ -29,6 +29,7 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* renderer); +static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels); static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer); static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value);@@ -67,6 +68,7 @@ renderer->d.writeOAM = GBAVideoSoftwareRendererWriteOAM;
renderer->d.writePalette = GBAVideoSoftwareRendererWritePalette; renderer->d.drawScanline = GBAVideoSoftwareRendererDrawScanline; renderer->d.finishFrame = GBAVideoSoftwareRendererFinishFrame; + renderer->d.getPixels = GBAVideoSoftwareRendererGetPixels; } static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) {@@ -499,6 +501,13 @@ softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx;
softwareRenderer->bg[2].sy = softwareRenderer->bg[2].refy; softwareRenderer->bg[3].sx = softwareRenderer->bg[3].refx; softwareRenderer->bg[3].sy = softwareRenderer->bg[3].refy; +} + +static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels) { + struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; + + *stride = softwareRenderer->outputBufferStride; + *pixels = softwareRenderer->outputBuffer; } static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer) {
@@ -77,7 +77,6 @@ #if SDL_VERSION_ATLEAST(2, 0, 0)
renderer.events.fullscreen = graphicsOpts.fullscreen; renderer.events.windowUpdated = 0; #endif - renderer.events.renderer = &renderer.d; if (!_GBASDLInit(&renderer)) { freeOptions(&opts);
@@ -18,7 +18,7 @@
#define SDL_BINDING_KEY 0x53444C4B #define SDL_BINDING_BUTTON 0x53444C42 -static void _takeScreenshot(struct GBAThread*, struct GBASDLEvents*); +static void _takeScreenshot(struct GBAThread*); bool GBASDLInitEvents(struct GBASDLEvents* context) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {@@ -82,7 +82,7 @@ return;
case SDLK_F12: if (event->type == SDL_KEYDOWN) { GBAThreadInterrupt(context); - _takeScreenshot(context, sdlContext); + _takeScreenshot(context); GBAThreadContinue(context); } return;@@ -262,11 +262,14 @@ _GBASDLHandleJoyHat(context, &event->jhat);
} } -static void _takeScreenshot(struct GBAThread* context, struct GBASDLEvents* sdlContext) { +static void _takeScreenshot(struct GBAThread* context) { + unsigned stride; + void* pixels = 0; struct VFile* vf = context->stateDir->openFile(context->stateDir, "screenshot.png", O_CREAT | O_WRONLY); + context->gba->video.renderer->getPixels(context->gba->video.renderer, &stride, &pixels); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); - PNGWritePixels(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 256, sdlContext->renderer->outputBuffer); + PNGWritePixels(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, stride, pixels); PNGWriteClose(png, info); vf->close(vf); }
@@ -11,7 +11,6 @@ struct GBAVideoSoftwareRenderer;
struct GBASDLEvents { struct GBAInputMap* bindings; - struct GBAVideoSoftwareRenderer* renderer; SDL_Joystick* joystick; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Window* window;