Directory mode for loading the first ROM in a directory, still a bit buggy
Jeffrey Pfau jeffrey@endrift.com
Thu, 17 Jul 2014 00:53:17 -0700
8 files changed,
54 insertions(+),
2 deletions(-)
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -169,7 +169,11 @@ return 0;
} void GBAMapOptionsToContext(struct StartupOptions* opts, struct GBAThread* threadContext) { - threadContext->rom = VFileOpen(opts->fname, O_RDONLY); + if (opts->dirmode) { + threadContext->gamedir = VDirOpen(opts->fname); + } else { + threadContext->rom = VFileOpen(opts->fname, O_RDONLY); + } threadContext->fname = opts->fname; threadContext->bios = VFileOpen(opts->bios, O_RDONLY); threadContext->patch = VFileOpen(opts->patch, O_RDONLY);@@ -192,6 +196,26 @@ if (threadContext->rewindBufferCapacity) {
threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(void*)); } else { threadContext->rewindBuffer = 0; + } + + 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) { + 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); + } } if (threadContext->fname && !threadContext->save) {
M
src/gba/gba-thread.h
→
src/gba/gba-thread.h
@@ -47,6 +47,7 @@ // Input
struct GBAVideoRenderer* renderer; struct GBASIODriverSet sioDrivers; struct ARMDebugger* debugger; + struct VDir* gamedir; struct VFile* rom; struct VFile* save; struct VFile* bios;
M
src/gba/gba.c
→
src/gba/gba.c
@@ -12,6 +12,8 @@
const uint32_t GBA_ARM7TDMI_FREQUENCY = 0x1000000; const uint32_t GBA_COMPONENT_MAGIC = 0x1000000; +static const uint64_t GBA_ROM_MAGIC = 0x21A29A6951AEFF24; + enum { SP_BASE_SYSTEM = 0x03FFFF00, SP_BASE_IRQ = 0x03FFFFA0,@@ -582,6 +584,16 @@ _GBAVLog(gba, gbaLevel, format, args);
va_end(args); } +bool GBAIsROM(struct VFile* vf) { + if (vf->seek(vf, 4, SEEK_SET) < 0) { + return false; + } + uint64_t signature; + if (vf->read(vf, &signature, sizeof(signature)) != sizeof(signature)) { + return false; + } + return signature == GBA_ROM_MAGIC; +} void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) { struct GBA* gba = (struct GBA*) cpu->master;
M
src/gba/gba.h
→
src/gba/gba.h
@@ -146,6 +146,8 @@ 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); +bool GBAIsROM(struct VFile* vf); + __attribute__((format (printf, 3, 4))) void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...);
M
src/platform/commandline.c
→
src/platform/commandline.c
@@ -23,6 +23,7 @@ " -f Start full-screen"
static const struct option _options[] = { { "bios", required_argument, 0, 'b' }, + { "dirmode", required_argument, 0, 'D' }, { "frameskip", required_argument, 0, 's' }, #ifdef USE_CLI_DEBUGGER { "debug", no_argument, 0, 'd' },@@ -41,7 +42,7 @@ memset(opts, 0, sizeof(*opts));
int ch; char options[64] = - "b:l:p:s:" + "b:Dl:p:s:" #ifdef USE_CLI_DEBUGGER "d" #endif@@ -57,6 +58,9 @@ while ((ch = getopt_long(argc, argv, options, _options, 0)) != -1) {
switch (ch) { case 'b': opts->bios = strdup(optarg); + break; + case 'D': + opts->dirmode = true; break; #ifdef USE_CLI_DEBUGGER case 'd':
M
src/platform/commandline.h
→
src/platform/commandline.h
@@ -18,6 +18,7 @@ struct StartupOptions {
char* fname; char* bios; char* patch; + bool dirmode; int logLevel; int frameskip; int rewindBufferCapacity;
M
src/util/vfs.c
→
src/util/vfs.c
@@ -30,6 +30,7 @@ static void _vfdUnmap(struct VFile* vf, void* memory, size_t size);
static void _vfdTruncate(struct VFile* vf, size_t size); static bool _vdClose(struct VDir* vd); +static void _vdRewind(struct VDir* vd); static struct VDirEntry* _vdListNext(struct VDir* vd); static struct VFile* _vdOpenFile(struct VDir* vd, const char* path, int mode);@@ -171,6 +172,7 @@ return 0;
} vd->d.close = _vdClose; + vd->d.rewind = _vdRewind; vd->d.listNext = _vdListNext; vd->d.openFile = _vdOpenFile; vd->path = strdup(path);@@ -189,6 +191,11 @@ }
free(vdde->path); free(vdde); return true; +} + +void _vdRewind(struct VDir* vd) { + struct VDirDE* vdde = (struct VDirDE*) vd; + rewinddir(vdde->de); } struct VDirEntry* _vdListNext(struct VDir* vd) {
M
src/util/vfs.h
→
src/util/vfs.h
@@ -22,6 +22,7 @@ };
struct VDir { bool (*close)(struct VDir* vd); + void (*rewind)(struct VDir* vd); struct VDirEntry* (*listNext)(struct VDir* vd); struct VFile* (*openFile)(struct VDir* vd, const char* name, int mode); };