all repos — mgba @ 9f5df2a6f2cc5fe0e7bdf478d7882e11c8dc8faa

mGBA Game Boy Advance Emulator

src/gba/gba-config.c (view raw)

  1#include "gba-config.h"
  2
  3#include "platform/commandline.h"
  4
  5#include <sys/stat.h>
  6
  7#define SECTION_NAME_MAX 128
  8
  9static const char* _lookupValue(const struct GBAConfig* config, const char* key) {
 10	const char* value;
 11	if (config->port) {
 12		value = ConfigurationGetValue(&config->configTable, config->port, key);
 13		if (value) {
 14			return value;
 15		}
 16	}
 17	value = ConfigurationGetValue(&config->configTable, 0, key);
 18	if (value) {
 19		return value;
 20	}
 21	if (config->port) {
 22		value = ConfigurationGetValue(&config->defaultsTable, config->port, key);
 23		if (value) {
 24			return value;
 25		}
 26	}
 27	return ConfigurationGetValue(&config->defaultsTable, 0, key);
 28}
 29
 30static bool _lookupCharValue(const struct GBAConfig* config, const char* key, char** out) {
 31	const char* value = _lookupValue(config, key);
 32	if (!value) {
 33		return false;
 34	}
 35	if (*out) {
 36		free(*out);
 37	}
 38	*out = strdup(value);
 39	return true;
 40}
 41
 42static bool _lookupIntValue(const struct GBAConfig* config, const char* key, int* out) {
 43	const char* charValue = _lookupValue(config, key);
 44	if (!charValue) {
 45		return false;
 46	}
 47	char* end;
 48	long value = strtol(charValue, &end, 10);
 49	if (*end) {
 50		return false;
 51	}
 52	*out = value;
 53	return true;
 54}
 55
 56static bool _lookupUIntValue(const struct GBAConfig* config, const char* key, unsigned* out) {
 57	const char* charValue = _lookupValue(config, key);
 58	if (!charValue) {
 59		return false;
 60	}
 61	char* end;
 62	unsigned long value = strtoul(charValue, &end, 10);
 63	if (*end) {
 64		return false;
 65	}
 66	*out = value;
 67	return true;
 68}
 69
 70static bool _lookupFloatValue(const struct GBAConfig* config, const char* key, float* out) {
 71	const char* charValue = _lookupValue(config, key);
 72	if (!charValue) {
 73		return false;
 74	}
 75	char* end;
 76	float value = strtof(charValue, &end);
 77	if (*end) {
 78		return false;
 79	}
 80	*out = value;
 81	return true;
 82}
 83
 84void GBAConfigInit(struct GBAConfig* config, const char* port) {
 85	ConfigurationInit(&config->configTable);
 86	ConfigurationInit(&config->defaultsTable);
 87	config->port = malloc(strlen("ports.") + strlen(port) + 1);
 88	sprintf(config->port, "ports.%s", port);
 89}
 90
 91void GBAConfigDeinit(struct GBAConfig* config) {
 92	ConfigurationDeinit(&config->configTable);
 93	ConfigurationDeinit(&config->defaultsTable);
 94	free(config->port);
 95}
 96
 97bool GBAConfigLoad(struct GBAConfig* config) {
 98	char path[PATH_MAX];
 99	char* home = getenv("HOME");
100	snprintf(path, PATH_MAX, "%s/.config/%s/config.ini", home, BINARY_NAME);
101	return ConfigurationRead(&config->configTable, path);
102}
103
104bool GBAConfigSave(const struct GBAConfig* config) {
105	// TODO: Support Windows; move to common code
106	char path[PATH_MAX];
107	char* home = getenv("HOME");
108	snprintf(path, PATH_MAX, "%s/.config", home);
109	mkdir(path, 0755);
110	snprintf(path, PATH_MAX, "%s/.config/%s", home, BINARY_NAME);
111	mkdir(path, 0755);
112	snprintf(path, PATH_MAX, "%s/.config/%s/config.ini", home, BINARY_NAME);
113	return ConfigurationWrite(&config->configTable, path);
114}
115
116const char* GBAConfigGetValue(const struct GBAConfig* config, const char* key) {
117	return _lookupValue(config, key);
118}
119
120void GBAConfigSetValue(struct GBAConfig* config, const char* key, const char* value) {
121	ConfigurationSetValue(&config->configTable, config->port, key, value);
122}
123
124void GBAConfigSetIntValue(struct GBAConfig* config, const char* key, int value) {
125	ConfigurationSetIntValue(&config->configTable, config->port, key, value);
126}
127
128void GBAConfigSetUIntValue(struct GBAConfig* config, const char* key, unsigned value) {
129	ConfigurationSetUIntValue(&config->configTable, config->port, key, value);
130}
131
132void GBAConfigSetFloatValue(struct GBAConfig* config, const char* key, float value) {
133	ConfigurationSetFloatValue(&config->configTable, config->port, key, value);
134}
135
136void GBAConfigSetDefaultValue(struct GBAConfig* config, const char* key, const char* value) {
137	ConfigurationSetValue(&config->defaultsTable, config->port, key, value);
138}
139
140void GBAConfigSetDefaultIntValue(struct GBAConfig* config, const char* key, int value) {
141	ConfigurationSetIntValue(&config->defaultsTable, config->port, key, value);
142}
143
144void GBAConfigSetDefaultUIntValue(struct GBAConfig* config, const char* key, unsigned value) {
145	ConfigurationSetUIntValue(&config->defaultsTable, config->port, key, value);
146}
147
148void GBAConfigSetDefaultFloatValue(struct GBAConfig* config, const char* key, float value) {
149	ConfigurationSetFloatValue(&config->defaultsTable, config->port, key, value);
150}
151
152void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) {
153	_lookupCharValue(config, "bios", &opts->bios);
154	_lookupIntValue(config, "logLevel", &opts->logLevel);
155	_lookupIntValue(config, "frameskip", &opts->frameskip);
156	_lookupIntValue(config, "rewindBufferCapacity", &opts->rewindBufferCapacity);
157	_lookupIntValue(config, "rewindBufferInterval", &opts->rewindBufferInterval);
158	_lookupFloatValue(config, "fpsTarget", &opts->fpsTarget);
159	unsigned audioBuffers;
160	if (_lookupUIntValue(config, "audioBuffers", &audioBuffers)) {
161		opts->audioBuffers = audioBuffers;
162	}
163
164	int fakeBool;
165	if (_lookupIntValue(config, "audioSync", &fakeBool)) {
166		opts->audioSync = fakeBool;
167	}
168	if (_lookupIntValue(config, "videoSync", &fakeBool)) {
169		opts->videoSync = fakeBool;
170	}
171
172	_lookupIntValue(config, "fullscreen", &opts->fullscreen);
173	_lookupIntValue(config, "width", &opts->width);
174	_lookupIntValue(config, "height", &opts->height);
175}
176
177void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* opts) {
178	ConfigurationSetValue(&config->defaultsTable, 0, "bios", opts->bios);
179	ConfigurationSetIntValue(&config->defaultsTable, 0, "logLevel", opts->logLevel);
180	ConfigurationSetIntValue(&config->defaultsTable, 0, "frameskip", opts->frameskip);
181	ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferCapacity", opts->rewindBufferCapacity);
182	ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferInterval", opts->rewindBufferInterval);
183	ConfigurationSetFloatValue(&config->defaultsTable, 0, "fpsTarget", opts->fpsTarget);
184	ConfigurationSetUIntValue(&config->defaultsTable, 0, "audioBuffers", opts->audioBuffers);
185	ConfigurationSetIntValue(&config->defaultsTable, 0, "audioSync", opts->audioSync);
186	ConfigurationSetIntValue(&config->defaultsTable, 0, "videoSync", opts->videoSync);
187	ConfigurationSetIntValue(&config->defaultsTable, 0, "fullscreen", opts->fullscreen);
188	ConfigurationSetIntValue(&config->defaultsTable, 0, "width", opts->width);
189	ConfigurationSetIntValue(&config->defaultsTable, 0, "height", opts->height);
190}
191
192void GBAConfigFreeOpts(struct GBAOptions* opts) {
193	free(opts->bios);
194	opts->bios = 0;
195}