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}