GBA Config: Refresh configuration system to be more versatile

This commit is contained in:
Jeffrey Pfau 2014-11-04 23:54:09 -08:00
parent e884bc4d7a
commit 2ddb074bda
8 changed files with 175 additions and 78 deletions

View File

@ -1,34 +1,44 @@
#include "gba-config.h"
#include "platform/commandline.h"
#include "util/configuration.h"
#define SECTION_NAME_MAX 128
static const char* _lookupValue(const struct Configuration* config, const char* key, const char* port) {
if (port) {
char sectionName[SECTION_NAME_MAX];
snprintf(sectionName, SECTION_NAME_MAX, "ports.%s", port);
sectionName[SECTION_NAME_MAX - 1] = '\0';
const char* value = ConfigurationGetValue(config, sectionName, key);
static const char* _lookupValue(const struct GBAConfig* config, const char* key) {
const char* value;
if (config->port) {
value = ConfigurationGetValue(&config->configTable, config->port, key);
if (value) {
return value;
}
}
return ConfigurationGetValue(config, 0, key);
value = ConfigurationGetValue(&config->configTable, 0, key);
if (value) {
return value;
}
if (config->port) {
value = ConfigurationGetValue(&config->defaultsTable, config->port, key);
if (value) {
return value;
}
}
return ConfigurationGetValue(&config->defaultsTable, 0, key);
}
static bool _lookupCharValue(const struct Configuration* config, const char* key, const char* port, char** out) {
const char* value = _lookupValue(config, key, port);
static bool _lookupCharValue(const struct GBAConfig* config, const char* key, char** out) {
const char* value = _lookupValue(config, key);
if (!value) {
return false;
}
if (*out) {
free(*out);
}
*out = strdup(value);
return true;
}
static bool _lookupIntValue(const struct Configuration* config, const char* key, const char* port, int* out) {
const char* charValue = _lookupValue(config, key, port);
static bool _lookupIntValue(const struct GBAConfig* config, const char* key, int* out) {
const char* charValue = _lookupValue(config, key);
if (!charValue) {
return false;
}
@ -41,8 +51,8 @@ static bool _lookupIntValue(const struct Configuration* config, const char* key,
return true;
}
static bool _lookupUIntValue(const struct Configuration* config, const char* key, const char* port, unsigned* out) {
const char* charValue = _lookupValue(config, key, port);
static bool _lookupUIntValue(const struct GBAConfig* config, const char* key, unsigned* out) {
const char* charValue = _lookupValue(config, key);
if (!charValue) {
return false;
}
@ -55,8 +65,8 @@ static bool _lookupUIntValue(const struct Configuration* config, const char* key
return true;
}
static bool _lookupFloatValue(const struct Configuration* config, const char* key, const char* port, float* out) {
const char* charValue = _lookupValue(config, key, port);
static bool _lookupFloatValue(const struct GBAConfig* config, const char* key, float* out) {
const char* charValue = _lookupValue(config, key);
if (!charValue) {
return false;
}
@ -69,35 +79,97 @@ static bool _lookupFloatValue(const struct Configuration* config, const char* ke
return true;
}
bool GBAConfigLoad(struct Configuration* config) {
return ConfigurationRead(config, BINARY_NAME ".ini");
void GBAConfigInit(struct GBAConfig* config, const char* port) {
ConfigurationInit(&config->configTable);
ConfigurationInit(&config->defaultsTable);
config->port = malloc(strlen("ports.") + strlen(port) + 1);
sprintf(config->port, "ports.%s", port);
}
void GBAConfigMapGeneralOpts(const struct Configuration* config, const char* port, struct GBAOptions* opts) {
_lookupCharValue(config, "bios", port, &opts->bios);
_lookupIntValue(config, "logLevel", port, &opts->logLevel);
_lookupIntValue(config, "frameskip", port, &opts->frameskip);
_lookupIntValue(config, "rewindBufferCapacity", port, &opts->rewindBufferCapacity);
_lookupIntValue(config, "rewindBufferInterval", port, &opts->rewindBufferInterval);
_lookupFloatValue(config, "fpsTarget", port, &opts->fpsTarget);
void GBAConfigDeinit(struct GBAConfig* config) {
ConfigurationDeinit(&config->configTable);
ConfigurationDeinit(&config->defaultsTable);
free(config->port);
}
bool GBAConfigLoad(struct GBAConfig* config) {
return ConfigurationRead(&config->configTable, BINARY_NAME ".ini");
}
bool GBAConfigSave(const struct GBAConfig* config) {
return ConfigurationWrite(&config->configTable, BINARY_NAME ".ini");
}
void GBAConfigSetValue(struct GBAConfig* config, const char* key, const char* value) {
ConfigurationSetValue(&config->configTable, config->port, key, value);
}
void GBAConfigSetIntValue(struct GBAConfig* config, const char* key, int value) {
ConfigurationSetIntValue(&config->configTable, config->port, key, value);
}
void GBAConfigSetUIntValue(struct GBAConfig* config, const char* key, unsigned value) {
ConfigurationSetUIntValue(&config->configTable, config->port, key, value);
}
void GBAConfigSetFloatValue(struct GBAConfig* config, const char* key, float value) {
ConfigurationSetFloatValue(&config->configTable, config->port, key, value);
}
void GBAConfigSetDefaultValue(struct GBAConfig* config, const char* key, const char* value) {
ConfigurationSetValue(&config->defaultsTable, config->port, key, value);
}
void GBAConfigSetDefaultIntValue(struct GBAConfig* config, const char* key, int value) {
ConfigurationSetIntValue(&config->defaultsTable, config->port, key, value);
}
void GBAConfigSetDefaultUIntValue(struct GBAConfig* config, const char* key, unsigned value) {
ConfigurationSetUIntValue(&config->defaultsTable, config->port, key, value);
}
void GBAConfigSetDefaultFloatValue(struct GBAConfig* config, const char* key, float value) {
ConfigurationSetFloatValue(&config->defaultsTable, config->port, key, value);
}
void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) {
_lookupCharValue(config, "bios", &opts->bios);
_lookupIntValue(config, "logLevel", &opts->logLevel);
_lookupIntValue(config, "frameskip", &opts->frameskip);
_lookupIntValue(config, "rewindBufferCapacity", &opts->rewindBufferCapacity);
_lookupIntValue(config, "rewindBufferInterval", &opts->rewindBufferInterval);
_lookupFloatValue(config, "fpsTarget", &opts->fpsTarget);
unsigned audioBuffers;
if (_lookupUIntValue(config, "audioBuffers", port, &audioBuffers)) {
if (_lookupUIntValue(config, "audioBuffers", &audioBuffers)) {
opts->audioBuffers = audioBuffers;
}
int fakeBool;
if (_lookupIntValue(config, "audioSync", port, &fakeBool)) {
if (_lookupIntValue(config, "audioSync", &fakeBool)) {
opts->audioSync = fakeBool;
}
if (_lookupIntValue(config, "videoSync", port, &fakeBool)) {
if (_lookupIntValue(config, "videoSync", &fakeBool)) {
opts->videoSync = fakeBool;
}
_lookupIntValue(config, "fullscreen", &opts->fullscreen);
_lookupIntValue(config, "width", &opts->width);
_lookupIntValue(config, "height", &opts->height);
}
void GBAConfigMapGraphicsOpts(const struct Configuration* config, const char* port, struct GBAOptions* opts) {
_lookupIntValue(config, "fullscreen", port, &opts->fullscreen);
_lookupIntValue(config, "width", port, &opts->width);
_lookupIntValue(config, "height", port, &opts->height);
void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* opts) {
ConfigurationSetValue(&config->defaultsTable, 0, "bios", opts->bios);
ConfigurationSetIntValue(&config->defaultsTable, 0, "logLevel", opts->logLevel);
ConfigurationSetIntValue(&config->defaultsTable, 0, "frameskip", opts->frameskip);
ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferCapacity", opts->rewindBufferCapacity);
ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferInterval", opts->rewindBufferInterval);
ConfigurationSetFloatValue(&config->defaultsTable, 0, "fpsTarget", opts->fpsTarget);
ConfigurationSetUIntValue(&config->defaultsTable, 0, "audioBuffers", opts->audioBuffers);
ConfigurationSetIntValue(&config->defaultsTable, 0, "audioSync", opts->audioSync);
ConfigurationSetIntValue(&config->defaultsTable, 0, "videoSync", opts->videoSync);
ConfigurationSetIntValue(&config->defaultsTable, 0, "fullscreen", opts->fullscreen);
ConfigurationSetIntValue(&config->defaultsTable, 0, "width", opts->width);
ConfigurationSetIntValue(&config->defaultsTable, 0, "height", opts->height);
}
void GBAConfigFreeOpts(struct GBAOptions* opts) {

View File

@ -3,7 +3,13 @@
#include "util/common.h"
struct Configuration;
#include "util/configuration.h"
struct GBAConfig {
struct Configuration configTable;
struct Configuration defaultsTable;
char* port;
};
struct GBAOptions {
char* bios;
@ -22,10 +28,25 @@ struct GBAOptions {
bool audioSync;
};
bool GBAConfigLoad(struct Configuration*);
void GBAConfigInit(struct GBAConfig*, const char* port);
void GBAConfigDeinit(struct GBAConfig*);
void GBAConfigMapGeneralOpts(const struct Configuration*, const char* port, struct GBAOptions*);
void GBAConfigMapGraphicsOpts(const struct Configuration*, const char* port, struct GBAOptions*);
void GBAConfigFreeOpts(struct GBAOptions*);
bool GBAConfigLoad(struct GBAConfig*);
bool GBAConfigSave(const struct GBAConfig*);
void GBAConfigSetValue(struct GBAConfig*, const char* key, const char* value);
void GBAConfigSetIntValue(struct GBAConfig*, const char* key, int value);
void GBAConfigSetUIntValue(struct GBAConfig*, const char* key, unsigned value);
void GBAConfigSetFloatValue(struct GBAConfig*, const char* key, float value);
void GBAConfigSetDefaultValue(struct GBAConfig*, const char* key, const char* value);
void GBAConfigSetDefaultIntValue(struct GBAConfig*, const char* key, int value);
void GBAConfigSetDefaultUIntValue(struct GBAConfig*, const char* key, unsigned value);
void GBAConfigSetDefaultFloatValue(struct GBAConfig*, const char* key, float value);
void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts);
void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* opts);
void GBAConfigFreeOpts(struct GBAOptions* opts);
#endif

View File

@ -38,9 +38,9 @@ static const struct option _options[] = {
{ 0, 0, 0, 0 }
};
bool _parseGraphicsArg(struct SubParser* parser, struct GBAOptions* gbaOpts, int option, const char* arg);
bool _parseGraphicsArg(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg);
bool parseArguments(struct GBAArguments* opts, struct GBAOptions* gbaOpts, int argc, char* const* argv, struct SubParser* subparser) {
bool parseArguments(struct GBAArguments* opts, struct GBAConfig* config, int argc, char* const* argv, struct SubParser* subparser) {
int ch;
char options[64] =
"b:Dl:p:s:"
@ -58,10 +58,7 @@ bool parseArguments(struct GBAArguments* opts, struct GBAOptions* gbaOpts, int a
while ((ch = getopt_long(argc, argv, options, _options, 0)) != -1) {
switch (ch) {
case 'b':
if (gbaOpts->bios) {
free(gbaOpts->bios);
}
gbaOpts->bios = strdup(optarg);
GBAConfigSetDefaultValue(config, "bios", optarg);
break;
case 'D':
opts->dirmode = true;
@ -83,17 +80,17 @@ bool parseArguments(struct GBAArguments* opts, struct GBAOptions* gbaOpts, int a
break;
#endif
case 'l':
gbaOpts->logLevel = atoi(optarg);
GBAConfigSetDefaultValue(config, "logLevel", optarg);
break;
case 'p':
opts->patch = strdup(optarg);
break;
case 's':
gbaOpts->frameskip = atoi(optarg);
GBAConfigSetDefaultValue(config, "frameskip", optarg);
break;
default:
if (subparser) {
if (!subparser->parse(subparser, gbaOpts, ch, optarg)) {
if (!subparser->parse(subparser, config, ch, optarg)) {
return false;
}
}
@ -125,12 +122,12 @@ void initParserForGraphics(struct SubParser* parser, struct GraphicsOpts* opts)
opts->multiplier = 0;
}
bool _parseGraphicsArg(struct SubParser* parser, struct GBAOptions* gbaOpts, int option, const char* arg) {
bool _parseGraphicsArg(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg) {
UNUSED(arg);
struct GraphicsOpts* graphicsOpts = parser->opts;
switch (option) {
case 'f':
gbaOpts->fullscreen = 1;
GBAConfigSetDefaultIntValue(config, "fullscreen", 1);
return true;
case '1':
case '2':
@ -140,8 +137,8 @@ bool _parseGraphicsArg(struct SubParser* parser, struct GBAOptions* gbaOpts, int
return false;
}
graphicsOpts->multiplier = option - '0';
gbaOpts->width = VIDEO_HORIZONTAL_PIXELS * graphicsOpts->multiplier;
gbaOpts->height = VIDEO_VERTICAL_PIXELS * graphicsOpts->multiplier;
GBAConfigSetDefaultIntValue(config, "width", VIDEO_HORIZONTAL_PIXELS * graphicsOpts->multiplier);
GBAConfigSetDefaultIntValue(config, "height", VIDEO_VERTICAL_PIXELS * graphicsOpts->multiplier);
return true;
default:
return false;

View File

@ -27,7 +27,7 @@ struct GBAArguments {
struct SubParser {
const char* usage;
bool (*parse)(struct SubParser* parser, struct GBAOptions* gbaOpts, int option, const char* arg);
bool (*parse)(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg);
const char* extraOptions;
void* opts;
};
@ -36,7 +36,7 @@ struct GraphicsOpts {
int multiplier;
};
bool parseArguments(struct GBAArguments* opts, struct GBAOptions* gbaOpts, int argc, char* const* argv, struct SubParser* subparser);
bool parseArguments(struct GBAArguments* opts, struct GBAConfig* config, int argc, char* const* argv, struct SubParser* subparser);
void freeArguments(struct GBAArguments* opts);
void usage(const char* arg0, const char* extraOptions);

View File

@ -28,7 +28,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 GBAOptions* gbaOpts, int option, const char* arg);
static bool _parsePerfOpts(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg);
static struct GBAThread* _thread;
@ -46,10 +46,16 @@ int main(int argc, char** argv) {
.opts = &perfOpts
};
struct GBAConfig config;
GBAConfigInit(&config, 0);
struct GBAOptions opts = {};
struct GBAArguments args = {};
if (!parseArguments(&args, &opts, argc, argv, &subparser)) {
if (!parseArguments(&args, &config, argc, argv, &subparser)) {
usage(argv[0], PERF_USAGE);
freeArguments(&args);
GBAConfigFreeOpts(&opts);
GBAConfigDeinit(&config);
return 1;
}
@ -66,12 +72,12 @@ int main(int argc, char** argv) {
context.debugger = createDebugger(&args);
char gameCode[5] = { 0 };
GBAConfigMap(&config, &opts);
opts.audioSync = false;
opts.videoSync = false;
GBAMapArgumentsToContext(&args, &context);
GBAMapOptionsToContext(&opts, &context);
context.sync.audioWait = false;
context.sync.videoFrameWait = false;
GBAThreadStart(&context);
GBAGetGameCode(context.gba, gameCode);
@ -90,6 +96,7 @@ int main(int argc, char** argv) {
GBAThreadJoin(&context);
GBAConfigFreeOpts(&opts);
freeArguments(&args);
GBAConfigDeinit(&config);
free(context.debugger);
free(renderer.outputBuffer);
@ -153,8 +160,8 @@ static void _GBAPerfShutdown(int signal) {
pthread_mutex_unlock(&_thread->stateMutex);
}
static bool _parsePerfOpts(struct SubParser* parser, struct GBAOptions* gbaOpts, int option, const char* arg) {
UNUSED(gbaOpts);
static bool _parsePerfOpts(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg) {
UNUSED(config);
struct PerfOpts* opts = parser->opts;
errno = 0;
switch (option) {

View File

@ -16,24 +16,19 @@ GBAApp::GBAApp(int& argc, char* argv[])
QApplication::setApplicationName(PROJECT_NAME);
QApplication::setApplicationVersion(PROJECT_VERSION);
struct Configuration config;
ConfigurationInit(&config);
GBAConfigLoad(&config);
GBAConfigInit(&m_config, PORT);
GBAConfigLoad(&m_config);
m_opts.audioSync = GameController::AUDIO_SYNC;
m_opts.videoSync = GameController::VIDEO_SYNC;
GBAConfigLoadDefaults(&m_config, &m_opts);
GBAConfigMapGeneralOpts(&config, PORT, &m_opts);
GBAConfigMapGraphicsOpts(&config, PORT, &m_opts);
bool parsed = parseArguments(&m_args, &m_config, argc, argv, 0);
GBAConfigMap(&m_config, &m_opts);
m_window.setOptions(&m_opts);
ConfigurationDeinit(&config);
if (parseArguments(&m_args, &m_opts, argc, argv, 0)) {
m_window.setOptions(&m_opts);
if (parsed) {
m_window.argumentsPassed(&m_args);
} else {
m_window.setOptions(&m_opts);
}
m_window.show();
@ -42,6 +37,7 @@ GBAApp::GBAApp(int& argc, char* argv[])
GBAApp::~GBAApp() {
freeArguments(&m_args);
GBAConfigFreeOpts(&m_opts);
GBAConfigDeinit(&m_config);
}
bool GBAApp::event(QEvent* event) {

View File

@ -29,7 +29,7 @@ private:
GBAArguments m_args;
GBAOptions m_opts;
Configuration m_config;
GBAConfig m_config;
};
}

View File

@ -65,8 +65,8 @@ int main(int argc, char** argv) {
struct GLSoftwareRenderer renderer;
GBAVideoSoftwareRendererCreate(&renderer.d);
struct Configuration config;
ConfigurationInit(&config);
struct GBAConfig config;
GBAConfigInit(&config, PORT);
GBAConfigLoad(&config);
struct GBAOptions opts = {
@ -74,19 +74,21 @@ int main(int argc, char** argv) {
.videoSync = false,
.audioSync = true,
};
GBAConfigLoadDefaults(&config, &opts);
struct GBAArguments args = {};
struct GraphicsOpts graphicsOpts = {};
struct SubParser subparser;
GBAConfigMapGeneralOpts(&config, PORT, &opts);
GBAConfigMapGraphicsOpts(&config, PORT, &opts);
GBAConfigMap(&config, &opts);
initParserForGraphics(&subparser, &graphicsOpts);
if (!parseArguments(&args, &opts, argc, argv, &subparser)) {
if (!parseArguments(&args, &config, argc, argv, &subparser)) {
usage(argv[0], subparser.usage);
freeArguments(&args);
GBAConfigFreeOpts(&opts);
GBAConfigDeinit(&config);
return 1;
}
@ -100,6 +102,7 @@ int main(int argc, char** argv) {
if (!_GBASDLInit(&renderer)) {
freeArguments(&args);
GBAConfigFreeOpts(&opts);
GBAConfigDeinit(&config);
return 1;
}
@ -120,7 +123,7 @@ int main(int argc, char** argv) {
renderer.events.bindings = &context.inputMap;
GBASDLInitEvents(&renderer.events);
GBASDLEventsLoadConfig(&renderer.events, &config);
GBASDLEventsLoadConfig(&renderer.events, &config.configTable); // TODO: Don't use this directly
GBAThreadStart(&context);
@ -129,6 +132,7 @@ int main(int argc, char** argv) {
GBAThreadJoin(&context);
freeArguments(&args);
GBAConfigFreeOpts(&opts);
GBAConfigDeinit(&config);
free(context.debugger);
_GBASDLDeinit(&renderer);