annotate config.c @ 1546:1a09422b87a5

Get Windows build working again. MegaWiFi code probably needs more work before it will actually work on Windows, but at least it doesn't break the build now
author Michael Pavone <pavone@retrodev.com>
date Mon, 26 Mar 2018 21:25:40 -0700
parents 650178d81d33
children 6ce36c3f250b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
467
140af5509ce7 Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents: 431
diff changeset
1 /*
140af5509ce7 Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents: 431
diff changeset
2 Copyright 2013 Michael Pavone
495
39cad98d2789 Allow OpenGL support to be disabled at compile time. Move generic utility functions out of config.c
Mike Pavone <pavone@retrodev.com>
parents: 467
diff changeset
3 This file is part of BlastEm.
467
140af5509ce7 Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents: 431
diff changeset
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
140af5509ce7 Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents: 431
diff changeset
5 */
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
6 #include "tern.h"
495
39cad98d2789 Allow OpenGL support to be disabled at compile time. Move generic utility functions out of config.c
Mike Pavone <pavone@retrodev.com>
parents: 467
diff changeset
7 #include "util.h"
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
8 #include "paths.h"
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
9 #include <stdio.h>
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
10 #include <stdlib.h>
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
11 #include <string.h>
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
12
795
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
13 #ifdef __MINGW64_VERSION_MAJOR
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
14 #define MINGW_W64_VERSION (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR)
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
15 #else
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
16 #define MINGW_W64_VERSION 0
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
17 #endif
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
18
bce97fc0bb8a Fix mingw-w64 build and cross-compilation
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 766
diff changeset
19 #if defined(_WIN32) && (MINGW_W64_VERSION < 3003)
741
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
20 char * strtok_r(char * input, char * sep, char ** state)
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
21 {
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
22 if (input) {
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
23 *state = input;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
24 }
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
25 char * ret = *state;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
26 while (**state && **state != *sep)
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
27 {
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
28 ++*state;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
29 }
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
30 if (**state)
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
31 {
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
32 **state = 0;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
33 ++*state;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
34 return ret;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
35 }
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
36 return NULL;
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
37 }
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
38 #endif
80a67be1770b Initial work on Windows port
Michael Pavone <pavone@retrodev.com>
parents: 496
diff changeset
39
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
40 static tern_node * parse_config_int(char **state, int started, int *line)
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
41 {
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
42 char *config_data, *curline;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
43 tern_node * head = NULL;
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
44 config_data = started ? NULL : *state;
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
45 while ((curline = strtok_r(config_data, "\n", state)))
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
46 {
866
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
47
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
48 config_data = NULL;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
49 curline = strip_ws(curline);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
50 int len = strlen(curline);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
51 if (!len) {
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
52 *line = *line + 1;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
53 continue;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
54 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
55 if (curline[0] == '#') {
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
56 *line = *line + 1;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
57 continue;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
58 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
59 if (curline[0] == '}') {
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
60 if (started) {
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
61 return head;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
62 }
792
724bbec47f86 Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows).
Michael Pavone <pavone@retrodev.com>
parents: 766
diff changeset
63 fatal_error("unexpected } on line %d\n", *line);
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
64 }
866
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
65
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
66 char * end = curline + len - 1;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
67 if (*end == '{') {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
68 *end = 0;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
69 curline = strip_ws(curline);
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
70 *line = *line + 1;
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
71 head = tern_insert_node(head, curline, parse_config_int(state, 1, line));
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
72 } else {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
73 char * val = strip_ws(split_keyval(curline));
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
74 char * key = curline;
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
75 if (*val) {
431
440efd7d27a9 Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents: 430
diff changeset
76 head = tern_insert_ptr(head, key, strdup(val));
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
77 } else {
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
78 fprintf(stderr, "Key %s is missing a value on line %d\n", key, *line);
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
79 }
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
80 *line = *line + 1;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
81 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
82 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
83 return head;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
84 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
85
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
86 tern_node *parse_config(char * config_data)
766
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
87 {
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
88 int line = 1;
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
89 return parse_config_int(&config_data, 0, &line);
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
90 }
1b2f8280ba81 WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents: 742
diff changeset
91
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
92 typedef struct {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
93 char *buf;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
94 uint32_t capacity;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
95 uint32_t size;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
96 uint32_t indent;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
97 } serialize_state;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
98
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
99 static void ensure_buf_capacity(uint32_t ensure, serialize_state *state)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
100 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
101 if (ensure + state->size > state->capacity) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
102 state->capacity = state->capacity * 2;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
103 state->buf = realloc(state->buf, state->capacity);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
104 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
105 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
106
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
107 static void indent(serialize_state *state)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
108 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
109 memset(state->buf + state->size, '\t', state->indent);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
110 state->size += state->indent;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
111 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
112
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
113 static void serialize_config_int(tern_node *config, serialize_state *state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
114
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
115 static void serialize_iter(char *key, tern_val val, uint8_t valtype, void *data)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
116 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
117 serialize_state *state = data;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
118 uint32_t keylen = strlen(key);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
119 uint32_t vallen = 0;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
120 if (valtype == TVAL_PTR) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
121 vallen = strlen(val.ptrval);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
122 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
123 ensure_buf_capacity(state->indent + keylen + 2 + vallen, state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
124 state->buf[state->size++] = '\n';
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
125 indent(state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
126 memcpy(state->buf + state->size, key, keylen);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
127 state->size += keylen;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
128 state->buf[state->size++] = ' ';
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
129 if (valtype == TVAL_PTR) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
130 memcpy(state->buf + state->size, val.ptrval, vallen);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
131 state->size += vallen;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
132 } else {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
133 serialize_config_int(val.ptrval, state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
134 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
135 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
136
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
137 static void serialize_config_int(tern_node *config, serialize_state *state)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
138 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
139 ensure_buf_capacity(1, state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
140 state->buf[state->size++] = '{';
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
141 state->indent++;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
142
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
143 tern_foreach(config, serialize_iter, state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
144
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
145 --state->indent;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
146 ensure_buf_capacity(2 + state->indent, state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
147 state->buf[state->size++] = '\n';
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
148 indent(state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
149 state->buf[state->size++] = '}';
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
150 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
151
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
152 char *serialize_config(tern_node *config, uint32_t *size_out)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
153 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
154 serialize_state state = {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
155 .size = 0,
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
156 .capacity = 1024,
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
157 .indent = 0
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
158 };
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
159 state.buf = malloc(state.capacity);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
160 tern_foreach(config, serialize_iter, &state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
161 //serialize_config_int(config, &state);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
162 *size_out = state.size;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
163 return state.buf;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
164 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
165
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
166 tern_node *parse_config_file(char *config_path)
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
167 {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
168 tern_node * ret = NULL;
816
7ed55a361e79 Use binary mode for reading shaders and config files so we actually get the number of bytes we expect
Michael Pavone <pavone@retrodev.com>
parents: 799
diff changeset
169 FILE * config_file = fopen(config_path, "rb");
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
170 if (!config_file) {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
171 goto open_fail;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
172 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
173 long config_size = file_size(config_file);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
174 if (!config_size) {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
175 goto config_empty;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
176 }
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
177 char * config_data = malloc(config_size+1);
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
178 if (fread(config_data, 1, config_size, config_file) != config_size) {
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
179 goto config_read_fail;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
180 }
796
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
181 config_data[config_size] = '\0';
41f73c76b978 Fix some memory issues
=?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com>
parents: 795
diff changeset
182
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
183 ret = parse_config(config_data);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
184 config_read_fail:
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
185 free(config_data);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
186 config_empty:
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
187 fclose(config_file);
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
188 open_fail:
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
189 return ret;
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
190 }
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
191
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
192 uint8_t serialize_config_file(tern_node *config, char *path)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
193 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
194 FILE *f = fopen(path, "w");
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
195 if (!f) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
196 return 0;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
197 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
198 uint32_t buf_size;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
199 char *buffer = serialize_config(config, &buf_size);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
200 uint8_t ret = buf_size == fwrite(buffer, 1, buf_size, f);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
201 fclose(f);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
202 return ret;
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
203 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
204
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
205 tern_node *parse_bundled_config(char *config_name)
859
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
206 {
1140
4490c9c12272 Detect system type from filename if header based methods fail. Allow overriding system type from command line.
Michael Pavone <pavone@retrodev.com>
parents: 876
diff changeset
207 uint32_t confsize;
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
208 char *confdata = read_bundled_file(config_name, &confsize);
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
209 tern_node *ret = NULL;
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
210 if (confdata) {
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
211 confdata[confsize] = 0;
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
212 ret = parse_config(confdata);
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
213 free(confdata);
859
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
214 }
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
215 return ret;
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
216 }
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
217
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
218 tern_node *load_config()
859
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
219 {
876
540cc4a7d626 Fix Android build breakage
Michael Pavone <pavone@retrodev.com>
parents: 875
diff changeset
220 char const *confdir = get_config_dir();
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
221 char *confpath = NULL;
866
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
222 tern_node *ret;
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
223 if (confdir) {
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
224 confpath = path_append(confdir, "blastem.cfg");
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
225 ret = parse_config_file(confpath);
859
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
226 if (ret) {
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
227 free(confpath);
859
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
228 return ret;
46bb673eed4e Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents: 816
diff changeset
229 }
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
230 }
866
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
231
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
232 ret = parse_bundled_config("default.cfg");
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
233 if (ret) {
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
234 free(confpath);
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
235 return ret;
866
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
236 }
69a6ec208111 Menu ROM now pulls real file names from the OS rather than using a fake list
Michael Pavone <pavone@retrodev.com>
parents: 859
diff changeset
237
875
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
238 if (confpath) {
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
239 fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", confpath);
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
240 } else {
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
241 fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n");
54ffba3768d6 Make menu stuff work on Android (theoretically)
Michael Pavone <pavone@retrodev.com>
parents: 866
diff changeset
242 }
792
724bbec47f86 Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows).
Michael Pavone <pavone@retrodev.com>
parents: 766
diff changeset
243 //this will never get reached, but the compiler doesn't know that. Let's make it happy
724bbec47f86 Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows).
Michael Pavone <pavone@retrodev.com>
parents: 766
diff changeset
244 return NULL;
430
7f84090ab1cd Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
245 }
1485
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
246
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
247 void persist_config(tern_node *config)
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
248 {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
249 char const *confdir = get_config_dir();
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
250 if (!confdir) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
251 fatal_error("Failed to locate config file directory\n");
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
252 }
1540
e94cff9cb625 Make sure config directory exists before trying to save config file
Michael Pavone <pavone@retrodev.com>
parents: 1489
diff changeset
253 ensure_dir_exists(confdir);
1489
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
254 char *confpath = path_append(confdir, "blastem.cfg");
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
255 if (!serialize_config_file(config, confpath)) {
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
256 fatal_error("Failed to write config to %s\n", confpath);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
257 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
258 free(confpath);
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
259 }
637fbc3b5063 Added code to persist config back to a file
Michael Pavone <pavone@retrodev.com>
parents: 1485
diff changeset
260
1485
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
261 char **get_extension_list(tern_node *config, uint32_t *num_exts_out)
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
262 {
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
263 char *ext_filter = strdup(tern_find_path_default(config, "ui\0extensions\0", (tern_val){.ptrval = "bin gen md smd sms gg"}, TVAL_PTR).ptrval);
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
264 uint32_t num_exts = 0, ext_storage = 5;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
265 char **ext_list = malloc(sizeof(char *) * ext_storage);
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
266 char *cur_filter = ext_filter;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
267 while (*cur_filter)
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
268 {
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
269 if (num_exts == ext_storage) {
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
270 ext_storage *= 2;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
271 ext_list = realloc(ext_list, sizeof(char *) * ext_storage);
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
272 }
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
273 ext_list[num_exts++] = cur_filter;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
274 cur_filter = split_keyval(cur_filter);
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
275 }
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
276 *num_exts_out = num_exts;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
277 return ext_list;
369da70ee2c2 Filter file list in Nuklear UI
Michael Pavone <pavone@retrodev.com>
parents: 1140
diff changeset
278 }