Feature: Command line ability to override configuration values

This commit is contained in:
Vicki Pfau 2017-04-11 22:20:37 -07:00
parent bf716b947a
commit d16df69790
3 changed files with 40 additions and 10 deletions

View File

@ -12,6 +12,7 @@ Features:
- Add option for whether rewinding restores save games - Add option for whether rewinding restores save games
- Qt: German translation (by Lothar Serra Mari) - Qt: German translation (by Lothar Serra Mari)
- Savestates now contain any RTC override data - Savestates now contain any RTC override data
- Command line ability to override configuration values
Bugfixes: Bugfixes:
- LR35902: Fix core never exiting with certain event patterns - LR35902: Fix core never exiting with certain event patterns
- GB Timer: Improve DIV reset behavior - GB Timer: Improve DIV reset behavior

View File

@ -48,10 +48,27 @@ static const struct option _options[] = {
static bool _parseGraphicsArg(struct mSubParser* parser, 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); 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) { 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:C:hl:p:s:v:"
#ifdef USE_EDITLINE #ifdef USE_EDITLINE
"d" "d"
#endif #endif
@ -62,6 +79,7 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
args->frameskip = -1; args->frameskip = -1;
args->logLevel = INT_MIN; args->logLevel = INT_MIN;
HashTableInit(&args->configOverrides, 0, free);
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);
@ -83,6 +101,9 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
case 'c': case 'c':
args->cheatsFile = strdup(optarg); args->cheatsFile = strdup(optarg);
break; break;
case 'C':
_tableInsert(&args->configOverrides, optarg);
break;
#ifdef USE_EDITLINE #ifdef USE_EDITLINE
case 'd': case 'd':
if (args->debuggerType != DEBUGGER_NONE) { if (args->debuggerType != DEBUGGER_NONE) {
@ -145,6 +166,7 @@ void applyArguments(const struct mArguments* args, struct mSubParser* subparser,
if (args->bios) { if (args->bios) {
mCoreConfigSetOverrideValue(config, "bios", args->bios); mCoreConfigSetOverrideValue(config, "bios", args->bios);
} }
HashTableEnumerate(&args->configOverrides, _tableApply, config);
if (subparser) { if (subparser) {
subparser->apply(subparser, config); subparser->apply(subparser, config);
} }
@ -165,6 +187,8 @@ void freeArguments(struct mArguments* args) {
free(args->bios); free(args->bios);
args->bios = 0; args->bios = 0;
HashTableDeinit(&args->configOverrides);
} }
void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts) { 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) { void usage(const char* arg0, const char* extraOptions) {
printf("usage: %s [option ...] file\n", arg0); printf("usage: %s [option ...] file\n", arg0);
puts("\nGeneric options:"); puts("\nGeneric options:");
puts(" -b, --bios FILE GBA BIOS file to use"); puts(" -b, --bios FILE GBA BIOS file to use");
puts(" -c, --cheats FILE Apply cheat codes from a file"); puts(" -c, --cheats FILE Apply cheat codes from a file");
puts(" -C, --config OPTION=VALUE Override config value");
#ifdef USE_EDITLINE #ifdef USE_EDITLINE
puts(" -d, --debug Use command-line debugger"); puts(" -d, --debug Use command-line debugger");
#endif #endif
#ifdef USE_GDB_STUB #ifdef USE_GDB_STUB
puts(" -g, --gdb Start GDB session (default port 2345)"); puts(" -g, --gdb Start GDB session (default port 2345)");
#endif #endif
puts(" -l, --log-level N Log level mask"); puts(" -l, --log-level N Log level mask");
puts(" -v, --movie FILE Play back a movie of recorded input"); puts(" -v, --movie FILE Play back a movie of recorded input");
puts(" -p, --patch FILE Apply a specified patch file when running"); puts(" -p, --patch FILE Apply a specified patch file when running");
puts(" -s, --frameskip N Skip every N frames"); puts(" -s, --frameskip N Skip every N frames");
puts(" --version Print version and exit"); puts(" --version Print version and exit");
if (extraOptions) { if (extraOptions) {
puts(extraOptions); puts(extraOptions);
} }

View File

@ -10,6 +10,8 @@
CXX_GUARD_START CXX_GUARD_START
#include <mgba-util/table.h>
#include <mgba/internal/debugger/debugger.h> #include <mgba/internal/debugger/debugger.h>
struct mArguments { struct mArguments {
@ -21,6 +23,8 @@ struct mArguments {
int logLevel; int logLevel;
int frameskip; int frameskip;
struct Table configOverrides;
enum mDebuggerType debuggerType; enum mDebuggerType debuggerType;
bool debugAtStart; bool debugAtStart;
bool showHelp; bool showHelp;