all repos — mgba @ ee5c918ff24e6f5f23864518d9bdd64309115919

mGBA Game Boy Advance Emulator

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
commit

ee5c918ff24e6f5f23864518d9bdd64309115919

parent

73425e80b51ffbb7f0553a7fa59455ad38890c7d

M src/gba/gba-thread.csrc/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.hsrc/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.csrc/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.hsrc/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.csrc/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.hsrc/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.csrc/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.hsrc/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); };