mirror of https://github.com/mgba-emu/mgba.git
Core: Put back sram in savestates
This commit is contained in:
parent
c3f69e7b69
commit
5ea104844d
|
@ -121,6 +121,9 @@ struct mCore {
|
|||
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
|
||||
|
|
|
@ -310,20 +310,16 @@ bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags) {
|
|||
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 @@ bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags) {
|
|||
}
|
||||
}
|
||||
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)) {
|
||||
|
|
|
@ -409,6 +409,33 @@ static struct mCheatDevice* _GBCoreCheatDevice(struct mCore* core) {
|
|||
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 @@ struct mCore* GBCoreCreate(void) {
|
|||
core->attachDebugger = _GBCoreAttachDebugger;
|
||||
core->detachDebugger = _GBCoreDetachDebugger;
|
||||
core->cheatDevice = _GBCoreCheatDevice;
|
||||
core->savedataClone = _GBCoreSavedataClone;
|
||||
core->savedataLoad = _GBCoreSavedataLoad;
|
||||
return core;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#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 @@ static struct mCheatDevice* _GBACoreCheatDevice(struct mCore* core) {
|
|||
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 @@ struct mCore* GBACoreCreate(void) {
|
|||
core->attachDebugger = _GBACoreAttachDebugger;
|
||||
core->detachDebugger = _GBACoreDetachDebugger;
|
||||
core->cheatDevice = _GBACoreCheatDevice;
|
||||
core->savedataClone = _GBACoreSavedataClone;
|
||||
core->savedataLoad = _GBACoreSavedataLoad;
|
||||
return core;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,27 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
|
|||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue