all repos — mgba @ 5ea104844d58095e3dc002d93074d3302976cae6

mGBA Game Boy Advance Emulator

Core: Put back sram in savestates
Jeffrey Pfau jeffrey@endrift.com
Mon, 30 May 2016 23:16:00 -0700
commit

5ea104844d58095e3dc002d93074d3302976cae6

parent

c3f69e7b693ae568e33d83cee264040c2db3d516

6 files changed, 99 insertions(+), 13 deletions(-)

jump to
M src/core/core.hsrc/core/core.h

@@ -121,6 +121,9 @@ void (*attachDebugger)(struct mCore*, struct mDebugger*);

void (*detachDebugger)(struct mCore*); struct mCheatDevice* (*cheatDevice)(struct mCore*); + + size_t (*savedataClone)(struct mCore*, void** sram); + bool (*savedataLoad)(struct mCore*, const void* sram, size_t size); }; #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
M src/core/serialize.csrc/core/serialize.c

@@ -310,20 +310,16 @@ struct mStateExtdata extdata;

mStateExtdataInit(&extdata); size_t stateSize = core->stateSize(core); if (flags & SAVESTATE_SAVEDATA) { - /* // TODO: A better way to do this would be nice - void* sram = malloc(SIZE_CART_FLASH1M); - struct VFile* svf = VFileFromMemory(sram, SIZE_CART_FLASH1M); - if (GBASavedataClone(&gba->memory.savedata, svf)) { + void* sram = NULL; + size_t size = core->savedataClone(core, &sram); + if (size) { struct mStateExtdataItem item = { - .size = svf->seek(svf, 0, SEEK_CUR), + .size = size, .data = sram, .clean = free }; mStateExtdataPut(&extdata, EXTDATA_SAVEDATA, &item); - } else { - free(sram); } - svf->close(svf);*/ } struct VFile* cheatVf = 0; struct mCheatDevice* device;

@@ -419,11 +415,9 @@ mLOG(SAVESTATE, WARN, "Savestate includes invalid screenshot");

} } if (flags & SAVESTATE_SAVEDATA && mStateExtdataGet(&extdata, EXTDATA_SAVEDATA, &item)) { - /*struct VFile* svf = VFileFromMemory(item.data, item.size); - GBASavedataLoad(&gba->memory.savedata, svf); - if (svf) { - svf->close(svf); - }*/ + if (item.data) { + core->savedataLoad(core, item.data, item.size); + } } struct mCheatDevice* device; if (flags & SAVESTATE_CHEATS && (device = core->cheatDevice(core)) && mStateExtdataGet(&extdata, EXTDATA_CHEATS, &item)) {
M src/gb/core.csrc/gb/core.c

@@ -409,6 +409,33 @@ }

return gbcore->cheatDevice; } +static size_t _GBCoreSavedataClone(struct mCore* core, void** sram) { + struct GB* gb = core->board; + struct VFile* vf = gb->sramVf; + if (vf) { + *sram = malloc(vf->size(vf)); + vf->seek(vf, 0, SEEK_SET); + return vf->read(vf, *sram, vf->size(vf)); + } + *sram = malloc(0x20000); + memcpy(*sram, gb->memory.sram, 0x20000); + return 0x20000; +} + +static bool _GBCoreSavedataLoad(struct mCore* core, const void* sram, size_t size) { + struct GB* gb = core->board; + struct VFile* vf = gb->sramVf; + if (vf) { + vf->seek(vf, 0, SEEK_SET); + return vf->write(vf, sram, size) > 0; + } + if (size > 0x20000) { + size = 0x20000; + } + memcpy(gb->memory.sram, sram, 0x20000); + return true; +} + struct mCore* GBCoreCreate(void) { struct GBCore* gbcore = malloc(sizeof(*gbcore)); struct mCore* core = &gbcore->d;

@@ -470,5 +497,7 @@ core->cliDebuggerSystem = _GBCoreCliDebuggerSystem;

core->attachDebugger = _GBCoreAttachDebugger; core->detachDebugger = _GBCoreDetachDebugger; core->cheatDevice = _GBCoreCheatDevice; + core->savedataClone = _GBCoreSavedataClone; + core->savedataLoad = _GBCoreSavedataLoad; return core; }
M src/gba/core.csrc/gba/core.c

@@ -13,6 +13,7 @@ #include "gba/gba.h"

#include "gba/extra/cli.h" #include "gba/overrides.h" #include "gba/renderers/video-software.h" +#include "gba/savedata.h" #include "gba/serialize.h" #include "util/memory.h" #include "util/patch.h"

@@ -429,6 +430,41 @@ }

return gbacore->cheatDevice; } +static size_t _GBACoreSavedataClone(struct mCore* core, void** sram) { + struct GBA* gba = core->board; + size_t size = GBASavedataSize(&gba->memory.savedata); + if (!size) { + *sram = NULL; + return 0; + } + *sram = malloc(size); + struct VFile* vf = VFileFromMemory(*sram, size); + if (!vf) { + free(*sram); + *sram = NULL; + return 0; + } + bool success = GBASavedataClone(&gba->memory.savedata, vf); + vf->close(vf); + if (!success) { + free(*sram); + *sram = NULL; + return 0; + } + return size; +} + +static bool _GBACoreSavedataLoad(struct mCore* core, const void* sram, size_t size) { + struct VFile* vf = VFileFromConstMemory(sram, size); + if (!vf) { + return false; + } + struct GBA* gba = core->board; + bool success = GBASavedataLoad(&gba->memory.savedata, vf); + vf->close(vf); + return success; +} + struct mCore* GBACoreCreate(void) { struct GBACore* gbacore = malloc(sizeof(*gbacore)); struct mCore* core = &gbacore->d;

@@ -490,5 +526,7 @@ core->cliDebuggerSystem = _GBACoreCliDebuggerSystem;

core->attachDebugger = _GBACoreAttachDebugger; core->detachDebugger = _GBACoreDetachDebugger; core->cheatDevice = _GBACoreCheatDevice; + core->savedataClone = _GBACoreSavedataClone; + core->savedataLoad = _GBACoreSavedataLoad; return core; }
M src/gba/savedata.csrc/gba/savedata.c

@@ -125,6 +125,27 @@ }

return true; } +size_t GBASavedataSize(struct GBASavedata* savedata) { + switch (savedata->type) { + case SAVEDATA_SRAM: + return SIZE_CART_SRAM; + case SAVEDATA_FLASH512: + return SIZE_CART_FLASH512; + case SAVEDATA_FLASH1M: + return SIZE_CART_FLASH1M; + case SAVEDATA_EEPROM: + return SIZE_CART_EEPROM; + case SAVEDATA_FORCE_NONE: + return 0; + case SAVEDATA_AUTODETECT: + default: + if (savedata->vf) { + return savedata->vf->size(savedata->vf); + } + return 0; + } +} + bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) { if (savedata->vf) { off_t read = 0;
M src/gba/savedata.hsrc/gba/savedata.h

@@ -97,6 +97,7 @@ void GBASavedataDeinit(struct GBASavedata* savedata);

void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf); void GBASavedataUnmask(struct GBASavedata* savedata); +size_t GBASavedataSize(struct GBASavedata* savedata); bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out); bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in); void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type, bool realisticTiming);