From d16df6979010a1864a9f4ef518edfd4387d2e6d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 11 Apr 2017 22:20:37 -0700 Subject: [PATCH] Feature: Command line ability to override configuration values --- CHANGES | 1 + src/feature/commandline.c | 45 ++++++++++++++++++++++++++++++--------- src/feature/commandline.h | 4 ++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 8739f213a..e48baefc3 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Features: - Add option for whether rewinding restores save games - Qt: German translation (by Lothar Serra Mari) - Savestates now contain any RTC override data + - Command line ability to override configuration values Bugfixes: - LR35902: Fix core never exiting with certain event patterns - GB Timer: Improve DIV reset behavior diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 9e9158208..07da69760 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -48,10 +48,27 @@ static const struct option _options[] = { static bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg); static void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config); +static void _tableInsert(struct Table* table, const char* pair) { + char* eq = strchr(pair, '='); + if (eq) { + char option[128] = ""; + strncpy(option, pair, eq - pair); + option[sizeof(option) - 1] = '\0'; + HashTableInsert(table, option, strdup(&eq[1])); + } else { + HashTableInsert(table, pair, strdup("1")); + } +} + +static void _tableApply(const char* key, void* value, void* user) { + struct mCoreConfig* config = user; + mCoreConfigSetOverrideValue(config, key, value); +} + bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparser) { int ch; char options[64] = - "b:c:hl:p:s:v:" + "b:c:C:hl:p:s:v:" #ifdef USE_EDITLINE "d" #endif @@ -62,6 +79,7 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct memset(args, 0, sizeof(*args)); args->frameskip = -1; args->logLevel = INT_MIN; + HashTableInit(&args->configOverrides, 0, free); if (subparser && subparser->extraOptions) { // TODO: modularize options to subparsers strncat(options, subparser->extraOptions, sizeof(options) - strlen(options) - 1); @@ -83,6 +101,9 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct case 'c': args->cheatsFile = strdup(optarg); break; + case 'C': + _tableInsert(&args->configOverrides, optarg); + break; #ifdef USE_EDITLINE case 'd': if (args->debuggerType != DEBUGGER_NONE) { @@ -145,6 +166,7 @@ void applyArguments(const struct mArguments* args, struct mSubParser* subparser, if (args->bios) { mCoreConfigSetOverrideValue(config, "bios", args->bios); } + HashTableEnumerate(&args->configOverrides, _tableApply, config); if (subparser) { subparser->apply(subparser, config); } @@ -165,6 +187,8 @@ void freeArguments(struct mArguments* args) { free(args->bios); args->bios = 0; + + HashTableDeinit(&args->configOverrides); } void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts) { @@ -210,19 +234,20 @@ void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config) { void usage(const char* arg0, const char* extraOptions) { printf("usage: %s [option ...] file\n", arg0); puts("\nGeneric options:"); - puts(" -b, --bios FILE GBA BIOS file to use"); - puts(" -c, --cheats FILE Apply cheat codes from a file"); + puts(" -b, --bios FILE GBA BIOS file to use"); + puts(" -c, --cheats FILE Apply cheat codes from a file"); + puts(" -C, --config OPTION=VALUE Override config value"); #ifdef USE_EDITLINE - puts(" -d, --debug Use command-line debugger"); + puts(" -d, --debug Use command-line debugger"); #endif #ifdef USE_GDB_STUB - puts(" -g, --gdb Start GDB session (default port 2345)"); + puts(" -g, --gdb Start GDB session (default port 2345)"); #endif - puts(" -l, --log-level N Log level mask"); - puts(" -v, --movie FILE Play back a movie of recorded input"); - puts(" -p, --patch FILE Apply a specified patch file when running"); - puts(" -s, --frameskip N Skip every N frames"); - puts(" --version Print version and exit"); + puts(" -l, --log-level N Log level mask"); + puts(" -v, --movie FILE Play back a movie of recorded input"); + puts(" -p, --patch FILE Apply a specified patch file when running"); + puts(" -s, --frameskip N Skip every N frames"); + puts(" --version Print version and exit"); if (extraOptions) { puts(extraOptions); } diff --git a/src/feature/commandline.h b/src/feature/commandline.h index 322c8e87b..b47442c21 100644 --- a/src/feature/commandline.h +++ b/src/feature/commandline.h @@ -10,6 +10,8 @@ CXX_GUARD_START +#include + #include struct mArguments { @@ -21,6 +23,8 @@ struct mArguments { int logLevel; int frameskip; + struct Table configOverrides; + enum mDebuggerType debuggerType; bool debugAtStart; bool showHelp;