mirror of https://github.com/mgba-emu/mgba.git
Core: Clean up ROM loading
This commit is contained in:
parent
44116c9beb
commit
38f89a1bd8
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include "util/common.h"
|
#include "util/common.h"
|
||||||
|
|
||||||
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
|
#include "core/directories.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct VFile;
|
struct VFile;
|
||||||
struct mRTCSource;
|
struct mRTCSource;
|
||||||
|
|
||||||
|
@ -24,6 +28,10 @@ struct mCore {
|
||||||
void* cpu;
|
void* cpu;
|
||||||
void* board;
|
void* board;
|
||||||
|
|
||||||
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
|
struct mDirectorySet dirs;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool (*init)(struct mCore*);
|
bool (*init)(struct mCore*);
|
||||||
void (*deinit)(struct mCore*);
|
void (*deinit)(struct mCore*);
|
||||||
|
|
||||||
|
@ -32,8 +40,9 @@ struct mCore {
|
||||||
void (*desiredVideoDimensions)(struct mCore*, unsigned* width, unsigned* height);
|
void (*desiredVideoDimensions)(struct mCore*, unsigned* width, unsigned* height);
|
||||||
void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride);
|
void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride);
|
||||||
|
|
||||||
bool (*isROM)(struct mCore*, struct VFile* vf);
|
bool (*isROM)(struct VFile* vf);
|
||||||
bool (*loadROM)(struct mCore*, struct VFile* vf, struct VFile* save, const char* fname);
|
bool (*loadROM)(struct mCore*, struct VFile* vf);
|
||||||
|
bool (*loadSave)(struct mCore*, struct VFile* vf);
|
||||||
void (*unloadROM)(struct mCore*);
|
void (*unloadROM)(struct mCore*);
|
||||||
|
|
||||||
bool (*loadBIOS)(struct mCore*, struct VFile* vf, int biosID);
|
bool (*loadBIOS)(struct mCore*, struct VFile* vf, int biosID);
|
||||||
|
@ -55,4 +64,7 @@ struct mCore {
|
||||||
void (*setRTC)(struct mCore*, struct mRTCSource*);
|
void (*setRTC)(struct mCore*, struct mRTCSource*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool mCoreLoadFile(struct mCore* core, const char* path);
|
||||||
|
bool mCoreAutoloadSave(struct mCore* core);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,9 +99,20 @@ struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path
|
||||||
file = 0;
|
file = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (file) {
|
||||||
|
char dirname[PATH_MAX];
|
||||||
|
separatePath(path, dirname, dirs->baseName, 0);
|
||||||
|
mDirectorySetAttachBase(dirs, VDirOpen(dirname));
|
||||||
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* suffix, int mode) {
|
||||||
|
char name[PATH_MAX];
|
||||||
|
snprintf(name, sizeof(name), "%s%s", dirs->baseName, suffix);
|
||||||
|
return dirs->base->openFile(dirs->base, name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts) {
|
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts) {
|
||||||
if (opts->savegamePath) {
|
if (opts->savegamePath) {
|
||||||
struct VDir* dir = VDirOpen(opts->savegamePath);
|
struct VDir* dir = VDirOpen(opts->savegamePath);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
struct VDir;
|
struct VDir;
|
||||||
|
|
||||||
struct mDirectorySet {
|
struct mDirectorySet {
|
||||||
|
char baseName[PATH_MAX];
|
||||||
struct VDir* base;
|
struct VDir* base;
|
||||||
struct VDir* archive;
|
struct VDir* archive;
|
||||||
struct VDir* save;
|
struct VDir* save;
|
||||||
|
@ -27,6 +28,7 @@ void mDirectorySetAttachBase(struct mDirectorySet* dirs, struct VDir* base);
|
||||||
void mDirectorySetDetachBase(struct mDirectorySet* dirs);
|
void mDirectorySetDetachBase(struct mDirectorySet* dirs);
|
||||||
|
|
||||||
struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*));
|
struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*));
|
||||||
|
struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* suffix, int mode);
|
||||||
|
|
||||||
struct GBAOptions;
|
struct GBAOptions;
|
||||||
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts);
|
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts);
|
||||||
|
|
|
@ -38,6 +38,10 @@ static bool _GBCoreInit(struct mCore* core) {
|
||||||
|
|
||||||
gb->keySource = &gbcore->keys;
|
gb->keySource = &gbcore->keys;
|
||||||
|
|
||||||
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
|
mDirectorySetInit(&core->dirs);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +50,9 @@ static void _GBCoreDeinit(struct mCore* core) {
|
||||||
GBDestroy(core->board);
|
GBDestroy(core->board);
|
||||||
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
|
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
|
||||||
mappedMemoryFree(core->board, sizeof(struct GB));
|
mappedMemoryFree(core->board, sizeof(struct GB));
|
||||||
|
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||||
|
mDirectorySetDeinit(&core->dirs);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _GBCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
|
static void _GBCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
|
||||||
|
@ -65,13 +72,12 @@ static void _GBCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t st
|
||||||
gbcore->renderer.outputBufferStride = stride;
|
gbcore->renderer.outputBufferStride = stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _GBCoreLoadROM(struct mCore* core, struct VFile* vf, struct VFile* save, const char* fname) {
|
static bool _GBCoreLoadROM(struct mCore* core, struct VFile* vf) {
|
||||||
return GBLoadROM(core->board, vf, save, fname);
|
return GBLoadROM(core->board, vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _GBCoreIsROM(struct mCore* core, struct VFile* vf) {
|
static bool _GBCoreLoadSave(struct mCore* core, struct VFile* vf) {
|
||||||
UNUSED(core);
|
return GBLoadSave(core->board, vf);
|
||||||
return GBIsROM(vf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _GBCoreUnloadROM(struct mCore* core) {
|
static void _GBCoreUnloadROM(struct mCore* core) {
|
||||||
|
@ -144,8 +150,9 @@ struct mCore* GBCoreCreate(void) {
|
||||||
core->setSync = _GBCoreSetSync;
|
core->setSync = _GBCoreSetSync;
|
||||||
core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions;
|
core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions;
|
||||||
core->setVideoBuffer = _GBCoreSetVideoBuffer;
|
core->setVideoBuffer = _GBCoreSetVideoBuffer;
|
||||||
core->isROM = _GBCoreIsROM;
|
core->isROM = GBIsROM;
|
||||||
core->loadROM = _GBCoreLoadROM;
|
core->loadROM = _GBCoreLoadROM;
|
||||||
|
core->loadSave = _GBCoreLoadSave;
|
||||||
core->unloadROM = _GBCoreUnloadROM;
|
core->unloadROM = _GBCoreUnloadROM;
|
||||||
core->reset = _GBCoreReset;
|
core->reset = _GBCoreReset;
|
||||||
core->runFrame = _GBCoreRunFrame;
|
core->runFrame = _GBCoreRunFrame;
|
||||||
|
|
22
src/gb/gb.c
22
src/gb/gb.c
|
@ -60,7 +60,7 @@ static void GBInit(struct LR35902Core* cpu, struct LR35902Component* component)
|
||||||
gb->diPending = false;
|
gb->diPending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GBLoadROM(struct GB* gb, struct VFile* vf, struct VFile* sav, const char* fname) {
|
bool GBLoadROM(struct GB* gb, struct VFile* vf) {
|
||||||
GBUnloadROM(gb);
|
GBUnloadROM(gb);
|
||||||
gb->romVf = vf;
|
gb->romVf = vf;
|
||||||
gb->pristineRomSize = vf->size(vf);
|
gb->pristineRomSize = vf->size(vf);
|
||||||
|
@ -79,21 +79,25 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf, struct VFile* sav, const char* f
|
||||||
}
|
}
|
||||||
gb->yankedRomSize = 0;
|
gb->yankedRomSize = 0;
|
||||||
gb->memory.rom = gb->pristineRom;
|
gb->memory.rom = gb->pristineRom;
|
||||||
gb->activeFile = fname;
|
|
||||||
gb->memory.romSize = gb->pristineRomSize;
|
gb->memory.romSize = gb->pristineRomSize;
|
||||||
gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
|
gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
|
||||||
gb->sramVf = sav;
|
|
||||||
if (sav) {
|
// TODO: error check
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GBLoadSave(struct GB* gb, struct VFile* vf) {
|
||||||
|
gb->sramVf = vf;
|
||||||
|
if (vf) {
|
||||||
// TODO: Do this in bank-switching code
|
// TODO: Do this in bank-switching code
|
||||||
if (sav->size(sav) < 0x20000) {
|
if (vf->size(vf) < 0x20000) {
|
||||||
sav->truncate(sav, 0x20000);
|
vf->truncate(vf, 0x20000);
|
||||||
}
|
}
|
||||||
gb->memory.sram = sav->map(sav, 0x20000, MAP_WRITE);
|
gb->memory.sram = vf->map(vf, 0x20000, MAP_WRITE);
|
||||||
} else {
|
} else {
|
||||||
gb->memory.sram = anonymousMemoryMap(0x20000);
|
gb->memory.sram = anonymousMemoryMap(0x20000);
|
||||||
}
|
}
|
||||||
return true;
|
return gb->memory.sram;
|
||||||
// TODO: error check
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBUnloadROM(struct GB* gb) {
|
void GBUnloadROM(struct GB* gb) {
|
||||||
|
|
|
@ -61,8 +61,6 @@ struct GB {
|
||||||
struct VFile* romVf;
|
struct VFile* romVf;
|
||||||
struct VFile* sramVf;
|
struct VFile* sramVf;
|
||||||
|
|
||||||
const char* activeFile;
|
|
||||||
|
|
||||||
bool diPending;
|
bool diPending;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,7 +98,8 @@ void GBHalt(struct LR35902Core* cpu);
|
||||||
void GBStop(struct LR35902Core* cpu);
|
void GBStop(struct LR35902Core* cpu);
|
||||||
|
|
||||||
struct VFile;
|
struct VFile;
|
||||||
bool GBLoadROM(struct GB* gb, struct VFile* vf, struct VFile* sav, const char* fname);
|
bool GBLoadROM(struct GB* gb, struct VFile* vf);
|
||||||
|
bool GBLoadSave(struct GB* gb, struct VFile* vf);
|
||||||
void GBYankROM(struct GB* gb);
|
void GBYankROM(struct GB* gb);
|
||||||
void GBUnloadROM(struct GB* gb);
|
void GBUnloadROM(struct GB* gb);
|
||||||
|
|
||||||
|
|
|
@ -284,8 +284,10 @@ int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args) {
|
||||||
.audioWait = true
|
.audioWait = true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct VFile* vf = VFileOpen(args->fname, O_RDONLY);
|
if (!mCoreLoadFile(renderer->core, args->fname)) {
|
||||||
struct VFile* savVf = 0;
|
return 1;
|
||||||
|
}
|
||||||
|
mCoreAutoloadSave(renderer->core);
|
||||||
|
|
||||||
renderer->audio.samples = 1024;
|
renderer->audio.samples = 1024;
|
||||||
renderer->audio.sampleRate = 44100;
|
renderer->audio.sampleRate = 44100;
|
||||||
|
@ -293,22 +295,11 @@ int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args) {
|
||||||
GBSDLInitAudio(&renderer->audio, 0);
|
GBSDLInitAudio(&renderer->audio, 0);
|
||||||
renderer->audio.sync = &thread.sync;
|
renderer->audio.sync = &thread.sync;
|
||||||
|
|
||||||
{
|
|
||||||
char savepath[PATH_MAX];
|
|
||||||
char dirname[PATH_MAX];
|
|
||||||
char basename[PATH_MAX];
|
|
||||||
separatePath(args->fname, dirname, basename, 0);
|
|
||||||
snprintf(savepath, sizeof(savepath), "%s" PATH_SEP "%s.sav", dirname, basename);
|
|
||||||
savVf = VFileOpen(savepath, O_RDWR | O_CREAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer->core->loadROM(renderer->core, vf, savVf, args->fname);
|
|
||||||
mCoreThreadStart(&thread);
|
mCoreThreadStart(&thread);
|
||||||
renderer->audio.psg = 0;
|
renderer->audio.psg = 0;
|
||||||
GBSDLResumeAudio(&renderer->audio);
|
GBSDLResumeAudio(&renderer->audio);
|
||||||
renderer->runloop(renderer, &thread);
|
renderer->runloop(renderer, &thread);
|
||||||
renderer->core->unloadROM(renderer->core);
|
renderer->core->unloadROM(renderer->core);
|
||||||
vf->close(vf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue