Core: Refactor config loading in mCore

This commit is contained in:
Jeffrey Pfau 2016-02-04 21:58:45 -08:00
parent 7bc15e50c5
commit 407335e2f4
27 changed files with 302 additions and 189 deletions

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "config.h" #include "config.h"
#include "gba/gba.h"
#include "util/formatting.h" #include "util/formatting.h"
#include "util/string.h" #include "util/string.h"
#include "util/vfs.h" #include "util/vfs.h"
@ -299,7 +300,7 @@ void mCoreConfigSetOverrideFloatValue(struct mCoreConfig* config, const char* ke
ConfigurationSetFloatValue(&config->overridesTable, config->port, key, value); ConfigurationSetFloatValue(&config->overridesTable, config->port, key, value);
} }
void mCoreConfigMap(const struct mCoreConfig* config, struct GBAOptions* opts) { void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts) {
_lookupCharValue(config, "bios", &opts->bios); _lookupCharValue(config, "bios", &opts->bios);
_lookupCharValue(config, "shader", &opts->shader); _lookupCharValue(config, "shader", &opts->shader);
_lookupIntValue(config, "logLevel", &opts->logLevel); _lookupIntValue(config, "logLevel", &opts->logLevel);
@ -351,21 +352,9 @@ void mCoreConfigMap(const struct mCoreConfig* config, struct GBAOptions* opts) {
_lookupCharValue(config, "savestatePath", &opts->savestatePath); _lookupCharValue(config, "savestatePath", &opts->savestatePath);
_lookupCharValue(config, "screenshotPath", &opts->screenshotPath); _lookupCharValue(config, "screenshotPath", &opts->screenshotPath);
_lookupCharValue(config, "patchPath", &opts->patchPath); _lookupCharValue(config, "patchPath", &opts->patchPath);
char* idleOptimization = 0;
if (_lookupCharValue(config, "idleOptimization", &idleOptimization)) {
if (strcasecmp(idleOptimization, "ignore") == 0) {
opts->idleOptimization = IDLE_LOOP_IGNORE;
} else if (strcasecmp(idleOptimization, "remove") == 0) {
opts->idleOptimization = IDLE_LOOP_REMOVE;
} else if (strcasecmp(idleOptimization, "detect") == 0) {
opts->idleOptimization = IDLE_LOOP_DETECT;
}
free(idleOptimization);
}
} }
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct GBAOptions* opts) { void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts) {
ConfigurationSetValue(&config->defaultsTable, 0, "bios", opts->bios); ConfigurationSetValue(&config->defaultsTable, 0, "bios", opts->bios);
ConfigurationSetValue(&config->defaultsTable, 0, "shader", opts->shader); ConfigurationSetValue(&config->defaultsTable, 0, "shader", opts->shader);
ConfigurationSetIntValue(&config->defaultsTable, 0, "skipBios", opts->skipBios); ConfigurationSetIntValue(&config->defaultsTable, 0, "skipBios", opts->skipBios);
@ -388,18 +377,6 @@ void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct GBAOptions
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio); ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio);
ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo); ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo);
ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver); ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver);
switch (opts->idleOptimization) {
case IDLE_LOOP_IGNORE:
ConfigurationSetValue(&config->defaultsTable, 0, "idleOptimization", "ignore");
break;
case IDLE_LOOP_REMOVE:
ConfigurationSetValue(&config->defaultsTable, 0, "idleOptimization", "remove");
break;
case IDLE_LOOP_DETECT:
ConfigurationSetValue(&config->defaultsTable, 0, "idleOptimization", "detect");
break;
}
} }
// These two are basically placeholders in case the internal layout changes, e.g. for loading separate files // These two are basically placeholders in case the internal layout changes, e.g. for loading separate files
@ -411,7 +388,7 @@ struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig* config) {
return &config->configTable; return &config->configTable;
} }
void mCoreConfigFreeOpts(struct GBAOptions* opts) { void mCoreConfigFreeOpts(struct mCoreOptions* opts) {
free(opts->bios); free(opts->bios);
free(opts->shader); free(opts->shader);
free(opts->savegamePath); free(opts->savegamePath);

View File

@ -8,8 +8,6 @@
#include "util/common.h" #include "util/common.h"
#include "gba/gba.h"
#include "util/configuration.h" #include "util/configuration.h"
struct mCoreConfig { struct mCoreConfig {
@ -19,7 +17,7 @@ struct mCoreConfig {
char* port; char* port;
}; };
struct GBAOptions { struct mCoreOptions {
char* bios; char* bios;
bool skipBios; bool skipBios;
bool useBios; bool useBios;
@ -50,8 +48,6 @@ struct GBAOptions {
bool videoSync; bool videoSync;
bool audioSync; bool audioSync;
enum GBAIdleLoopOptimization idleOptimization;
}; };
void mCoreConfigInit(struct mCoreConfig*, const char* port); void mCoreConfigInit(struct mCoreConfig*, const char* port);
@ -87,12 +83,12 @@ void mCoreConfigSetOverrideIntValue(struct mCoreConfig*, const char* key, int va
void mCoreConfigSetOverrideUIntValue(struct mCoreConfig*, const char* key, unsigned value); void mCoreConfigSetOverrideUIntValue(struct mCoreConfig*, const char* key, unsigned value);
void mCoreConfigSetOverrideFloatValue(struct mCoreConfig*, const char* key, float value); void mCoreConfigSetOverrideFloatValue(struct mCoreConfig*, const char* key, float value);
void mCoreConfigMap(const struct mCoreConfig* config, struct GBAOptions* opts); void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts);
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct GBAOptions* opts); void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts);
struct Configuration* mCoreConfigGetInput(struct mCoreConfig*); struct Configuration* mCoreConfigGetInput(struct mCoreConfig*);
struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig*); struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig*);
void mCoreConfigFreeOpts(struct GBAOptions* opts); void mCoreConfigFreeOpts(struct mCoreOptions* opts);
#endif #endif

93
src/core/core.c Normal file
View File

