Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/Ini.cpp
2 views
1
/*
2
* Glide64 - Glide video plugin for Nintendo 64 emulators.
3
* Copyright (c) 2002 Dave2001
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public
16
* Licence along with this program; if not, write to the Free
17
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
* Boston, MA 02110-1301, USA
19
*/
20
21
//****************************************************************
22
//
23
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
24
// Project started on December 29th, 2001
25
//
26
// To modify Glide64:
27
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
28
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
29
//
30
// Official Glide64 development channel: #Glide64 on EFnet
31
//
32
// Original author: Dave2001 ([email protected])
33
// Other authors: Gonetz, Gugaman
34
//
35
//****************************************************************
36
37
// INI code v1.1
38
39
#define M64P_PLUGIN_PROTOTYPES 1
40
#include "m64p_types.h"
41
#include "m64p_plugin.h"
42
#include "m64p_config.h"
43
#include "m64p_vidext.h"
44
#include "Ini.h"
45
#include "Gfx1.3.h"
46
#include <limits.h>
47
#ifndef _WIN32
48
#include <unistd.h>
49
#include <string.h>
50
#include <dirent.h>
51
#include <stdlib.h>
52
#endif // _WIN32
53
54
#include <errno.h>
55
#ifndef _WIN32
56
#include <sys/resource.h>
57
#endif
58
59
#ifdef _WIN32
60
#define PATH_MAX _MAX_PATH
61
#endif
62
63
/* PATH_MAX only may be defined by limits.h */
64
#ifndef PATH_MAX
65
#define PATH_MAX 4096
66
#endif
67
68
FILE *ini;
69
int sectionstart;
70
int last_line; // last good line
71
int last_line_ret; // last line ended in return?
72
WORD cr = 0x0A0D;
73
static char configdir[PATH_MAX] = {0};
74
75
BOOL INI_Open ()
76
{
77
// Get the path of the dll, ex: C:\Games\Project64\Plugin\Glide64.dll
78
char path[PATH_MAX];
79
if(strlen(configdir) > 0)
80
{
81
strncpy(path, configdir, PATH_MAX);
82
// make sure there's a trailing '/'
83
//if(path[strlen(path)-1] != '/')
84
// strncat(path, "/", PATH_MAX - strlen(path));
85
}
86
else
87
{
88
#ifdef _WIN32
89
GetModuleFileName (hInstance, path, PATH_MAX);
90
#else // _WIN32
91
# ifdef __FreeBSD__
92
int n = readlink("/proc/curproc/files", path, PATH_MAX);
93
#else
94
int n = readlink("/proc/self/exe", path, PATH_MAX);
95
#endif
96
if (n == -1) strcpy(path, "./");
97
else
98
{
99
char path2[PATH_MAX];
100
int i;
101
102
path[n] = '\0';
103
strcpy(path2, path);
104
for (i=strlen(path2)-1; i>0; i--)
105
{
106
if(path2[i] == '/') break;
107
}
108
if(i == 0) strcpy(path, "./");
109
else
110
{
111
DIR *dir;
112
struct dirent *entry;
113
int gooddir = 0;
114
115
path2[i+1] = '\0';
116
dir = opendir(path2);
117
while((entry = readdir(dir)) != NULL)
118
{
119
if(!strcmp(entry->d_name, "plugins"))
120
gooddir = 1;
121
}
122
closedir(dir);
123
if(!gooddir) strcpy(path, "./");
124
}
125
}
126
127
#endif // _WIN32
128
129
// Find the previous backslash
130
int i;
131
for (i=strlen(path)-1; i>0; i--)
132
{
133
#ifdef _WIN32
134
if (path[i] == '\\')
135
#else // _WIN32
136
if (path[i] == '/')
137
#endif // _WIN32
138
break;
139
}
140
if (path == 0) return FALSE;
141
path[i+1] = 0;
142
143
#ifndef _WIN32
144
strcat(path, "plugins/");
145
#endif // _WIN32
146
}
147
148
//strncat (path, "Glide64.ini", PATH_MAX - strlen(path));
149
WriteLog(M64MSG_INFO, "opening %s\n", path);
150
// Open the file
151
ini = fopen (path, "rb");
152
if (ini == NULL)
153
{
154
WriteLog(M64MSG_ERROR, "Could not find Glide64.ini!");
155
return FALSE;
156
/*
157
ini = fopen (path, "w+b");
158
if (ini == NULL)
159
{
160
return FALSE;
161
}
162
*/
163
}
164
165
sectionstart = 0;
166
last_line = 0;
167
last_line_ret = 1;
168
169
return TRUE;
170
}
171
172
void INI_Close ()
173
{
174
//if (ini)
175
// fclose(ini);
176
}
177
178
void INI_InsertSpace(int space)
179
{
180
// Since there is no good way to normally insert to or delete from a certain location in
181
// a file, this function was added. It will insert (or delete) space bytes at the
182
// current location.
183
184
// note: negative count means delete
185
char chunk[2048];
186
int len, file, start_pos, cur_pos;
187
188
#ifdef _WIN32
189
file = _fileno(ini);
190
#else // _WIN32
191
file = fileno(ini);
192
#endif // _WIN32
193
194
start_pos = ftell(ini);
195
fseek(ini,0,SEEK_END);
196
197
// if adding, extend the file
198
if (space > 0)
199
#ifdef _WIN32
200
_chsize (file, _filelength(file)+space);
201
#else // _WIN32
202
{
203
int t1 = ftell(ini);
204
fseek(ini, 0L, SEEK_END);
205
int t2 = ftell(ini);
206
fseek(ini, t1, SEEK_SET);
207
ftruncate(file, t2+space);
208
}
209
#endif // _WIN32
210
211
while (1) {
212
cur_pos = ftell(ini);
213
len = cur_pos - start_pos;
214
if (len == 0) break;
215
if (len > 2048) len = 2048;
216
217
fseek (ini,-len,SEEK_CUR);
218
fread (chunk,1,len,ini);
219
fseek (ini,-len+space,SEEK_CUR);
220
fwrite (chunk,1,len,ini);
221
fseek (ini,-len-space,SEEK_CUR);
222
}
223
224
// if deleted, make the file shorter
225
if (space < 0)
226
#ifdef _WIN32
227
_chsize (file, _filelength(file)+space);
228
#else // _WIN32
229
{
230
int t1 = ftell(ini);
231
fseek(ini, 0L, SEEK_END);
232
int t2 = ftell(ini);
233
fseek(ini, t1, SEEK_SET);
234
ftruncate(file, t2+space);
235
}
236
#endif // _WIN32
237
}
238
239
BOOL INI_FindSection (const char *sectionname, BOOL create)
240
{
241
if (ini == NULL)
242
return FALSE;
243
244
char line[256], section[64];
245
char *p;
246
int i, sectionfound, ret;
247
248
rewind (ini);
249
250
last_line = 0;
251
sectionfound = 0;
252
253
while(!feof(ini)) {
254
ret = 0;
255
*line=0;
256
fgets(line,255,ini);
257
258
// remove enter
259
i=strlen(line);
260
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
261
// with just EOL), it would write into line[-1]
262
if(i>=1 && line[i-1]==0xa) {
263
ret=1;
264
line[i-1]=0;
265
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
266
}
267
268
// remove comments
269
p=line;
270
while(*p)
271
{
272
if (p[0]=='/' && p[1]=='/')
273
{
274
p[0]=0;
275
break;
276
}
277
p++;
278
}
279
280
// skip starting space
281
p=line;
282
while(*p<=' ' && *p) p++;
283
284
// empty line
285
if(!*p) continue;
286
287
last_line=ftell(ini); // where to add if not found
288
last_line_ret = ret;
289
290
if(*p!='[') continue;
291
292
p++;
293
for (i=0;i<63;i++)
294
{
295
if(*p==']' || !*p) break;
296
section[i]=*p++;
297
}
298
section[i]=0;
299
300
#ifdef _WIN32
301
if(!stricmp(section,sectionname))
302
#else // _WIN32
303
if (!strcasecmp(section,sectionname))
304
#endif // _WIN32
305
{
306
sectionstart=ftell(ini);
307
sectionfound=1;
308
return TRUE;
309
}
310
}
311
312
if (!sectionfound && create)
313
{
314
// create the section
315
fseek(ini,last_line,SEEK_SET);
316
INI_InsertSpace ((!last_line_ret) * 2 + 6 + strlen(sectionname));
317
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
318
fwrite (&cr, 1, 2, ini);
319
sprintf (section, "[%s]", sectionname);
320
fwrite (section, 1, strlen(section), ini);
321
fwrite (&cr, 1, 2, ini);
322
sectionstart = ftell(ini);
323
last_line = sectionstart;
324
last_line_ret = 1;
325
return TRUE;
326
}
327
328
return FALSE;
329
}
330
331
// Reads the value of item 'itemname' as a string.
332
const char *INI_ReadString (const char *itemname, char *value, const char *def_value, BOOL create)
333
{
334
char line[256], name[64];
335
char *p, *n;
336
int ret, i;
337
*value = 0;
338
339
fseek(ini,sectionstart,SEEK_SET);
340
341
while(!feof(ini)) {
342
ret = 0;
343
*line=0;
344
fgets(line,255,ini);
345
346
// remove enter
347
i=strlen(line);
348
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
349
// with just EOL), it would write into line[-1]
350
// OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0;
351
if(i>=1 && line[i-1]==0xa) {
352
ret=1;
353
line[i-1]=0;
354
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
355
}
356
357
// remove comments
358
p=line;
359
while(*p)
360
{
361
if (p[0]==';')
362
{
363
p[0]=0;
364
break;
365
}
366
p++;
367
}
368
369
// skip starting space
370
p=line;
371
while(*p<=' ' && *p) p++;
372
373
// empty line
374
if(!*p) continue;
375
376
// new section
377
if(*p=='[') break;
378
379
last_line=ftell(ini); // where to add if not found
380
last_line_ret = ret;
381
382
// read name
383
n = name;
384
while(*p && *p!='=' && *p>' ') *n++ = *p++;
385
*n = 0;
386
387
#ifdef _WIN32
388
if(!stricmp(name,itemname))
389
#else // _WIN32
390
if(!strcasecmp(name,itemname))
391
#endif // _WIN32
392
{
393
// skip spaces/equal sign
394
while(*p<=' ' || *p=='=') p++;
395
396
// read value
397
n = value;
398
while(*p) *n++ = *p++;
399
400
// remove trailing spaces
401
while (*(n-1) == ' ') n--;
402
403
*n=0;
404
405
return value;
406
}
407
}
408
409
// uh-oh, not found. we need to create
410
if (create)
411
{
412
fseek(ini,last_line,SEEK_SET);
413
INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(def_value) + 5);
414
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
415
sprintf (line, "%s = %s", itemname, def_value);
416
fwrite (line, 1, strlen(line), ini);
417
fwrite (&cr, 1, 2, ini);
418
last_line = ftell(ini);
419
last_line_ret = 1;
420
}
421
422
strcpy (value, def_value);
423
return value;
424
}
425
426
// Reads the value of item 'itemname' as a string.
427
void INI_WriteString (const char *itemname, const char *value)
428
{
429
char line[256], name[64];
430
char *p, *n;
431
int ret, i;
432
433
fseek(ini,sectionstart,SEEK_SET);
434
435
while(!feof(ini)) {
436
ret = 0;
437
*line=0;
438
fgets(line,255,ini);
439
440
// remove enter
441
i=strlen(line);
442
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
443
// with just EOL), it would write into line[-1]
444
// OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0;
445
if(i>=1 && line[i-1]==0xa) {
446
ret=1;
447
line[i-1]=0;
448
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
449
}
450
451
// remove comments
452
p=line;
453
while(*p)
454
{
455
if (p[0]=='/' && p[1]=='/')
456
{
457
p[0]=0;
458
break;
459
}
460
p++;
461
}
462
463
// skip starting space
464
p=line;
465
while(*p<=' ' && *p) p++;
466
467
// empty line
468
if(!*p) continue;
469
470
// new section
471
if(*p=='[') break;
472
473
last_line=ftell(ini); // where to add if not found
474
last_line_ret = ret;
475
476
// read name
477
n = name;
478
while(*p && *p!='=' && *p>' ') *n++ = *p++;
479
*n = 0;
480
481
#ifdef _WIN32
482
if(!stricmp(name,itemname))
483
#else // _WIN32
484
if(!strcasecmp(name,itemname))
485
#endif // _WIN32
486
{
487
INI_InsertSpace (-i + (strlen(itemname) + strlen(value) + 5));
488
sprintf (line, "%s = %s", itemname, value);
489
fseek (ini, -i, SEEK_CUR);
490
fwrite (line, 1, strlen(line), ini);
491
fwrite (&cr, 1, 2, ini);
492
last_line = ftell(ini);
493
last_line_ret = 1;
494
return;
495
}
496
}
497
498
// uh-oh, not found. we need to create
499
fseek(ini,last_line,SEEK_SET);
500
INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(value) + 5);
501
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
502
sprintf (line, "%s = %s", itemname, value);
503
fwrite (line, 1, strlen(line), ini);
504
fwrite (&cr, 1, 2, ini);
505
last_line = ftell(ini);
506
last_line_ret = 1;
507
return;
508
}
509
510
int INI_ReadInt (const char *itemname, int def_value, BOOL create)
511
{
512
if (ini == NULL)
513
return def_value;
514
515
char value[64], def[64];
516
#ifdef _WIN32
517
_itoa (def_value, def, 10);
518
#else // _WIN32
519
sprintf(def, "%d", def_value);
520
#endif // _WIN32
521
INI_ReadString (itemname, value, def, create);
522
return atoi (value);
523
}
524
525
void INI_WriteInt (const char *itemname, int value)
526
{
527
char valstr[64];
528
#ifdef _WIN32
529
_itoa (value, valstr, 10);
530
#else // _WIN32
531
sprintf(valstr, "%d", value);
532
#endif // _WIN32
533
INI_WriteString (itemname, valstr);
534
}
535
536
void SetConfigDir( const char *configDir )
537
{
538
strncpy(configdir, configDir, PATH_MAX);
539
}
540
541
542