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}