mirror of https://github.com/mgba-emu/mgba.git
Allow save file to be specified externally
This commit is contained in:
parent
7bb5e29a98
commit
42484bbcc3
|
@ -2,6 +2,7 @@
|
|||
#define COMMON_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue