diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index c20816dbd..1d19c6e79 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -91,6 +91,7 @@ struct mCoreCallbacks { void (*coreCrashed)(void* context); void (*sleep)(void* context); void (*keysRead)(void* context); + void (*savedataUpdated)(void* context); }; DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks); diff --git a/src/gb/gb.c b/src/gb/gb.c index 7aea9eaad..4cd61eca7 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -247,6 +247,14 @@ void GBSramClean(struct GB* gb, uint32_t frameCount) { } else { mLOG(GB_MEM, INFO, "Savedata failed to sync!"); } + + size_t c; + for (c = 0; c < mCoreCallbacksListSize(&gb->coreCallbacks); ++c) { + struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gb->coreCallbacks, c); + if (callbacks->savedataUpdated) { + callbacks->savedataUpdated(callbacks->context); + } + } } } diff --git a/src/gba/gba.c b/src/gba/gba.c index 18ae17222..693a583b5 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -816,6 +816,7 @@ void GBAFrameStarted(struct GBA* gba) { } void GBAFrameEnded(struct GBA* gba) { + int wasDirty = gba->memory.savedata.dirty; GBASavedataClean(&gba->memory.savedata, gba->video.frameCounter); if (gba->cpu->components && gba->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]) { @@ -846,6 +847,9 @@ void GBAFrameEnded(struct GBA* gba) { if (callbacks->videoFrameEnded) { callbacks->videoFrameEnded(callbacks->context); } + if (callbacks->savedataUpdated && wasDirty && !gba->memory.savedata.dirty) { + callbacks->savedataUpdated(callbacks->context); + } } } diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 39a805725..1ae924a9f 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -534,16 +534,14 @@ void GBASavedataClean(struct GBASavedata* savedata, uint32_t frameCount) { if (savedata->dirty & SAVEDATA_DIRT_NEW) { savedata->dirtAge = frameCount; savedata->dirty &= ~SAVEDATA_DIRT_NEW; - if (!(savedata->dirty & SAVEDATA_DIRT_SEEN)) { - savedata->dirty |= SAVEDATA_DIRT_SEEN; - } + savedata->dirty |= SAVEDATA_DIRT_SEEN; } else if ((savedata->dirty & SAVEDATA_DIRT_SEEN) && frameCount - savedata->dirtAge > CLEANUP_THRESHOLD) { if (savedata->maskWriteback) { GBASavedataUnmask(savedata); } + savedata->dirty = 0; if (savedata->mapMode & MAP_WRITE) { size_t size = GBASavedataSize(savedata); - savedata->dirty = 0; if (savedata->data && savedata->vf->sync(savedata->vf, savedata->data, size)) { mLOG(GBA_SAVE, INFO, "Savedata synced"); } else {