GBA: Rom unloading and replacing

This commit is contained in:
Jeffrey Pfau 2015-06-19 22:28:49 -07:00
parent 289e9b0cf1
commit 635fae7d05
4 changed files with 79 additions and 32 deletions

View File

@ -96,14 +96,22 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
gba->performingDMA = false;
}
void GBADestroy(struct GBA* gba) {
void GBAUnloadROM(struct GBA* gba) {
if (gba->pristineRom == gba->memory.rom) {
gba->memory.rom = 0;
} else {
mappedMemoryFree(gba->pristineRom, gba->pristineRomSize);
}
if (gba->romVf) {
gba->romVf->unmap(gba->romVf, gba->pristineRom, gba->pristineRomSize);
gba->pristineRom = 0;
gba->romVf = 0;
}
}
void GBADestroy(struct GBA* gba) {
GBAUnloadROM(gba);
if (gba->biosVf) {
gba->biosVf->unmap(gba->biosVf, gba->memory.bios, SIZE_BIOS);
@ -370,6 +378,7 @@ void GBADetachDebugger(struct GBA* gba) {
}
void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname) {
GBAUnloadROM(gba);
gba->romVf = vf;
gba->pristineRomSize = vf->size(vf);
vf->seek(vf, 0, SEEK_SET);

View File

@ -208,6 +208,7 @@ void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mo
void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname);
void GBAYankROM(struct GBA* gba);
void GBAUnloadROM(struct GBA* gba);
void GBALoadBIOS(struct GBA* gba, struct VFile* vf);
void GBAApplyPatch(struct GBA* gba, struct Patch* patch);

View File

@ -23,6 +23,8 @@
#include <signal.h>
static void _loadGameDir(struct GBAThread* threadContext);
static const float _defaultFPSTarget = 60.f;
#ifndef DISABLE_THREADING
@ -352,18 +354,7 @@ void GBAMapArgumentsToContext(const struct GBAArguments* args, struct GBAThread*
threadContext->gameDir = VDirOpen(args->fname);
threadContext->stateDir = threadContext->gameDir;
} else {
threadContext->rom = VFileOpen(args->fname, O_RDONLY);
threadContext->gameDir = 0;
#if USE_LIBZIP
if (!threadContext->gameDir) {
threadContext->gameDir = VDirOpenZip(args->fname, 0);
}
#endif
#if USE_LZMA
if (!threadContext->gameDir) {
threadContext->gameDir = VDirOpen7z(args->fname, 0);
}
#endif
GBAThreadLoadROM(threadContext, args->fname);
}
threadContext->fname = args->fname;
threadContext->patch = VFileOpen(args->patch, O_RDONLY);
@ -398,25 +389,7 @@ bool GBAThreadStart(struct GBAThread* threadContext) {
}
if (threadContext->gameDir) {
threadContext->gameDir->rewind(threadContext->gameDir);
struct VDirEntry* dirent = threadContext->gameDir->listNext(threadContext->gameDir);
while (dirent) {
struct Patch patchTemp;
struct VFile* vf = threadContext->gameDir->openFile(threadContext->gameDir, dirent->name(dirent), O_RDONLY);
if (!vf) {
dirent = threadContext->gameDir->listNext(threadContext->gameDir);
continue;
}
if (!threadContext->rom && GBAIsROM(vf)) {
threadContext->rom = vf;
} else if (!threadContext->patch && loadPatch(vf, &patchTemp)) {
threadContext->patch = vf;
} else {
vf->close(vf);
}
dirent = threadContext->gameDir->listNext(threadContext->gameDir);
}
_loadGameDir(threadContext);
}
if (!threadContext->rom && !bootBios) {
@ -678,6 +651,67 @@ void GBAThreadPauseFromThread(struct GBAThread* threadContext) {
GBASyncSetVideoSync(&threadContext->sync, frameOn);
}
void GBAThreadLoadROM(struct GBAThread* threadContext, const char* fname) {
threadContext->rom = VFileOpen(fname, O_RDONLY);
threadContext->gameDir = 0;
#if USE_LIBZIP
if (!threadContext->gameDir) {
threadContext->gameDir = VDirOpenZip(fname, 0);
}
#endif
#if USE_LZMA
if (!threadContext->gameDir) {
threadContext->gameDir = VDirOpen7z(fname, 0);
}
#endif
}
static void _loadGameDir(struct GBAThread* threadContext) {
threadContext->gameDir->rewind(threadContext->gameDir);
struct VDirEntry* dirent = threadContext->gameDir->listNext(threadContext->gameDir);
while (dirent) {
struct Patch patchTemp;
struct VFile* vf = threadContext->gameDir->openFile(threadContext->gameDir, dirent->name(dirent), O_RDONLY);
if (!vf) {
dirent = threadContext->gameDir->listNext(threadContext->gameDir);
continue;
}
if (!threadContext->rom && GBAIsROM(vf)) {
threadContext->rom = vf;
} else if (!threadContext->patch && loadPatch(vf, &patchTemp)) {
threadContext->patch = vf;
} else {
vf->close(vf);
}
dirent = threadContext->gameDir->listNext(threadContext->gameDir);
}
}
void GBAThreadReplaceROM(struct GBAThread* threadContext, const char* fname) {
GBAUnloadROM(threadContext->gba);
if (threadContext->rom) {
threadContext->rom->close(threadContext->rom);
threadContext->rom = 0;
}
if (threadContext->save) {
threadContext->save->close(threadContext->save);
threadContext->save = 0;
}
GBAThreadLoadROM(threadContext, fname);
if(threadContext->gameDir) {
_loadGameDir(threadContext);
}
threadContext->fname = fname;
threadContext->save = VDirOptionalOpenFile(threadContext->stateDir, threadContext->fname, "sram", ".sav", O_CREAT | O_RDWR);
GBARaiseIRQ(threadContext->gba, IRQ_GAMEPAK);
GBALoadROM(threadContext->gba, threadContext->rom, threadContext->save, threadContext->fname);
}
#ifdef USE_PTHREADS
struct GBAThread* GBAThreadGetContext(void) {
pthread_once(&_contextOnce, _createTLS);

View File

@ -126,6 +126,9 @@ void GBAThreadTogglePause(struct GBAThread* threadContext);
void GBAThreadPauseFromThread(struct GBAThread* threadContext);
struct GBAThread* GBAThreadGetContext(void);
void GBAThreadLoadROM(struct GBAThread* threadContext, const char* fname);
void GBAThreadReplaceROM(struct GBAThread* threadContext, const char* fname);
#ifdef USE_PNG
void GBAThreadTakeScreenshot(struct GBAThread* threadContext);
#endif