@ -0,0 +1,93 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "core.h"
#include "core/log.h"
#include "util/vfs.h"
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreLoadFile(struct mCore* core, const char* path) {
struct VFile* rom = mDirectorySetOpenPath(&core->dirs, path, core->isROM);
if (!rom) {
return false;
}
bool ret = core->loadROM(core, rom);
if (!ret) {
rom->close(rom);
}
return ret;
}
bool mCoreAutoloadSave(struct mCore* core) {
return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, ".sav", O_CREAT | O_RDWR));
}
bool mCoreAutoloadPatch(struct mCore* core) {
return core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".ups", O_RDONLY)) ||
core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".ips", O_RDONLY)) ||
core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".bps", O_RDONLY));
}
bool mCoreSaveState(struct mCore* core, int slot, int flags) {
struct VFile* vf = mCoreGetState(core, slot, true);
if (!vf) {
return false;
}
bool success = core->saveState(core, vf, flags);
vf->close(vf);
if (success) {
mLOG(STATUS, INFO, "State %i saved", slot);
} else {
mLOG(STATUS, INFO, "State %i failed to save", slot);
}
return success;
}
bool mCoreLoadState(struct mCore* core, int slot, int flags) {
struct VFile* vf = mCoreGetState(core, slot, false);
if (!vf) {
return false;
}
bool success = core->loadState(core, vf, flags);
vf->close(vf);
if (success) {
mLOG(STATUS, INFO, "State %i loaded", slot);
} else {
mLOG(STATUS, INFO, "State %i failed to loaded", slot);
}
return success;
}
struct VFile* mCoreGetState(struct mCore* core, int slot, bool write) {
char name[PATH_MAX];
snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot);
return core->dirs.state->openFile(core->dirs.state, name, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY);
}
void mCoreDeleteState(struct mCore* core, int slot) {
char name[PATH_MAX];
snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot);
core->dirs.state->deleteFile(core->dirs.state, name);
}
#endif
void mCoreInitConfig(struct mCore* core, const char* port) {
mCoreConfigInit(&core->config, port);
}
void mCoreLoadConfig(struct mCore* core) {
#ifndef MINIMAL_CORE
mCoreConfigLoad(&core->config);
#endif
mCoreConfigMap(&core->config, &core->opts);
#ifndef MINIMAL_CORE
mDirectorySetMapOptions(&core->dirs, &core->opts);
#endif
core->loadConfig(core);
}

View File

@ -11,9 +11,14 @@
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
#include "core/directories.h" #include "core/directories.h"
#endif #endif
#ifndef MINIMAL_CORE
#include "core/input.h"
#endif
#include "core/config.h"
struct VFile; struct VFile;
struct mRTCSource; struct mRTCSource;
struct mCoreConfig;
#ifdef COLOR_16_BIT #ifdef COLOR_16_BIT
typedef uint16_t color_t; typedef uint16_t color_t;
@ -32,11 +37,17 @@ struct mCore {
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct mDirectorySet dirs; struct mDirectorySet dirs;
#endif #endif
#ifndef MINIMAL_CORE
struct mInputMap inputMap;
#endif
struct mCoreConfig config;
struct mCoreOptions opts;
bool (*init)(struct mCore*); bool (*init)(struct mCore*);
void (*deinit)(struct mCore*); void (*deinit)(struct mCore*);
void (*setSync)(struct mCore*, struct mCoreSync*); void (*setSync)(struct mCore*, struct mCoreSync*);
void (*loadConfig)(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);
@ -72,9 +83,9 @@ struct mCore {
void (*setRTC)(struct mCore*, struct mRTCSource*); void (*setRTC)(struct mCore*, struct mRTCSource*);
}; };
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreLoadFile(struct mCore* core, const char* path); bool mCoreLoadFile(struct mCore* core, const char* path);
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreAutoloadSave(struct mCore* core); bool mCoreAutoloadSave(struct mCore* core);
bool mCoreAutoloadPatch(struct mCore* core); bool mCoreAutoloadPatch(struct mCore* core);
@ -84,4 +95,7 @@ struct VFile* mCoreGetState(struct mCore* core, int slot, bool write);
void mCoreDeleteState(struct mCore* core, int slot); void mCoreDeleteState(struct mCore* core, int slot);
#endif #endif
void mCoreInitConfig(struct mCore* core, const char* port);
void mCoreLoadConfig(struct mCore* core);
#endif #endif

View File

