mirror of https://github.com/mgba-emu/mgba.git
GBA: Rom unloading and replacing
This commit is contained in:
parent
289e9b0cf1
commit
635fae7d05
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue