static bool _savePNGState(struct GBA* gba, struct VFile* vf) { unsigned stride; const void* pixels = 0; gba->video.renderer->getPixels(gba->video.renderer, &stride, &pixels); if (!pixels) { return false; } struct GBASerializedState* state = GBAAllocateState(); if (!state) { return false; } GBASerialize(gba, state); uLongf len = compressBound(sizeof(*state)); void* buffer = malloc(len); if (!buffer) { GBADeallocateState(state); return false; } compress(buffer, &len, (const Bytef*) state, sizeof(*state)); GBADeallocateState(state); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); if (!png || !info) { PNGWriteClose(png, info); free(buffer); return false; } PNGWritePixels(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, stride, pixels); PNGWriteCustomChunk(png, "gbAs", len, buffer); PNGWriteClose(png, info); free(buffer); return true; }
void mCoreTakeScreenshot(struct mCore* core) { #ifdef USE_PNG size_t stride; color_t* pixels = 0; unsigned width, height; core->desiredVideoDimensions(core, &width, &height); struct VFile* vf = VDirFindNextAvailable(core->dirs.screenshot, core->dirs.baseName, "-", ".png", O_CREAT | O_TRUNC | O_WRONLY); bool success = false; if (vf) { core->getVideoBuffer(core, &pixels, &stride); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, width, height); success = PNGWritePixels(png, width, height, stride, pixels); PNGWriteClose(png, info); vf->close(vf); } if (success) { mLOG(STATUS, INFO, "Screenshot saved"); return; } #else UNUSED(core); #endif mLOG(STATUS, WARN, "Failed to take screenshot"); }
void mCoreTakeScreenshot(struct mCore* core) { #ifdef USE_PNG size_t stride; const void* pixels = 0; unsigned width, height; core->desiredVideoDimensions(core, &width, &height); struct VFile* vf; #ifndef PSP2 vf = VDirFindNextAvailable(core->dirs.screenshot, core->dirs.baseName, "-", ".png", O_CREAT | O_TRUNC | O_WRONLY); #else vf = VFileMemChunk(0, 0); #endif bool success = false; if (vf) { core->getPixels(core, &pixels, &stride); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, width, height); success = PNGWritePixels(png, width, height, stride, pixels); PNGWriteClose(png, info); #ifdef PSP2 void* data = vf->map(vf, 0, 0); PhotoExportParam param = { 0, NULL, NULL, NULL, { 0 } }; scePhotoExportFromData(data, vf->size(vf), ¶m, NULL, NULL, NULL, NULL, 0); #endif vf->close(vf); } if (success) { mLOG(STATUS, INFO, "Screenshot saved"); return; } #else UNUSED(core); #endif mLOG(STATUS, WARN, "Failed to take screenshot"); }
void GBATakeScreenshot(struct GBA* gba, struct VDir* dir) { #ifdef USE_PNG unsigned stride; const void* pixels = 0; struct VFile* vf = VDirOptionalOpenIncrementFile(dir, gba->activeFile, "screenshot", "-", ".png", O_CREAT | O_TRUNC | O_WRONLY); bool success = false; if (vf) { gba->video.renderer->getPixels(gba->video.renderer, &stride, &pixels); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); success = PNGWritePixels(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, stride, pixels); PNGWriteClose(png, info); vf->close(vf); } if (success) { GBALog(gba, GBA_LOG_STATUS, "Screenshot saved"); return; } #endif GBALog(gba, GBA_LOG_STATUS, "Failed to take screenshot"); }