mirror of https://github.com/mgba-emu/mgba.git
Directory mode for loading the first ROM in a directory, still a bit buggy
This commit is contained in:
parent
73425e80b5
commit
ee5c918ff2
|
@ -169,7 +169,11 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
|
|||
}
|
||||
|
||||
void GBAMapOptionsToContext(struct StartupOptions* opts, struct GBAThread* threadContext) {
|
||||
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);
|
||||
|
@ -194,6 +198,26 @@ bool GBAThreadStart(struct GBAThread* threadContext) {
|
|||
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) {
|
||||
char* savedata = 0;
|
||||
char* dotPoint = strrchr(threadContext->fname, '.');
|
||||
|
|
|
@ -47,6 +47,7 @@ struct GBAThread {
|
|||
struct GBAVideoRenderer* renderer;
|
||||
struct GBASIODriverSet sioDrivers;
|
||||
struct ARMDebugger* debugger;
|
||||
struct VDir* gamedir;
|
||||
struct VFile* rom;
|
||||
struct VFile* save;
|
||||
struct VFile* bios;
|
||||
|
|
|
@ -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 @@ void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel leve
|
|||
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;
|
||||
|
|
|
@ -146,6 +146,8 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char
|
|||
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, ...);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
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 @@ bool parseCommandArgs(struct StartupOptions* opts, int argc, char* const* argv,
|
|||
|
||||
int ch;
|
||||
char options[64] =
|
||||
"b:l:p:s:"
|
||||
"b:Dl:p:s:"
|
||||
#ifdef USE_CLI_DEBUGGER
|
||||
"d"
|
||||
#endif
|
||||
|
@ -58,6 +59,9 @@ bool parseCommandArgs(struct StartupOptions* opts, int argc, char* const* argv,
|
|||
case 'b':
|
||||
opts->bios = strdup(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
opts->dirmode = true;
|
||||
break;
|
||||
#ifdef USE_CLI_DEBUGGER
|
||||
case 'd':
|
||||
if (opts->debuggerType != DEBUGGER_NONE) {
|
||||
|
|
|
@ -18,6 +18,7 @@ struct StartupOptions {
|
|||
char* fname;
|
||||
char* bios;
|
||||
char* patch;
|
||||
bool dirmode;
|
||||
int logLevel;
|
||||
int frameskip;
|
||||
int rewindBufferCapacity;
|
||||
|
|
|
@ -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 @@ struct VDir* VDirOpen(const char* path) {
|
|||
}
|
||||
|
||||
vd->d.close = _vdClose;
|
||||
vd->d.rewind = _vdRewind;
|
||||
vd->d.listNext = _vdListNext;
|
||||
vd->d.openFile = _vdOpenFile;
|
||||
vd->path = strdup(path);
|
||||
|
@ -191,6 +193,11 @@ bool _vdClose(struct VDir* vd) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void _vdRewind(struct VDir* vd) {
|
||||
struct VDirDE* vdde = (struct VDirDE*) vd;
|
||||
rewinddir(vdde->de);
|
||||
}
|
||||
|
||||
struct VDirEntry* _vdListNext(struct VDir* vd) {
|
||||
struct VDirDE* vdde = (struct VDirDE*) vd;
|
||||
vdde->vde.ent = readdir(vdde->de);
|
||||
|
|
|
@ -22,6 +22,7 @@ struct VDirEntry {
|
|||
|
||||
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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue