Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-2-2013-Decompilation
Path: blob/main/RSDKv4/Ini.cpp
817 views
1
#include "RetroEngine.hpp"
2
#if !RETRO_USE_ORIGINAL_CODE
3
#include <stdlib.h>
4
#include <algorithm>
5
#include <string>
6
7
int strncmp(char const *a, char const *b)
8
{
9
for (;; a++, b++) {
10
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
11
if (d != 0 || !*a)
12
return d;
13
}
14
}
15
16
IniParser::IniParser(const char *filename, bool addPath)
17
{
18
items.clear();
19
char buf[0x100];
20
char section[0x40];
21
bool hasSection = false;
22
char key[0x100];
23
char value[0x100];
24
25
char pathBuffer[0x80];
26
27
if (addPath) {
28
#if RETRO_PLATFORM == RETRO_UWP
29
if (!usingCWD)
30
sprintf(pathBuffer, "%s/%s", getResourcesPath(), filename);
31
else
32
sprintf(pathBuffer, "%s", filename);
33
#elif RETRO_PLATFORM == RETRO_OSX
34
sprintf(pathBuffer, "%s/%s", gamePath, filename);
35
#else
36
sprintf(pathBuffer, "%s", filename);
37
#endif
38
}
39
else {
40
sprintf(pathBuffer, "%s", filename);
41
}
42
43
FileIO *f;
44
if ((f = fOpen(pathBuffer, "r")) == NULL) {
45
PrintLog("ERROR: Couldn't open file '%s'!", filename);
46
return;
47
}
48
49
while (true) {
50
bool flag = false;
51
int ret = 0;
52
int strLen = 0;
53
while (true) {
54
ret = (int)fRead(&buf[strLen++], sizeof(byte), 1, f);
55
flag = ret == 0;
56
if (ret == 0) {
57
strLen--;
58
break;
59
}
60
if (buf[strLen - 1] == '\n')
61
break;
62
}
63
buf[strLen] = 0;
64
if (buf[0] == '#')
65
continue;
66
67
if (sscanf(buf, "[%[^][]]", section) == 1) {
68
hasSection = true;
69
}
70
else if (sscanf(buf, "%[^;=]= %[^\t\r\n]", key, value) == 2 || sscanf(buf, "%[^;=]=%[^\t\r\n]", key, value) == 2
71
|| sscanf(buf, "%[^;=] = %[^\t\r\n]", key, value) == 2 || sscanf(buf, "%[^;=] =%[^\t\r\n]", key, value) == 2) {
72
ConfigItem item;
73
if (hasSection)
74
sprintf(item.section, "%s", section);
75
else
76
sprintf(item.section, "");
77
78
sprintf(item.key, "%s", key);
79
sprintf(item.value, "%s", value);
80
item.hasSection = hasSection;
81
items.push_back(item);
82
}
83
if (flag)
84
break;
85
}
86
87
fClose(f);
88
}
89
90
int IniParser::GetString(const char *section, const char *key, char *dest)
91
{
92
if (items.size() == 0)
93
return 0;
94
95
for (int x = 0; x < items.size(); x++) {
96
if (!strcmp(section, items[x].section)) {
97
if (!strcmp(key, items[x].key)) {
98
strcpy(dest, items[x].value);
99
return 1;
100
}
101
}
102
}
103
104
return 0;
105
}
106
int IniParser::GetInteger(const char *section, const char *key, int *dest)
107
{
108
if (items.size() == 0)
109
return 0;
110
111
for (int x = 0; x < items.size(); x++) {
112
if (!strcmp(section, items[x].section)) {
113
if (!strcmp(key, items[x].key)) {
114
*dest = atoi(items[x].value);
115
return 1;
116
}
117
}
118
}
119
120
return 0;
121
}
122
int IniParser::GetFloat(const char *section, const char *key, float *dest)
123
{
124
if (items.size() == 0)
125
return 0;
126
127
for (int x = 0; x < items.size(); x++) {
128
if (!strcmp(section, items[x].section)) {
129
if (!strcmp(key, items[x].key)) {
130
*dest = atof(items[x].value);
131
return 1;
132
}
133
}
134
}
135
136
return 0;
137
}
138
int IniParser::GetBool(const char *section, const char *key, bool *dest)
139
{
140
if (items.size() == 0)
141
return 0;
142
143
for (int x = 0; x < items.size(); x++) {
144
if (!strcmp(section, items[x].section)) {
145
if (!strcmp(key, items[x].key)) {
146
*dest = !strncmp(items[x].value, "true") || !strcmp(items[x].value, "1");
147
return 1;
148
}
149
}
150
}
151
152
return 0;
153
}
154
155
int IniParser::SetString(const char *section, const char *key, char *value)
156
{
157
int where = -1;
158
for (int x = 0; x < items.size(); x++) {
159
if (strcmp(section, items[x].section) == 0) {
160
if (strcmp(key, items[x].key) == 0) {
161
where = x;
162
break;
163
}
164
}
165
}
166
if (where < 0) {
167
where = (int)items.size();
168
items.push_back(ConfigItem());
169
}
170
171
strcpy(items[where].section, section);
172
strcpy(items[where].key, key);
173
strcpy(items[where].value, value);
174
items[where].type = INI_ITEM_STRING;
175
return 1;
176
}
177
int IniParser::SetInteger(const char *section, const char *key, int value)
178
{
179
int where = -1;
180
for (int x = 0; x < items.size(); x++) {
181
if (strcmp(section, items[x].section) == 0) {
182
if (strcmp(key, items[x].key) == 0) {
183
where = x;
184
break;
185
}
186
}
187
}
188
if (where < 0) {
189
where = (int)items.size();
190
items.push_back(ConfigItem());
191
}
192
193
strcpy(items[where].section, section);
194
strcpy(items[where].key, key);
195
sprintf(items[where].value, "%d", value);
196
items[where].type = INI_ITEM_INT;
197
return 1;
198
}
199
int IniParser::SetFloat(const char *section, const char *key, float value)
200
{
201
int where = -1;
202
for (int x = 0; x < items.size(); x++) {
203
if (strcmp(section, items[x].section) == 0) {
204
if (strcmp(key, items[x].key) == 0) {
205
where = x;
206
break;
207
}
208
}
209
}
210
if (where < 0) {
211
where = (int)items.size();
212
items.push_back(ConfigItem());
213
}
214
215
strcpy(items[where].section, section);
216
strcpy(items[where].key, key);
217
sprintf(items[where].value, "%f", value);
218
items[where].type = INI_ITEM_FLOAT;
219
return 1;
220
}
221
int IniParser::SetBool(const char *section, const char *key, bool value)
222
{
223
int where = -1;
224
for (int x = 0; x < items.size(); x++) {
225
if (strcmp(section, items[x].section) == 0) {
226
if (strcmp(key, items[x].key) == 0) {
227
where = x;
228
break;
229
}
230
}
231
}
232
if (where < 0) {
233
where = (int)items.size();
234
items.push_back(ConfigItem());
235
}
236
237
strcpy(items[where].section, section);
238
strcpy(items[where].key, key);
239
sprintf(items[where].value, "%s", value ? "true" : "false");
240
items[where].type = INI_ITEM_BOOL;
241
return 1;
242
}
243
int IniParser::SetComment(const char *section, const char *key, const char *comment)
244
{
245
int where = -1;
246
for (int x = 0; x < items.size(); x++) {
247
if (strcmp(section, items[x].section) == 0) {
248
if (strcmp(key, items[x].key) == 0) {
249
where = x;
250
break;
251
}
252
}
253
}
254
if (where < 0) {
255
where = (int)items.size();
256
items.push_back(ConfigItem());
257
}
258
259
strcpy(items[where].section, section);
260
strcpy(items[where].key, key);
261
sprintf(items[where].value, "%s", comment);
262
items[where].type = INI_ITEM_COMMENT;
263
return 1;
264
}
265
266
void IniParser::Write(const char *filename, bool addPath)
267
{
268
char pathBuffer[0x80];
269
270
if (addPath) {
271
#if RETRO_PLATFORM == RETRO_UWP
272
if (!usingCWD)
273
sprintf(pathBuffer, "%s/%s", getResourcesPath(), filename);
274
else
275
sprintf(pathBuffer, "%s", filename);
276
#elif RETRO_PLATFORM == RETRO_OSX
277
sprintf(pathBuffer, "%s/%s", gamePath, filename);
278
#else
279
sprintf(pathBuffer, "%s", filename);
280
#endif
281
}
282
else {
283
sprintf(pathBuffer, "%s", filename);
284
}
285
286
FileIO *f;
287
if ((f = fOpen(pathBuffer, "w")) == NULL) {
288
PrintLog("ERROR: Couldn't open file '%s' for writing!", filename);
289
return;
290
}
291
292
char sections[10][60];
293
char past[60];
294
int c = 0;
295
sprintf(past, "");
296
for (int i = 0; i < items.size(); ++i) {
297
if (std::find(std::begin(sections), std::end(sections), items[i].section) == std::end(sections) && strcmp(past, items[i].section) != 0) {
298
sprintf(past, "%s", items[i].section);
299
sprintf(sections[c], "%s", items[i].section);
300
c++;
301
}
302
}
303
304
if (c > 1) {
305
if (strcmp(sections[0], sections[c - 1]) == 0)
306
c--;
307
}
308
309
char buffer[0x100];
310
311
// Sectionless items
312
for (int i = 0; i < items.size(); ++i) {
313
if (strcmp("", items[i].section) == 0) {
314
switch (items[i].type) {
315
default:
316
case INI_ITEM_STRING:
317
case INI_ITEM_INT:
318
case INI_ITEM_FLOAT:
319
case INI_ITEM_BOOL:
320
sprintf(buffer, "%s=%s\n", items[i].key, items[i].value);
321
fWrite(&buffer, 1, StrLength(buffer), f);
322
break;
323
case INI_ITEM_COMMENT:
324
sprintf(buffer, "; %s\n", items[i].value);
325
fWrite(&buffer, 1, StrLength(buffer), f);
326
break;
327
}
328
}
329
}
330
sprintf(buffer, "\n");
331
fWrite(&buffer, StrLength(buffer), 1, f);
332
333
// Sections
334
for (int s = 0; s < c; ++s) {
335
sprintf(buffer, "[%s]\n", sections[s]);
336
fWrite(&buffer, 1, StrLength(buffer), f);
337
for (int i = 0; i < items.size(); ++i) {
338
if (strcmp(sections[s], items[i].section) == 0) {
339
switch (items[i].type) {
340
default:
341
case INI_ITEM_STRING:
342
case INI_ITEM_INT:
343
case INI_ITEM_FLOAT:
344
case INI_ITEM_BOOL:
345
sprintf(buffer, "%s=%s\n", items[i].key, items[i].value);
346
fWrite(&buffer, 1, StrLength(buffer), f);
347
break;
348
case INI_ITEM_COMMENT:
349
sprintf(buffer, "; %s\n", items[i].value);
350
fWrite(&buffer, 1, StrLength(buffer), f);
351
break;
352
}
353
}
354
}
355
356
if (s + 1 < c) {
357
sprintf(buffer, "\n");
358
fWrite(&buffer, StrLength(buffer), 1, f);
359
}
360
}
361
362
fClose(f);
363
}
364
#endif
365
366