#include "gba-config.h" #include "platform/commandline.h" #define SECTION_NAME_MAX 128 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; } } 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 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 GBAConfig* config, const char* key, int* out) { const char* charValue = _lookupValue(config, key); if (!charValue) { return false; } char* end; long value = strtol(charValue, &end, 10); if (*end) { return false; } *out = value; return true; } static bool _lookupUIntValue(const struct GBAConfig* config, const char* key, unsigned* out) { const char* charValue = _lookupValue(config, key); if (!charValue) { return false; } char* end; unsigned long value = strtoul(charValue, &end, 10); if (*end) { return false; } *out = value; return true; } static bool _lookupFloatValue(const struct GBAConfig* config, const char* key, float* out) { const char* charValue = _lookupValue(config, key); if (!charValue) { return false; } char* end; float value = strtof(charValue, &end); if (*end) { return false; } *out = value; return true; } 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 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", &audioBuffers)) { opts->audioBuffers = audioBuffers; } int fakeBool; if (_lookupIntValue(config, "audioSync", &fakeBool)) { opts->audioSync = 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 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) { free(opts->bios); opts->bios = 0; }