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"); }
struct VFile* mLibraryOpenVFile(struct mLibrary* library, const struct mLibraryEntry* entry) { struct mLibraryListing entries; mLibraryListingInit(&entries, 0); if (!mLibraryGetEntries(library, &entries, 0, 0, entry)) { mLibraryListingDeinit(&entries); return NULL; } struct VFile* vf = NULL; size_t i; for (i = 0; i < mLibraryListingSize(&entries); ++i) { struct mLibraryEntry* e = mLibraryListingGetPointer(&entries, i); struct VDir* dir = VDirOpenArchive(e->base); bool isArchive = true; if (!dir) { dir = VDirOpen(e->base); isArchive = false; } if (!dir) { continue; } vf = dir->openFile(dir, e->filename, O_RDONLY); if (vf && isArchive) { struct VFile* vfclone = VFileMemChunk(NULL, vf->size(vf)); uint8_t buffer[2048]; ssize_t read; while ((read = vf->read(vf, buffer, sizeof(buffer))) > 0) { vfclone->write(vfclone, buffer, read); } vf->close(vf); vf = vfclone; } dir->close(dir); if (vf) { break; } } return vf; }