all repos — mgba @ 938c9e965d14e6867f165b3be3391b0c15484bf5

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