Allow save file to be specified externally

This commit is contained in:
Jeffrey Pfau 2014-07-16 02:57:04 -07:00
parent 7bb5e29a98
commit 42484bbcc3
7 changed files with 32 additions and 42 deletions

View File

@ -2,6 +2,7 @@
#define COMMON_H
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);