all repos — mgba @ 8fc39428913b7695c59e642e5a889bc97236b4b7

mGBA Game Boy Advance Emulator

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

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