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/. */
#include "config.h"
#include "gba/gba.h"
#include "util/formatting.h"
#include "util/string.h"
#include "util/vfs.h"
@ -299,7 +300,7 @@ void mCoreConfigSetOverrideFloatValue(struct mCoreConfig* config, const char* ke
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, "shader", &opts->shader);
_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, "screenshotPath", &opts->screenshotPath);
_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, "shader", opts->shader);
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, "resampleVideo", opts->resampleVideo);
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
@ -411,7 +388,7 @@ struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig* config) {
return &config->configTable;
}
void mCoreConfigFreeOpts(struct GBAOptions* opts) {
void mCoreConfigFreeOpts(struct mCoreOptions* opts) {
free(opts->bios);
free(opts->shader);
free(opts->savegamePath);

View File

@ -8,8 +8,6 @@
#include "util/common.h"
#include "gba/gba.h"
#include "util/configuration.h"
struct mCoreConfig {
@ -19,7 +17,7 @@ struct mCoreConfig {
char* port;
};
struct GBAOptions {
struct mCoreOptions {
char* bios;
bool skipBios;
bool useBios;
@ -50,8 +48,6 @@ struct GBAOptions {
bool videoSync;
bool audioSync;
enum GBAIdleLoopOptimization idleOptimization;
};
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 mCoreConfigSetOverrideFloatValue(struct mCoreConfig*, const char* key, float value);
void mCoreConfigMap(const struct mCoreConfig* config, struct GBAOptions* opts);
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct GBAOptions* opts);
void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts);
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts);
struct Configuration* mCoreConfigGetInput(struct mCoreConfig*);
struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig*);
void mCoreConfigFreeOpts(struct GBAOptions* opts);
void mCoreConfigFreeOpts(struct mCoreOptions* opts);
#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
#include "core/directories.h"
#endif
#ifndef MINIMAL_CORE
#include "core/input.h"
#endif
#include "core/config.h"
struct VFile;
struct mRTCSource;
struct mCoreConfig;
#ifdef COLOR_16_BIT
typedef uint16_t color_t;
@ -32,11 +37,17 @@ struct mCore {
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct mDirectorySet dirs;
#endif
#ifndef MINIMAL_CORE
struct mInputMap inputMap;
#endif
struct mCoreConfig config;
struct mCoreOptions opts;
bool (*init)(struct mCore*);
void (*deinit)(struct mCore*);
void (*setSync)(struct mCore*, struct mCoreSync*);
void (*loadConfig)(struct mCore*);
void (*desiredVideoDimensions)(struct mCore*, unsigned* width, unsigned* height);
void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride);
@ -72,9 +83,9 @@ struct mCore {
void (*setRTC)(struct mCore*, struct mRTCSource*);
};
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreLoadFile(struct mCore* core, const char* path);
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreAutoloadSave(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);
#endif
void mCoreInitConfig(struct mCore* core, const char* port);
void mCoreLoadConfig(struct mCore* core);
#endif

View File

@ -113,7 +113,7 @@ struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* su
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) {
struct VDir* dir = VDirOpen(opts->savegamePath);
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* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, const char* suffix, int mode);
struct GBAOptions;
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct GBAOptions* opts);
struct mCoreOptions;
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts);
#endif
#endif

View File

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

View File

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

View File

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

View File

@ -11,6 +11,7 @@
#include "gba/renderers/video-software.h"
#include "gba/serialize.h"
#include "util/memory.h"
#include "util/vfs.h"
struct GBACore {
struct mCore d;
@ -31,6 +32,8 @@ static bool _GBACoreInit(struct mCore* core) {
core->cpu = cpu;
core->board = gba;
memset(&core->opts, 0, sizeof(core->opts));
GBACreate(gba);
// TODO: Restore debugger and cheats
ARMSetComponents(cpu, &gba->d, 0, 0);
@ -63,6 +66,29 @@ static void _GBACoreSetSync(struct mCore* core, struct mCoreSync* 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) {
UNUSED(core);
*width = VIDEO_HORIZONTAL_PIXELS;
@ -109,6 +135,9 @@ static void _GBACoreUnloadROM(struct mCore* core) {
static void _GBACoreReset(struct mCore* core) {
ARMReset(core->cpu);
if (core->opts.skipBios) {
GBASkipBIOS(core->board);
}
}
static void _GBACoreRunFrame(struct mCore* core) {
@ -178,6 +207,7 @@ struct mCore* GBACoreCreate(void) {
core->init = _GBACoreInit;
core->deinit = _GBACoreDeinit;
core->setSync = _GBACoreSetSync;
core->loadConfig = _GBACoreLoadConfig;
core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions;
core->setVideoBuffer = _GBACoreSetVideoBuffer;
core->getAudioChannel = _GBACoreGetAudioChannel;

View File

@ -372,7 +372,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
return 0;
}
void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* threadContext) {
void GBAMapOptionsToContext(const struct mCoreOptions* opts, struct GBAThread* threadContext) {
if (opts->useBios) {
threadContext->bios = VFileOpen(opts->bios, O_RDONLY);
} else {
@ -400,12 +400,10 @@ void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* thr
threadContext->audioBuffers = opts->audioBuffers;
}
threadContext->idleOptimization = opts->idleOptimization;
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);
threadContext->fname = args->fname;
threadContext->patch = VFileOpen(args->patch, O_RDONLY);

View File

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

View File

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

View File

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

View File

@ -48,9 +48,8 @@ static struct GBACheatDevice cheats;
static struct GBACheatSet cheatSet;
static void _reloadSettings(void) {
struct GBAOptions opts = {
struct mCoreOptions opts = {
.useBios = true,
.idleOptimization = IDLE_LOOP_REMOVE
};
struct retro_variable var;
@ -71,11 +70,11 @@ static void _reloadSettings(void) {
var.value = 0;
if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
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) {
opts.idleOptimization = IDLE_LOOP_REMOVE;
mCoreConfigSetDefaultIntValue(&context.config, "idleOptimization", IDLE_LOOP_REMOVE);
} 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
GBAContextInit(&context, 0);
struct GBAOptions opts = {
struct mCoreOptions opts = {
.useBios = true,
.idleOptimization = IDLE_LOOP_REMOVE
};
mCoreConfigLoadDefaults(&context.config, &opts);
GBAVideoSoftwareRendererCreate(&renderer);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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