mirror of https://github.com/mgba-emu/mgba.git
mGUI: Cache save state screenshot validity in state menu (fixes #2005)
This commit is contained in:
parent
ccafcf7bdc
commit
c6aa7c6673
1
CHANGES
1
CHANGES
|
@ -23,6 +23,7 @@ Other fixes:
|
|||
- GB Audio: Fix audio channel 4 being slow to deserialize
|
||||
- GB Core: Fix GBC colors setting breaking default model overrides (fixes mgba.io/i/2161)
|
||||
- GBA: Fix out of bounds ROM accesses on patched ROMs smaller than 32 MiB
|
||||
- mGUI: Cache save state screenshot validity in state menu (fixes mgba.io/i/2005)
|
||||
- Qt: Fix infrequent deadlock when using sync to video
|
||||
- Qt: Fix applying savetype-only overrides
|
||||
- Qt: Fix crash in sprite view for partially out-of-bounds sprites (fixes mgba.io/i/2165)
|
||||
|
|
|
@ -42,6 +42,11 @@ enum {
|
|||
|
||||
#define RUNNER_STATE(X) ((X) << 16)
|
||||
|
||||
enum {
|
||||
SCREENSHOT_VALID = 0x10000,
|
||||
SCREENSHOT_INVALID = 0x20000,
|
||||
};
|
||||
|
||||
static const struct mInputPlatformInfo _mGUIKeyInfo = {
|
||||
.platformName = "gui",
|
||||
.keyId = (const char*[GUI_INPUT_MAX]) {
|
||||
|
@ -107,39 +112,49 @@ static void _drawBackground(struct GUIBackground* background, void* context) {
|
|||
|
||||
static void _drawState(struct GUIBackground* background, void* id) {
|
||||
struct mGUIBackground* gbaBackground = (struct mGUIBackground*) background;
|
||||
int stateId = ((int) id) >> 16;
|
||||
unsigned stateId = ((uint32_t) id) >> 16;
|
||||
if (gbaBackground->p->drawScreenshot) {
|
||||
unsigned w, h;
|
||||
gbaBackground->p->core->desiredVideoDimensions(gbaBackground->p->core, &w, &h);
|
||||
if (gbaBackground->screenshot && gbaBackground->screenshotId == (int) id) {
|
||||
gbaBackground->p->drawScreenshot(gbaBackground->p, gbaBackground->screenshot, w, h, true);
|
||||
size_t size = w * h * BYTES_PER_PIXEL;
|
||||
if (size != gbaBackground->imageSize) {
|
||||
mappedMemoryFree(gbaBackground->image, gbaBackground->imageSize);
|
||||
gbaBackground->image = NULL;
|
||||
}
|
||||
if (gbaBackground->image && gbaBackground->screenshotId == (stateId | SCREENSHOT_VALID)) {
|
||||
gbaBackground->p->drawScreenshot(gbaBackground->p, gbaBackground->image, w, h, true);
|
||||
return;
|
||||
}
|
||||
struct VFile* vf = mCoreGetState(gbaBackground->p->core, stateId, false);
|
||||
color_t* pixels = gbaBackground->screenshot;
|
||||
if (!pixels) {
|
||||
pixels = anonymousMemoryMap(w * h * 4);
|
||||
gbaBackground->screenshot = pixels;
|
||||
}
|
||||
bool success = false;
|
||||
if (vf && isPNG(vf) && pixels) {
|
||||
png_structp png = PNGReadOpen(vf, PNG_HEADER_BYTES);
|
||||
png_infop info = png_create_info_struct(png);
|
||||
png_infop end = png_create_info_struct(png);
|
||||
if (png && info && end) {
|
||||
success = PNGReadHeader(png, info);
|
||||
success = success && PNGReadPixels(png, info, pixels, w, h, w);
|
||||
success = success && PNGReadFooter(png, end);
|
||||
} else if (gbaBackground->screenshotId != (stateId | SCREENSHOT_INVALID)) {
|
||||
struct VFile* vf = mCoreGetState(gbaBackground->p->core, stateId, false);
|
||||
color_t* pixels = gbaBackground->image;
|
||||
if (!pixels) {
|
||||
pixels = anonymousMemoryMap(size);
|
||||
gbaBackground->image = pixels;
|
||||
gbaBackground->imageSize = size;
|
||||
}
|
||||
bool success = false;
|
||||
if (vf && isPNG(vf) && pixels) {
|
||||
png_structp png = PNGReadOpen(vf, PNG_HEADER_BYTES);
|
||||
png_infop info = png_create_info_struct(png);
|
||||
png_infop end = png_create_info_struct(png);
|
||||
if (png && info && end) {
|
||||
success = PNGReadHeader(png, info);
|
||||
success = success && PNGReadPixels(png, info, pixels, w, h, w);
|
||||
success = success && PNGReadFooter(png, end);
|
||||
}
|
||||
PNGReadClose(png, info, end);
|
||||
}
|
||||
if (vf) {
|
||||
vf->close(vf);
|
||||
}
|
||||
if (success) {
|
||||
gbaBackground->p->drawScreenshot(gbaBackground->p, pixels, w, h, true);
|
||||
gbaBackground->screenshotId = stateId | SCREENSHOT_VALID;
|
||||
} else {
|
||||
gbaBackground->screenshotId = stateId | SCREENSHOT_INVALID;
|
||||
}
|
||||
PNGReadClose(png, info, end);
|
||||
}
|
||||
if (vf) {
|
||||
vf->close(vf);
|
||||
}
|
||||
if (success) {
|
||||
gbaBackground->p->drawScreenshot(gbaBackground->p, pixels, w, h, true);
|
||||
gbaBackground->screenshotId = (int) id;
|
||||
} else if (gbaBackground->p->drawFrame) {
|
||||
if (gbaBackground->p->drawFrame && gbaBackground->screenshotId == (stateId | SCREENSHOT_INVALID)) {
|
||||
gbaBackground->p->drawFrame(gbaBackground->p, true);
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +330,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
|
|||
.draw = _drawState
|
||||
},
|
||||
.p = runner,
|
||||
.screenshot = 0,
|
||||
.image = 0,
|
||||
.screenshotId = 0
|
||||
};
|
||||
struct GUIMenu pauseMenu = {
|
||||
|
@ -628,10 +643,10 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
|
|||
runner->core->reset(runner->core);
|
||||
break;
|
||||
case RUNNER_SAVE_STATE:
|
||||
mCoreSaveState(runner->core, ((int) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_RTC | SAVESTATE_METADATA);
|
||||
mCoreSaveState(runner->core, ((uint32_t) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_RTC | SAVESTATE_METADATA);
|
||||
break;
|
||||
case RUNNER_LOAD_STATE:
|
||||
mCoreLoadState(runner->core, ((int) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_RTC);
|
||||
mCoreLoadState(runner->core, ((uint32_t) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_RTC);
|
||||
break;
|
||||
case RUNNER_SCREENSHOT:
|
||||
mCoreTakeScreenshot(runner->core);
|
||||
|
@ -696,10 +711,8 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
|
|||
mLOG(GUI_RUNNER, DEBUG, "Unloading game...");
|
||||
runner->core->unloadROM(runner->core);
|
||||
drawState.screenshotId = 0;
|
||||
if (drawState.screenshot) {
|
||||
unsigned w, h;
|
||||
runner->core->desiredVideoDimensions(runner->core, &w, &h);
|
||||
mappedMemoryFree(drawState.screenshot, w * h * 4);
|
||||
if (drawState.image) {
|
||||
mappedMemoryFree(drawState.image, drawState.imageSize);
|
||||
}
|
||||
|
||||
if (runner->config.port) {
|
||||
|
|
|
@ -31,8 +31,10 @@ struct mGUIBackground {
|
|||
struct GUIBackground d;
|
||||
struct mGUIRunner* p;
|
||||
|
||||
color_t* screenshot;
|
||||
int screenshotId;
|
||||
color_t* image;
|
||||
size_t imageSize;
|
||||
|
||||
unsigned screenshotId;
|
||||
};
|
||||
|
||||
struct mCore;
|
||||
|
|
Loading…
Reference in New Issue