From 42484bbcc35c6486edb6120c3f56b3432b3360f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 16 Jul 2014 02:57:04 -0700 Subject: [PATCH] Allow save file to be specified externally --- src/arm/common.h | 1 + src/gba/gba-savedata.c | 12 ++--------- src/gba/gba-savedata.h | 3 +-- src/gba/gba-thread.c | 47 +++++++++++++++++++++--------------------- src/gba/gba-thread.h | 1 + src/gba/gba.c | 7 ++----- src/gba/gba.h | 3 +-- 7 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/arm/common.h b/src/arm/common.h index 1cb803622..ff13735c1 100644 --- a/src/arm/common.h +++ b/src/arm/common.h @@ -2,6 +2,7 @@ #define COMMON_H #include +#include #include #include #include diff --git a/src/gba/gba-savedata.c b/src/gba/gba-savedata.c index d56689549..7ea06d4bc 100644 --- a/src/gba/gba-savedata.c +++ b/src/gba/gba-savedata.c @@ -12,13 +12,12 @@ static void _flashSwitchBank(struct GBASavedata* savedata, int bank); static void _flashErase(struct GBASavedata* savedata); static void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart); -void GBASavedataInit(struct GBASavedata* savedata, const char* filename) { +void GBASavedataInit(struct GBASavedata* savedata, struct VFile* vf) { savedata->type = SAVEDATA_NONE; savedata->data = 0; savedata->command = EEPROM_COMMAND_NULL; savedata->flashState = FLASH_STATE_RAW; - savedata->vf = 0; - savedata->filename = filename; + savedata->vf = vf; } void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) { @@ -47,7 +46,6 @@ void GBASavedataDeinit(struct GBASavedata* savedata) { case SAVEDATA_NONE: break; } - savedata->vf->close(savedata->vf); savedata->vf = 0; } else { switch (savedata->type) { @@ -78,10 +76,8 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; if (!savedata->vf) { - GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_FLASH1M); } else { @@ -105,10 +101,8 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; if (!savedata->vf) { - GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); } else { @@ -130,10 +124,8 @@ void GBASavedataInitSRAM(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; if (!savedata->vf) { - GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_SRAM); } else { diff --git a/src/gba/gba-savedata.h b/src/gba/gba-savedata.h index 15a3cca57..929a204a8 100644 --- a/src/gba/gba-savedata.h +++ b/src/gba/gba-savedata.h @@ -55,7 +55,6 @@ enum { struct GBASavedata { enum SavedataType type; uint8_t* data; - const char* filename; enum SavedataCommand command; struct VFile* vf; @@ -70,7 +69,7 @@ struct GBASavedata { enum FlashStateMachine flashState; }; -void GBASavedataInit(struct GBASavedata* savedata, const char* filename); +void GBASavedataInit(struct GBASavedata* savedata, struct VFile* vf); void GBASavedataDeinit(struct GBASavedata* savedata); void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type); diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index c7de7d61d..2b0565ce1 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -59,7 +59,6 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { struct GBAThread* threadContext = context; struct ARMComponent* components[1] = {}; int numComponents = 0; - char* savedata = 0; if (threadContext->debugger) { components[numComponents] = &threadContext->debugger->d; @@ -90,27 +89,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { } if (threadContext->fd) { - if (threadContext->fname) { - char* dotPoint = strrchr(threadContext->fname, '.'); - if (dotPoint > strrchr(threadContext->fname, '/') && dotPoint[1] && dotPoint[2] && dotPoint[3]) { - savedata = strdup(threadContext->fname); - dotPoint = strrchr(savedata, '.'); - dotPoint[1] = 's'; - dotPoint[2] = 'a'; - dotPoint[3] = 'v'; - dotPoint[4] = '\0'; - } else if (dotPoint) { - savedata = malloc((dotPoint - threadContext->fname + 5) * sizeof(char)); - strncpy(savedata, threadContext->fname, dotPoint - threadContext->fname + 1); - strcat(savedata, "sav"); - } else { - savedata = malloc(strlen(threadContext->fname + 5)); - strcpy(savedata, threadContext->fname); - strcat(savedata, "sav"); - } - } - gba.savefile = savedata; - GBALoadROM(&gba, threadContext->fd, threadContext->fname); + GBALoadROM(&gba, threadContext->fd, threadContext->saveFd, threadContext->fname); if (threadContext->biosFd) { GBALoadBIOS(&gba, threadContext->biosFd); } @@ -185,7 +164,6 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { ConditionWake(&threadContext->sync.videoFrameAvailableCond); ConditionWake(&threadContext->sync.audioRequiredCond); - free(savedata); return 0; } @@ -216,6 +194,29 @@ bool GBAThreadStart(struct GBAThread* threadContext) { threadContext->rewindBuffer = 0; } + if (threadContext->fname && !threadContext->saveFd) { + char* savedata = 0; + char* dotPoint = strrchr(threadContext->fname, '.'); + if (dotPoint > strrchr(threadContext->fname, '/') && dotPoint[1] && dotPoint[2] && dotPoint[3]) { + savedata = strdup(threadContext->fname); + dotPoint = strrchr(savedata, '.'); + dotPoint[1] = 's'; + dotPoint[2] = 'a'; + dotPoint[3] = 'v'; + dotPoint[4] = '\0'; + } else if (dotPoint) { + savedata = malloc((dotPoint - threadContext->fname + 5) * sizeof(char)); + strncpy(savedata, threadContext->fname, dotPoint - threadContext->fname + 1); + strcat(savedata, "sav"); + } else { + savedata = malloc(strlen(threadContext->fname + 5)); + strcpy(savedata, threadContext->fname); + strcat(savedata, "sav"); + } + threadContext->saveFd = VFileOpen(savedata, O_RDWR | O_CREAT); + free(savedata); + } + MutexInit(&threadContext->stateMutex); ConditionInit(&threadContext->stateCond); diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index 4db039da3..d25afaa54 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -48,6 +48,7 @@ struct GBAThread { struct GBASIODriverSet sioDrivers; struct ARMDebugger* debugger; struct VFile* fd; + struct VFile* saveFd; struct VFile* biosFd; struct VFile* patchFd; const char* fname; diff --git a/src/gba/gba.c b/src/gba/gba.c index 1018a6e6d..1549b03ad 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -109,7 +109,6 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) { struct GBA* gba = (struct GBA*) component; gba->cpu = cpu; gba->debugger = 0; - gba->savefile = 0; GBAInterruptHandlerInit(&cpu->irqh); GBAMemoryInit(gba); @@ -373,7 +372,7 @@ void GBADetachDebugger(struct GBA* gba) { gba->debugger = 0; } -void GBALoadROM(struct GBA* gba, struct VFile* vf, const char* fname) { +void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname) { gba->romVf = vf; gba->pristineRomSize = vf->seek(vf, 0, SEEK_END); vf->seek(vf, 0, SEEK_SET); @@ -381,9 +380,7 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, const char* fname) { gba->memory.rom = gba->pristineRom; gba->activeFile = fname; gba->memory.romSize = gba->pristineRomSize; - if (gba->savefile) { - GBASavedataInit(&gba->memory.savedata, gba->savefile); - } + GBASavedataInit(&gba->memory.savedata, sav); GBAGPIOInit(&gba->memory.gpio, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); _checkOverrides(gba, ((struct GBACartridge*) gba->memory.rom)->id); // TODO: error check diff --git a/src/gba/gba.h b/src/gba/gba.h index 2e7fb9a37..68cf85101 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -104,7 +104,6 @@ struct GBA { struct VFile* biosVf; const char* activeFile; - const char* savefile; int logLevel; GBALogHandler logHandler; @@ -143,7 +142,7 @@ void GBAHalt(struct GBA* gba); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger); void GBADetachDebugger(struct GBA* gba); -void GBALoadROM(struct GBA* gba, struct VFile* vf, const char* fname); +void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname); void GBALoadBIOS(struct GBA* gba, struct VFile* vf); void GBAApplyPatch(struct GBA* gba, struct Patch* patch);