GBA SIO: Add support for side data in save states

This commit is contained in:
Vicki Pfau 2024-09-07 21:12:19 -07:00
parent 26e20ca846
commit 630e3a591a
3 changed files with 40 additions and 1 deletions

View File

@ -113,6 +113,9 @@ struct GBASIODriver {
void (*reset)(struct GBASIODriver* driver); void (*reset)(struct GBASIODriver* driver);
bool (*load)(struct GBASIODriver* driver); bool (*load)(struct GBASIODriver* driver);
bool (*unload)(struct GBASIODriver* driver); bool (*unload)(struct GBASIODriver* driver);
uint32_t (*driverId)(const struct GBASIODriver* renderer);
bool (*loadState)(struct GBASIODriver* renderer, const void* state, size_t size);
void (*saveState)(struct GBASIODriver* renderer, void** state, size_t* size);
void (*setMode)(struct GBASIODriver* driver, enum GBASIOMode mode); void (*setMode)(struct GBASIODriver* driver, enum GBASIOMode mode);
bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode); bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode);
int (*connectedDevices)(struct GBASIODriver* driver); int (*connectedDevices)(struct GBASIODriver* driver);

View File

@ -287,6 +287,7 @@ DECL_BITS(GBASerializedMiscFlags, KeyIRQKeys, 4, 11);
enum { enum {
GBA_SUBSYSTEM_VIDEO_RENDERER = 0, GBA_SUBSYSTEM_VIDEO_RENDERER = 0,
GBA_SUBSYSTEM_SIO_DRIVER = 1,
GBA_SUBSYSTEM_MAX, GBA_SUBSYSTEM_MAX,
}; };

View File

@ -842,7 +842,21 @@ static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdat
if (type == gba->video.renderer->rendererId(gba->video.renderer)) { if (type == gba->video.renderer->rendererId(gba->video.renderer)) {
ok = gba->video.renderer->loadState(gba->video.renderer, ok = gba->video.renderer->loadState(gba->video.renderer,
(void*) ((uintptr_t) item.data + sizeof(uint32_t)), (void*) ((uintptr_t) item.data + sizeof(uint32_t)),
item.size - sizeof(type)); item.size - sizeof(type)) && ok;
}
} else if (item.data) {
ok = false;
}
}
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->loadState &&
mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item)) {
if ((uint32_t) item.size > sizeof(uint32_t)) {
uint32_t type;
LOAD_32(type, 0, item.data);
if (type == gba->sio.activeDriver->driverId(gba->sio.activeDriver)) {
ok = gba->sio.activeDriver->loadState(gba->sio.activeDriver,
(void*) ((uintptr_t) item.data + sizeof(uint32_t)),
item.size - sizeof(type)) && ok;
} }
} else if (item.data) { } else if (item.data) {
ok = false; ok = false;
@ -868,6 +882,27 @@ static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* ext
} }
if (buffer) { if (buffer) {
free(buffer); free(buffer);
buffer = NULL;
}
size = 0;
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->saveState) {
gba->sio.activeDriver->saveState(gba->sio.activeDriver, &buffer, &size);
if (size > 0 && buffer) {
struct mStateExtdataItem item;
item.size = size + sizeof(uint32_t);
item.data = malloc(item.size);
item.clean = free;
uint32_t type = gba->sio.activeDriver->driverId(gba->sio.activeDriver);
STORE_32(type, 0, item.data);
memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size);
mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item);
}
if (buffer) {
free(buffer);
buffer = NULL;
}
size = 0;
} }
return true; return true;