@ -113,7 +113,7 @@ struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* su
return dirs->base->openFile(dirs->base, name, mode); return dirs->base->openFile(dirs->base, name, mode);
} }
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts) { void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts) {
if (opts->savegamePath) { if (opts->savegamePath) {
struct VDir* dir = VDirOpen(opts->savegamePath); struct VDir* dir = VDirOpen(opts->savegamePath);
if (dir) { if (dir) {

View File

@ -30,8 +30,8 @@ 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 VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* suffix, int mode);
struct GBAOptions; struct mCoreOptions;
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts); void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts);
#endif #endif
#endif #endif

View File

@ -60,6 +60,11 @@ static void _GBCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
gb->sync = sync; gb->sync = sync;
} }
static void _GBCoreLoadConfig(struct mCore* core) {
UNUSED(core);
// TODO
}
static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
UNUSED(core); UNUSED(core);
*width = GB_VIDEO_HORIZONTAL_PIXELS; *width = GB_VIDEO_HORIZONTAL_PIXELS;
@ -184,6 +189,7 @@ struct mCore* GBCoreCreate(void) {
core->init = _GBCoreInit; core->init = _GBCoreInit;
core->deinit = _GBCoreDeinit; core->deinit = _GBCoreDeinit;
core->setSync = _GBCoreSetSync; core->setSync = _GBCoreSetSync;
core->loadConfig = _GBCoreLoadConfig;
core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions; core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions;
core->setVideoBuffer = _GBCoreSetVideoBuffer; core->setVideoBuffer = _GBCoreSetVideoBuffer;
core->getAudioChannel = _GBCoreGetAudioChannel; core->getAudioChannel = _GBCoreGetAudioChannel;

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gba/context/context.h" #include "gba/context/context.h"
#include "gba/video.h"
#include "gba/context/overrides.h" #include "gba/context/overrides.h"
#include "util/memory.h" #include "util/memory.h"
@ -54,10 +55,9 @@ bool GBAContextInit(struct GBAContext* context, const char* port) {
mCoreConfigDirectory(biosPath, PATH_MAX); mCoreConfigDirectory(biosPath, PATH_MAX);
strncat(biosPath, PATH_SEP "gba_bios.bin", PATH_MAX - strlen(biosPath)); strncat(biosPath, PATH_SEP "gba_bios.bin", PATH_MAX - strlen(biosPath));
struct GBAOptions opts = { struct mCoreOptions opts = {
.bios = biosPath, .bios = biosPath,
.useBios = true, .useBios = true,
.idleOptimization = IDLE_LOOP_DETECT,
.logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS .logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS
}; };
mCoreConfigLoad(&context->config); mCoreConfigLoad(&context->config);
@ -161,7 +161,7 @@ bool GBAContextLoadBIOSFromVFile(struct GBAContext* context, struct VFile* bios)
} }
bool GBAContextStart(struct GBAContext* context) { bool GBAContextStart(struct GBAContext* context) {
struct GBAOptions opts = { .bios = 0 }; struct mCoreOptions opts = { .bios = 0 };
if (context->renderer) { if (context->renderer) {
GBAVideoAssociateRenderer(&context->gba->video, context->renderer); GBAVideoAssociateRenderer(&context->gba->video, context->renderer);
@ -180,7 +180,6 @@ bool GBAContextStart(struct GBAContext* context) {
GBALoadBIOS(context->gba, context->bios); GBALoadBIOS(context->gba, context->bios);
} }
context->gba->logLevel = opts.logLevel; context->gba->logLevel = opts.logLevel;
context->gba->idleOptimization = opts.idleOptimization;
GBAContextReset(context); GBAContextReset(context);

View File

@ -11,6 +11,7 @@
#include "core/directories.h" #include "core/directories.h"
#include "core/config.h" #include "core/config.h"
#include "core/sync.h" #include "core/sync.h"
#include "gba/gba.h"
#include "gba/input.h" #include "gba/input.h"
struct GBAContext { struct GBAContext {
@ -26,7 +27,7 @@ struct GBAContext {
#endif #endif
struct ARMComponent* components[GBA_COMPONENT_MAX]; struct ARMComponent* components[GBA_COMPONENT_MAX];
struct mCoreConfig config; struct mCoreConfig config;
struct GBAOptions opts; struct mCoreOptions opts;
struct mInputMap inputMap; struct mInputMap inputMap;
}; };

View File

@ -11,6 +11,7 @@
#include "gba/renderers/video-software.h" #include "gba/renderers/video-software.h"
#include "gba/serialize.h" #include "gba/serialize.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/vfs.h"
struct GBACore { struct GBACore {
struct mCore d; struct mCore d;
@ -31,6 +32,8 @@ static bool _GBACoreInit(struct mCore* core) {
core->cpu = cpu; core->cpu = cpu;
core->board = gba; core->board = gba;
memset(&core->opts, 0, sizeof(core->opts));
GBACreate(gba); GBACreate(gba);
// TODO: Restore debugger and cheats // TODO: Restore debugger and cheats
ARMSetComponents(cpu, &gba->d, 0, 0); ARMSetComponents(cpu, &gba->d, 0, 0);
@ -63,6 +66,29 @@ static void _GBACoreSetSync(struct mCore* core, struct mCoreSync* sync) {
gba->sync = sync; gba->sync = sync;
} }
static void _GBACoreLoadConfig(struct mCore* core) {
struct GBA* gba = core->board;
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct VFile* bios = 0;
if (core->opts.useBios) {
bios = VFileOpen(core->opts.bios, O_RDONLY);
}
GBALoadBIOS(gba, bios);
#endif
const char* idleOptimization = mCoreConfigGetValue(&core->config, "idleOptimization");
if (idleOptimization) {
if (strcasecmp(idleOptimization, "ignore") == 0) {
gba->idleOptimization = IDLE_LOOP_IGNORE;
} else if (strcasecmp(idleOptimization, "remove") == 0) {
gba->idleOptimization = IDLE_LOOP_REMOVE;
} else if (strcasecmp(idleOptimization, "detect") == 0) {
gba->idleOptimization = IDLE_LOOP_DETECT;
}
}
}
static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
UNUSED(core); UNUSED(core);
*width = VIDEO_HORIZONTAL_PIXELS; *width = VIDEO_HORIZONTAL_PIXELS;
@ -109,6 +135,9 @@ static void _GBACoreUnloadROM(struct mCore* core) {
static void _GBACoreReset(struct mCore* core) { static void _GBACoreReset(struct mCore* core) {
ARMReset(core->cpu); ARMReset(core->cpu);
if (core->opts.skipBios) {
GBASkipBIOS(core->board);
}
} }
static void _GBACoreRunFrame(struct mCore* core) { static void _GBACoreRunFrame(struct mCore* core) {
@ -178,6 +207,7 @@ struct mCore* GBACoreCreate(void) {
core->init = _GBACoreInit; core->init = _GBACoreInit;
core->deinit = _GBACoreDeinit; core->deinit = _GBACoreDeinit;
core->setSync = _GBACoreSetSync; core->setSync = _GBACoreSetSync;
core->loadConfig = _GBACoreLoadConfig;
core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions; core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions;
core->setVideoBuffer = _GBACoreSetVideoBuffer; core->setVideoBuffer = _GBACoreSetVideoBuffer;
core->getAudioChannel = _GBACoreGetAudioChannel; core->getAudioChannel = _GBACoreGetAudioChannel;

View File

@ -372,7 +372,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
return 0; return 0;
} }
void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* threadContext) { void GBAMapOptionsToContext(const struct mCoreOptions* opts, struct GBAThread* threadContext) {
if (opts->useBios) { if (opts->useBios) {
threadContext->bios = VFileOpen(opts->bios, O_RDONLY); threadContext->bios = VFileOpen(opts->bios, O_RDONLY);
} else { } else {
@ -400,12 +400,10 @@ void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* thr
threadContext->audioBuffers = opts->audioBuffers; threadContext->audioBuffers = opts->audioBuffers;
} }
threadContext->idleOptimization = opts->idleOptimization;
mDirectorySetMapOptions(&threadContext->dirs, opts); mDirectorySetMapOptions(&threadContext->dirs, opts);
} }
void GBAMapArgumentsToContext(const struct GBAArguments* args, struct GBAThread* threadContext) { void GBAMapArgumentsToContext(const struct mArguments* args, struct GBAThread* threadContext) {
GBAThreadLoadROM(threadContext, args->fname); GBAThreadLoadROM(threadContext, args->fname);
threadContext->fname = args->fname; threadContext->fname = args->fname;
threadContext->patch = VFileOpen(args->patch, O_RDONLY); threadContext->patch = VFileOpen(args->patch, O_RDONLY);

View File

@ -18,9 +18,9 @@
#include "util/threading.h" #include "util/threading.h"
struct GBAThread; struct GBAThread;
struct GBAArguments; struct mArguments;
struct GBACheatSet; struct GBACheatSet;
struct GBAOptions; struct mCoreOptions;
typedef void (*GBAThreadCallback)(struct GBAThread* threadContext); typedef void (*GBAThreadCallback)(struct GBAThread* threadContext);
typedef bool (*ThreadStopCallback)(struct GBAThread* threadContext); typedef bool (*ThreadStopCallback)(struct GBAThread* threadContext);
@ -93,8 +93,8 @@ struct GBAThread {
struct GBACheatDevice* cheats; struct GBACheatDevice* cheats;
}; };
void GBAMapOptionsToContext(const struct GBAOptions*, struct GBAThread*); void GBAMapOptionsToContext(const struct mCoreOptions*, struct GBAThread*);
void GBAMapArgumentsToContext(const struct GBAArguments*, struct GBAThread*); void GBAMapArgumentsToContext(const struct mArguments*, struct GBAThread*);
bool GBAThreadStart(struct GBAThread* threadContext); bool GBAThreadStart(struct GBAThread* threadContext);
bool GBAThreadHasStarted(struct GBAThread* threadContext); bool GBAThreadHasStarted(struct GBAThread* threadContext);

View File

@ -50,9 +50,10 @@ static const struct option _options[] = {
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
static bool _parseGraphicsArg(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg); static bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg);
static void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config);
bool parseArguments(struct GBAArguments* opts, struct mCoreConfig* config, int argc, char* const* argv, struct SubParser* subparser) { bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparser) {
int ch; int ch;
char options[64] = char options[64] =
"b:c:hl:p:s:v:" "b:c:hl:p:s:v:"
@ -63,7 +64,7 @@ bool parseArguments(struct GBAArguments* opts, struct mCoreConfig* config, int a
"g" "g"
#endif #endif
; ;
memset(opts, 0, sizeof(*opts)); memset(args, 0, sizeof(*args));
if (subparser && subparser->extraOptions) { if (subparser && subparser->extraOptions) {
// TODO: modularize options to subparsers // TODO: modularize options to subparsers
strncat(options, subparser->extraOptions, sizeof(options) - strlen(options) - 1); strncat(options, subparser->extraOptions, sizeof(options) - strlen(options) - 1);
@ -74,51 +75,51 @@ bool parseArguments(struct GBAArguments* opts, struct mCoreConfig* config, int a
switch (ch) { switch (ch) {
case '\0': case '\0':
if (strcmp(opt->name, "version") == 0) { if (strcmp(opt->name, "version") == 0) {
opts->showVersion = true; args->showVersion = true;
} else { } else {
return false; return false;
} }
break; break;
case 'b': case 'b':
mCoreConfigSetOverrideValue(config, "bios", optarg); args->bios = strdup(optarg);
break; break;
case 'c': case 'c':
opts->cheatsFile = strdup(optarg); args->cheatsFile = strdup(optarg);
break; break;
#ifdef USE_CLI_DEBUGGER #ifdef USE_CLI_DEBUGGER
case 'd': case 'd':
if (opts->debuggerType != DEBUGGER_NONE) { if (args->debuggerType != DEBUGGER_NONE) {
return false; return false;
} }
opts->debuggerType = DEBUGGER_CLI; args->debuggerType = DEBUGGER_CLI;
break; break;
#endif #endif
#ifdef USE_GDB_STUB #ifdef USE_GDB_STUB
case 'g': case 'g':
if (opts->debuggerType != DEBUGGER_NONE) { if (args->debuggerType != DEBUGGER_NONE) {
return false; return false;
} }
opts->debuggerType = DEBUGGER_GDB; args->debuggerType = DEBUGGER_GDB;
break; break;
#endif #endif
case 'h': case 'h':
opts->showHelp = true; args->showHelp = true;
break; break;
case 'l': case 'l':
mCoreConfigSetOverrideValue(config, "logLevel", optarg); args->logLevel = atoi(optarg);
break; break;
case 'p': case 'p':
opts->patch = strdup(optarg); args->patch = strdup(optarg);
break; break;
case 's': case 's':
mCoreConfigSetOverrideValue(config, "frameskip", optarg); args->frameskip = atoi(optarg);
break; break;
case 'v': case 'v':
opts->movie = strdup(optarg); args->movie = strdup(optarg);
break; break;
default: default:
if (subparser) { if (subparser) {
if (!subparser->parse(subparser, config, ch, optarg)) { if (!subparser->parse(subparser, ch, optarg)) {
return false; return false;
} }
} }
@ -128,39 +129,54 @@ bool parseArguments(struct GBAArguments* opts, struct mCoreConfig* config, int a
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (argc != 1) { if (argc != 1) {
return opts->showHelp || opts->showVersion; return args->showHelp || args->showVersion;
} }
opts->fname = strdup(argv[0]); args->fname = strdup(argv[0]);
return true; return true;
} }
void freeArguments(struct GBAArguments* opts) { void applyArguments(struct mArguments* args, struct mSubParser* subparser, struct mCoreConfig* config) {
free(opts->fname); mCoreConfigSetOverrideIntValue(config, "frameskip", args->frameskip);
opts->fname = 0; mCoreConfigSetOverrideIntValue(config, "logLevel", args->logLevel);
mCoreConfigSetOverrideValue(config, "bios", args->bios);
free(opts->patch); if (subparser) {
opts->patch = 0; subparser->apply(subparser, config);
}
free(opts->movie);
opts->movie = 0;
} }
void initParserForGraphics(struct SubParser* parser, struct GraphicsOpts* opts) { void freeArguments(struct mArguments* args) {
free(args->fname);
args->fname = 0;
free(args->patch);
args->patch = 0;
free(args->movie);
args->movie = 0;
free(args->cheatsFile);
args->cheatsFile = 0;
free(args->bios);
args->bios = 0;
}
void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts) {
parser->usage = GRAPHICS_USAGE; parser->usage = GRAPHICS_USAGE;
parser->opts = opts; parser->opts = opts;
parser->parse = _parseGraphicsArg; parser->parse = _parseGraphicsArg;
parser->apply = _applyGraphicsArgs;
parser->extraOptions = GRAPHICS_OPTIONS; parser->extraOptions = GRAPHICS_OPTIONS;
opts->multiplier = 0; opts->multiplier = 0;
opts->fullscreen = false; opts->fullscreen = false;
} }
bool _parseGraphicsArg(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg) { bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg) {
UNUSED(arg); UNUSED(arg);
struct GraphicsOpts* graphicsOpts = parser->opts; struct mGraphicsOpts* graphicsOpts = parser->opts;
switch (option) { switch (option) {
case 'f': case 'f':
graphicsOpts->fullscreen = true; graphicsOpts->fullscreen = true;
mCoreConfigSetOverrideIntValue(config, "fullscreen", 1);
return true; return true;
case '1': case '1':
case '2': case '2':
@ -172,15 +188,18 @@ bool _parseGraphicsArg(struct SubParser* parser, struct mCoreConfig* config, int
return false; return false;
} }
graphicsOpts->multiplier = option - '0'; graphicsOpts->multiplier = option - '0';
mCoreConfigSetOverrideIntValue(config, "width", VIDEO_HORIZONTAL_PIXELS * graphicsOpts->multiplier);
mCoreConfigSetOverrideIntValue(config, "height", VIDEO_VERTICAL_PIXELS * graphicsOpts->multiplier);
return true; return true;
default: default:
return false; return false;
} }
} }
struct ARMDebugger* createDebugger(struct GBAArguments* opts, struct GBAThread* context) { void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config) {
struct mGraphicsOpts* graphicsOpts = parser->opts;
mCoreConfigSetOverrideIntValue(config, "fullscreen", graphicsOpts->fullscreen);
}
struct ARMDebugger* createDebugger(struct mArguments* opts, struct GBAThread* context) {
#ifndef USE_CLI_DEBUGGER #ifndef USE_CLI_DEBUGGER
UNUSED(context); UNUSED(context);
#endif #endif

View File

@ -8,8 +8,6 @@
#include "util/common.h" #include "util/common.h"
#include "core/config.h"
enum DebuggerType { enum DebuggerType {
DEBUGGER_NONE = 0, DEBUGGER_NONE = 0,
#ifdef USE_CLI_DEBUGGER #ifdef USE_CLI_DEBUGGER
@ -21,11 +19,14 @@ enum DebuggerType {
DEBUGGER_MAX DEBUGGER_MAX
}; };
struct GBAArguments { struct mArguments {
char* fname; char* fname;
char* patch; char* patch;
char* cheatsFile; char* cheatsFile;
char* movie; char* movie;
char* bios;
int logLevel;
int frameskip;
enum DebuggerType debuggerType; enum DebuggerType debuggerType;
bool debugAtStart; bool debugAtStart;
@ -33,28 +34,31 @@ struct GBAArguments {
bool showVersion; bool showVersion;
}; };
struct SubParser { struct mCoreConfig;
struct mSubParser {
const char* usage; const char* usage;
bool (*parse)(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg); bool (*parse)(struct mSubParser* parser, int option, const char* arg);
void (*apply)(struct mSubParser* parser, struct mCoreConfig* config);
const char* extraOptions; const char* extraOptions;
void* opts; void* opts;
}; };
struct GraphicsOpts { struct mGraphicsOpts {
int multiplier; int multiplier;
bool fullscreen; bool fullscreen;
}; };
struct GBAThread; struct GBAThread;
bool parseArguments(struct GBAArguments* opts, struct mCoreConfig* config, int argc, char* const* argv, bool parseArguments(struct mArguments* args, int argc, char* const* argv,
struct SubParser* subparser); struct mSubParser* subparser);
void freeArguments(struct GBAArguments* opts); void applyArguments(struct mArguments* args, struct mSubParser* subparser, struct mCoreConfig* config);
void freeArguments(struct mArguments* args);
void usage(const char* arg0, const char* extraOptions); void usage(const char* arg0, const char* extraOptions);
void version(const char* arg0); void version(const char* arg0);
void initParserForGraphics(struct SubParser* parser, struct GraphicsOpts* opts); void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts);
struct ARMDebugger* createDebugger(struct GBAArguments* opts, struct GBAThread* context); struct ARMDebugger* createDebugger(struct mArguments* opts, struct GBAThread* context);
#endif #endif

View File

@ -48,9 +48,8 @@ static struct GBACheatDevice cheats;
static struct GBACheatSet cheatSet; static struct GBACheatSet cheatSet;
static void _reloadSettings(void) { static void _reloadSettings(void) {
struct GBAOptions opts = { struct mCoreOptions opts = {
.useBios = true, .useBios = true,
.idleOptimization = IDLE_LOOP_REMOVE
}; };
struct retro_variable var; struct retro_variable var;
@ -71,11 +70,11 @@ static void _reloadSettings(void) {
var.value = 0; var.value = 0;
if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
if (strcmp(var.value, "Don't Remove") == 0) { if (strcmp(var.value, "Don't Remove") == 0) {
opts.idleOptimization = IDLE_LOOP_IGNORE; mCoreConfigSetDefaultIntValue(&context.config, "idleOptimization", IDLE_LOOP_IGNORE);
} else if (strcmp(var.value, "Remove Known") == 0) { } else if (strcmp(var.value, "Remove Known") == 0) {
opts.idleOptimization = IDLE_LOOP_REMOVE; mCoreConfigSetDefaultIntValue(&context.config, "idleOptimization", IDLE_LOOP_REMOVE);
} else if (strcmp(var.value, "Detect and Remove") == 0) { } else if (strcmp(var.value, "Detect and Remove") == 0) {
opts.idleOptimization = IDLE_LOOP_DETECT; mCoreConfigSetDefaultIntValue(&context.config, "idleOptimization", IDLE_LOOP_DETECT);
} }
} }

View File

@ -59,9 +59,8 @@
{ {
// TODO: Add a log handler // TODO: Add a log handler
GBAContextInit(&context, 0); GBAContextInit(&context, 0);
struct GBAOptions opts = { struct mCoreOptions opts = {
.useBios = true, .useBios = true,
.idleOptimization = IDLE_LOOP_REMOVE
}; };
mCoreConfigLoadDefaults(&context.config, &opts); mCoreConfigLoadDefaults(&context.config, &opts);
GBAVideoSoftwareRendererCreate(&renderer); GBAVideoSoftwareRendererCreate(&renderer);

View File

@ -126,9 +126,10 @@ ConfigController::~ConfigController() {
mCoreConfigFreeOpts(&m_opts); mCoreConfigFreeOpts(&m_opts);
} }
bool ConfigController::parseArguments(GBAArguments* args, int argc, char* argv[], SubParser* subparser) { bool ConfigController::parseArguments(mArguments* args, int argc, char* argv[], mSubParser* subparser) {
if (::parseArguments(args, &m_config, argc, argv, subparser)) { if (::parseArguments(args, argc, argv, subparser)) {
mCoreConfigFreeOpts(&m_opts); mCoreConfigFreeOpts(&m_opts);
applyArguments(args, subparser, &m_config);
mCoreConfigMap(&m_config, &m_opts); mCoreConfigMap(&m_config, &m_opts);
return true; return true;
} }

View File

@ -22,7 +22,7 @@ extern "C" {
class QAction; class QAction;
class QMenu; class QMenu;
struct GBAArguments; struct mArguments;
struct GBACartridgeOverride; struct GBACartridgeOverride;
namespace QGBA { namespace QGBA {
@ -64,8 +64,8 @@ public:
ConfigController(QObject* parent = nullptr); ConfigController(QObject* parent = nullptr);
~ConfigController(); ~ConfigController();
const GBAOptions* options() const { return &m_opts; } const mCoreOptions* options() const { return &m_opts; }
bool parseArguments(GBAArguments* args, int argc, char* argv[], SubParser* subparser = nullptr); bool parseArguments(mArguments* args, int argc, char* argv[], mSubParser* subparser = nullptr);
ConfigOption* addOption(const char* key); ConfigOption* addOption(const char* key);
void updateOption(const char* key); void updateOption(const char* key);
@ -97,7 +97,7 @@ private:
Configuration* defaults() { return &m_config.defaultsTable; } Configuration* defaults() { return &m_config.defaultsTable; }
mCoreConfig m_config; mCoreConfig m_config;
GBAOptions m_opts; mCoreOptions m_opts;
QMap<QString, ConfigOption*> m_optionSet; QMap<QString, ConfigOption*> m_optionSet;
QSettings* m_settings; QSettings* m_settings;

View File

@ -52,9 +52,9 @@ GBAApp::GBAApp(int& argc, char* argv[])
Display::setDriver(static_cast<Display::Driver>(m_configController.getQtOption("displayDriver").toInt())); Display::setDriver(static_cast<Display::Driver>(m_configController.getQtOption("displayDriver").toInt()));
} }
GBAArguments args; mArguments args;
GraphicsOpts graphicsOpts; mGraphicsOpts graphicsOpts;
SubParser subparser; mSubParser subparser;
initParserForGraphics(&subparser, &graphicsOpts); initParserForGraphics(&subparser, &graphicsOpts);
bool loaded = m_configController.parseArguments(&args, argc, argv, &subparser); bool loaded = m_configController.parseArguments(&args, argc, argv, &subparser);
if (loaded && args.showHelp) { if (loaded && args.showHelp) {

View File

@ -245,7 +245,7 @@ void GameController::setOverride(const GBACartridgeOverride& override) {
m_threadContext.hasOverride = true; m_threadContext.hasOverride = true;
} }
void GameController::setOptions(const GBAOptions* opts) { void GameController::setOptions(const mCoreOptions* opts) {
setFrameskip(opts->frameskip); setFrameskip(opts->frameskip);
setAudioSync(opts->audioSync); setAudioSync(opts->audioSync);
setVideoSync(opts->videoSync); setVideoSync(opts->videoSync);
@ -257,7 +257,7 @@ void GameController::setOptions(const GBAOptions* opts) {
threadInterrupt(); threadInterrupt();
mDirectorySetMapOptions(&m_threadContext.dirs, opts); mDirectorySetMapOptions(&m_threadContext.dirs, opts);
m_threadContext.idleOptimization = opts->idleOptimization; // TODO: Put back idle optimization
threadContinue(); threadContinue();
} }

View File

@ -25,7 +25,7 @@ extern "C" {
} }
struct GBAAudio; struct GBAAudio;
struct GBAOptions; struct mCoreOptions;
struct GBAVideoSoftwareRenderer; struct GBAVideoSoftwareRenderer;
struct Configuration; struct Configuration;
@ -70,7 +70,7 @@ public:
void setOverride(const GBACartridgeOverride& override); void setOverride(const GBACartridgeOverride& override);
void clearOverride() { m_threadContext.hasOverride = false; } void clearOverride() { m_threadContext.hasOverride = false; }
void setOptions(const GBAOptions*); void setOptions(const mCoreOptions*);
int stateSlot() const { return m_stateSlot; } int stateSlot() const { return m_stateSlot; }

View File

@ -172,7 +172,7 @@ Window::~Window() {
#endif #endif
} }
void Window::argumentsPassed(GBAArguments* args) { void Window::argumentsPassed(mArguments* args) {
loadConfig(); loadConfig();
if (args->patch) { if (args->patch) {
@ -197,7 +197,7 @@ void Window::setConfig(ConfigController* config) {
} }
void Window::loadConfig() { void Window::loadConfig() {
const GBAOptions* opts = m_config->options(); const mCoreOptions* opts = m_config->options();
reloadConfig(); reloadConfig();
// TODO: Move these to ConfigController // TODO: Move these to ConfigController
@ -237,7 +237,7 @@ void Window::loadConfig() {
} }
void Window::reloadConfig() { void Window::reloadConfig() {
const GBAOptions* opts = m_config->options(); const mCoreOptions* opts = m_config->options();
m_log.setLevels(opts->logLevel); m_log.setLevels(opts->logLevel);

View File

@ -21,9 +21,7 @@ extern "C" {
#include "InputController.h" #include "InputController.h"
#include "LoadSaveState.h" #include "LoadSaveState.h"
#include "LogController.h" #include "LogController.h"
struct mArguments;
struct GBAOptions;
struct GBAArguments;
namespace QGBA { namespace QGBA {
@ -47,7 +45,7 @@ public:
GameController* controller() { return m_controller; } GameController* controller() { return m_controller; }
void setConfig(ConfigController*); void setConfig(ConfigController*);
void argumentsPassed(GBAArguments*); void argumentsPassed(mArguments*);
void resizeFrame(int width, int height); void resizeFrame(int width, int height);

View File

@ -53,22 +53,15 @@ static void mSDLDeinit(struct mSDLRenderer* renderer);
// TODO: Clean up signatures // TODO: Clean up signatures
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
static int mSDLRunGBA(struct mSDLRenderer* renderer, struct GBAArguments* args, struct GBAOptions* opts, struct mCoreConfig* config); static int mSDLRunGBA(struct mSDLRenderer* renderer, struct mArguments* args, struct mCoreOptions* opts, struct mCoreConfig* config);
#endif #endif
static int mSDLRun(struct mSDLRenderer* renderer, struct GBAArguments* args); static int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args);
int main(int argc, char** argv) { int main(int argc, char** argv) {
struct mSDLRenderer renderer = {}; struct mSDLRenderer renderer = {};
struct mInputMap inputMap; struct mCoreOptions opts = {
mInputMapInit(&inputMap, &GBAInputInfo);
struct mCoreConfig config;
mCoreConfigInit(&config, PORT);
mCoreConfigLoad(&config);
struct GBAOptions opts = {
.width = 0, .width = 0,
.height = 0, .height = 0,
.useBios = true, .useBios = true,
@ -78,25 +71,21 @@ int main(int argc, char** argv) {
.audioSync = true, .audioSync = true,
}; };
struct GBAArguments args; struct mArguments args;
struct GraphicsOpts graphicsOpts; struct mGraphicsOpts graphicsOpts;
struct SubParser subparser; struct mSubParser subparser;
initParserForGraphics(&subparser, &graphicsOpts); initParserForGraphics(&subparser, &graphicsOpts);
bool parsed = parseArguments(&args, &config, argc, argv, &subparser); bool parsed = parseArguments(&args, argc, argv, &subparser);
if (!parsed || args.showHelp) { if (!parsed || args.showHelp) {
usage(argv[0], subparser.usage); usage(argv[0], subparser.usage);
freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config);
return !parsed; return !parsed;
} }
if (args.showVersion) { if (args.showVersion) {
version(argv[0]); version(argv[0]);
freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config);
return 0; return 0;
} }
@ -108,7 +97,6 @@ int main(int argc, char** argv) {
printf("Could not open game. Are you sure the file exists?\n"); printf("Could not open game. Are you sure the file exists?\n");
freeArguments(&args); freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config);
return 1; return 1;
} }
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
@ -153,13 +141,15 @@ int main(int argc, char** argv) {
printf("Could not run game. Are you sure the file exists and is a compatible game?\n"); printf("Could not run game. Are you sure the file exists and is a compatible game?\n");
freeArguments(&args); freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config);
return 1; return 1;
} }
} }
mCoreConfigLoadDefaults(&config, &opts); mInputMapInit(&renderer.core->inputMap, &GBAInputInfo);
mCoreConfigMap(&config, &opts); mCoreInitConfig(renderer.core, PORT);
applyArguments(&args, &subparser, &renderer.core->config);
mCoreConfigLoadDefaults(&renderer.core->config, &opts);
renderer.viewportWidth = opts.width; renderer.viewportWidth = opts.width;
renderer.viewportHeight = opts.height; renderer.viewportHeight = opts.height;
@ -180,7 +170,7 @@ int main(int argc, char** argv) {
if (!mSDLInit(&renderer)) { if (!mSDLInit(&renderer)) {
freeArguments(&args); freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config); mCoreConfigDeinit(&renderer.core->config);
return 1; return 1;
} }
@ -188,32 +178,33 @@ int main(int argc, char** argv) {
// TODO: Check return code // TODO: Check return code
renderer.core->init(renderer.core); renderer.core->init(renderer.core);
} }
mCoreLoadConfig(renderer.core);
renderer.player.bindings = &inputMap; renderer.player.bindings = &renderer.core->inputMap;
mSDLInitBindingsGBA(&inputMap); mSDLInitBindingsGBA(&renderer.core->inputMap);
mSDLInitEvents(&renderer.events); mSDLInitEvents(&renderer.events);
mSDLEventsLoadConfig(&renderer.events, mCoreConfigGetInput(&config)); mSDLEventsLoadConfig(&renderer.events, mCoreConfigGetInput(&renderer.core->config));
mSDLAttachPlayer(&renderer.events, &renderer.player); mSDLAttachPlayer(&renderer.events, &renderer.player);
mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&config)); mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&renderer.core->config));
int ret; int ret;
// TODO: Use opts and config // TODO: Use opts and config
ret = mSDLRun(&renderer, &args); ret = mSDLRun(&renderer, &args);
mSDLDetachPlayer(&renderer.events, &renderer.player); mSDLDetachPlayer(&renderer.events, &renderer.player);
mInputMapDeinit(&inputMap); mInputMapDeinit(&renderer.core->inputMap);
mSDLDeinit(&renderer); mSDLDeinit(&renderer);
freeArguments(&args); freeArguments(&args);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
mCoreConfigDeinit(&config); mCoreConfigDeinit(&renderer.core->config);
return ret; return ret;
} }
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
int mSDLRunGBA(struct mSDLRenderer* renderer, struct GBAArguments* args, struct GBAOptions* opts, struct mCoreConfig* config) { int mSDLRunGBA(struct mSDLRenderer* renderer, struct mArguments* args, struct mCoreOptions* opts, struct mCoreConfig* config) {
struct GBAThread context = { struct GBAThread context = {
.userData = renderer .userData = renderer
}; };
@ -265,7 +256,7 @@ int mSDLRunGBA(struct mSDLRenderer* renderer, struct GBAArguments* args, struct
} }
#endif #endif
int mSDLRun(struct mSDLRenderer* renderer, struct GBAArguments* args) { int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
struct mCoreThread thread = { struct mCoreThread thread = {
.core = renderer->core, .core = renderer->core,
.sync = { .sync = {

View File

@ -375,9 +375,9 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events) {
#endif #endif
} }
static void _pauseAfterFrame(struct GBAThread* context) { static void _pauseAfterFrame(struct mCoreThread* context) {
context->frameCallback = 0; context->frameCallback = 0;
GBAThreadPauseFromThread(context); mCoreThreadPauseFromThread(context);
} }
static void _mSDLHandleKeypressGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const struct SDL_KeyboardEvent* event) { static void _mSDLHandleKeypressGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const struct SDL_KeyboardEvent* event) {
@ -415,11 +415,6 @@ static void _mSDLHandleKeypressGBA(struct GBAThread* context, struct mSDLPlayer*
GBAThreadContinue(context); GBAThreadContinue(context);
return; return;
#endif #endif
case SDLK_BACKSLASH:
GBAThreadPause(context);
context->frameCallback = _pauseAfterFrame;
GBAThreadUnpause(context);
return;
case SDLK_BACKQUOTE: case SDLK_BACKQUOTE:
GBAThreadInterrupt(context); GBAThreadInterrupt(context);
GBARewind(context, 10); GBARewind(context, 10);
@ -443,11 +438,6 @@ static void _mSDLHandleKeypressGBA(struct GBAThread* context, struct mSDLPlayer*
case SDLK_p: case SDLK_p:
GBAThreadTogglePause(context); GBAThreadTogglePause(context);
break; break;
case SDLK_n:
GBAThreadPause(context);
context->frameCallback = _pauseAfterFrame;
GBAThreadUnpause(context);
break;
case SDLK_r: case SDLK_r:
GBAThreadReset(context); GBAThreadReset(context);
break; break;
@ -575,7 +565,9 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer*
return; return;
#endif #endif
case SDLK_BACKSLASH: case SDLK_BACKSLASH:
// TODO: Put back frame advance mCoreThreadPause(context);
context->frameCallback = _pauseAfterFrame;
mCoreThreadUnpause(context);
return; return;
case SDLK_BACKQUOTE: case SDLK_BACKQUOTE:
// TODO: Put back rewind // TODO: Put back rewind
@ -599,7 +591,9 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer*
mCoreThreadTogglePause(context); mCoreThreadTogglePause(context);
break; break;
case SDLK_n: case SDLK_n:
// TODO: Put back frame advance mCoreThreadPause(context);
context->frameCallback = _pauseAfterFrame;
mCoreThreadUnpause(context);
break; break;
case SDLK_r: case SDLK_r:
mCoreThreadReset(context); mCoreThreadReset(context);

View File

@ -36,7 +36,7 @@ struct FuzzOpts {
static void _GBAFuzzRunloop(struct GBAContext* context, int frames); static void _GBAFuzzRunloop(struct GBAContext* context, int frames);
static void _GBAFuzzShutdown(int signal); static void _GBAFuzzShutdown(int signal);
static bool _parseFuzzOpts(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg); static bool _parseFuzzOpts(struct mSubParser* parser, int option, const char* arg);
static bool _dispatchExiting = false; static bool _dispatchExiting = false;
@ -44,7 +44,7 @@ int main(int argc, char** argv) {
signal(SIGINT, _GBAFuzzShutdown); signal(SIGINT, _GBAFuzzShutdown);
struct FuzzOpts fuzzOpts = { false, 0, 0, 0, 0 }; struct FuzzOpts fuzzOpts = { false, 0, 0, 0, 0 };
struct SubParser subparser = { struct mSubParser subparser = {
.usage = FUZZ_USAGE, .usage = FUZZ_USAGE,
.parse = _parseFuzzOpts, .parse = _parseFuzzOpts,
.extraOptions = FUZZ_OPTIONS, .extraOptions = FUZZ_OPTIONS,
@ -53,26 +53,23 @@ int main(int argc, char** argv) {
struct GBAContext context; struct GBAContext context;
GBAContextInit(&context, "fuzz"); GBAContextInit(&context, "fuzz");
struct GBAOptions opts = { struct mCoreOptions opts = {}; // TODO: Put back idle loops
.idleOptimization = IDLE_LOOP_DETECT
};
mCoreConfigLoadDefaults(&context.config, &opts); mCoreConfigLoadDefaults(&context.config, &opts);
mCoreConfigFreeOpts(&opts); mCoreConfigFreeOpts(&opts);
struct GBAArguments args; struct mArguments args;
bool parsed = parseArguments(&args, &context.config, argc, argv, &subparser); bool parsed = parseArguments(&args, argc, argv, &subparser);
if (!parsed || args.showHelp) { if (!parsed || args.showHelp) {
usage(argv[0], FUZZ_USAGE); usage(argv[0], FUZZ_USAGE);
freeArguments(&args);
GBAContextDeinit(&context); GBAContextDeinit(&context);
return !parsed; return !parsed;
} }
if (args.showVersion) { if (args.showVersion) {
version(argv[0]); version(argv[0]);
freeArguments(&args);
GBAContextDeinit(&context); GBAContextDeinit(&context);
return 0; return 0;
} }
applyArguments(&args, NULL, &context.config);
struct GBAVideoSoftwareRenderer renderer; struct GBAVideoSoftwareRenderer renderer;
renderer.outputBuffer = 0; renderer.outputBuffer = 0;
@ -161,8 +158,7 @@ static void _GBAFuzzShutdown(int signal) {
_dispatchExiting = true; _dispatchExiting = true;
} }
static bool _parseFuzzOpts(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg) { static bool _parseFuzzOpts(struct mSubParser* parser, int option, const char* arg) {
UNUSED(config);
struct FuzzOpts* opts = parser->opts; struct FuzzOpts* opts = parser->opts;
errno = 0; errno = 0;
switch (option) { switch (option) {

View File

@ -38,7 +38,7 @@ struct PerfOpts {
static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet); static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet);
static void _GBAPerfShutdown(int signal); static void _GBAPerfShutdown(int signal);
static bool _parsePerfOpts(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg); static bool _parsePerfOpts(struct mSubParser* parser, int option, const char* arg);
static void _loadSavestate(struct GBAThread* context); static void _loadSavestate(struct GBAThread* context);
static struct GBAThread* _thread; static struct GBAThread* _thread;
@ -52,7 +52,7 @@ int main(int argc, char** argv) {
GBAVideoSoftwareRendererCreate(&renderer); GBAVideoSoftwareRendererCreate(&renderer);
struct PerfOpts perfOpts = { false, false, 0, 0, 0 }; struct PerfOpts perfOpts = { false, false, 0, 0, 0 };
struct SubParser subparser = { struct mSubParser subparser = {
.usage = PERF_USAGE, .usage = PERF_USAGE,
.parse = _parsePerfOpts, .parse = _parsePerfOpts,
.extraOptions = PERF_OPTIONS, .extraOptions = PERF_OPTIONS,
@ -63,13 +63,11 @@ int main(int argc, char** argv) {
mCoreConfigInit(&config, "perf"); mCoreConfigInit(&config, "perf");
mCoreConfigLoad(&config); mCoreConfigLoad(&config);
struct GBAOptions opts = { struct mCoreOptions opts = {}; // TODO: Put back idle loops
.idleOptimization = IDLE_LOOP_DETECT
};
mCoreConfigLoadDefaults(&config, &opts); mCoreConfigLoadDefaults(&config, &opts);
struct GBAArguments args; struct mArguments args;
bool parsed = parseArguments(&args, &config, argc, argv, &subparser); bool parsed = parseArguments(&args, argc, argv, &subparser);
if (!parsed || args.showHelp) { if (!parsed || args.showHelp) {
usage(argv[0], PERF_USAGE); usage(argv[0], PERF_USAGE);
freeArguments(&args); freeArguments(&args);
@ -84,6 +82,7 @@ int main(int argc, char** argv) {
mCoreConfigDeinit(&config); mCoreConfigDeinit(&config);
return 0; return 0;
} }
applyArguments(&args, NULL, &config);
renderer.outputBuffer = malloc(256 * 256 * 4); renderer.outputBuffer = malloc(256 * 256 * 4);
renderer.outputBufferStride = 256; renderer.outputBufferStride = 256;
@ -212,8 +211,7 @@ static void _GBAPerfShutdown(int signal) {
ConditionWake(&_thread->sync.videoFrameAvailableCond); ConditionWake(&_thread->sync.videoFrameAvailableCond);
} }
static bool _parsePerfOpts(struct SubParser* parser, struct mCoreConfig* config, int option, const char* arg) { static bool _parsePerfOpts(struct mSubParser* parser, int option, const char* arg) {
UNUSED(config);
struct PerfOpts* opts = parser->opts; struct PerfOpts* opts = parser->opts;
errno = 0; errno = 0;
switch (option) { switch (option) {