some meshgen and map rendering updates
[voxelands-alt.git] / src / core / config.c
blobf05bbec341d16c3636ae10d1f9fc5eb4f4851d66
1 /************************************************************************
2 * config.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #include "nvp.h"
22 #include "crypto.h"
23 #include "file.h"
24 #include "array.h"
25 #include "wm.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
31 static struct {
32 nvp_t *items;
33 nvp_t *files;
34 int isinit;
35 } config = {
36 NULL,
37 NULL,
41 typedef struct config_s {
42 char* default_value;
43 int (*setter)(char* v);
44 } config_t;
46 /* get the value of a config setting */
47 char* config_get(char* name)
49 nvp_t *n = nvp_get(&config.items,name);
50 if (!n)
51 return NULL;
53 if (!n->value)
54 return ((config_t*)n->data)->default_value;
56 return n->value;
59 /* get a config setting as an int value */
60 int config_get_int(char* name)
62 char* v = config_get(name);
63 if (v)
64 return strtol(v,NULL,10);
66 return 0;
69 /* get a config setting as a float value */
70 float config_get_float(char* name)
72 char* v = config_get(name);
73 if (v)
74 return strtof(v,NULL);
76 return 0.0;
79 /* get a config setting as a boolean value */
80 int config_get_bool(char* name)
82 char* v = config_get(name);
83 return parse_bool(v);
86 /* set the value of a config setting */
87 void config_set(char* name, char* value)
89 config_t *c;
90 nvp_t *n;
92 if (!name)
93 return;
95 n = nvp_get(&config.items,name);
97 if (!n) {
98 if (!value)
99 return;
101 c = malloc(sizeof(config_t));
102 c->default_value = NULL;
103 c->setter = NULL;
105 nvp_set(&config.items,name,value,c);
107 return;
110 if (n->value)
111 free(n->value);
112 n->value = NULL;
114 if (value)
115 n->value = strdup(value);
117 c = n->data;
118 if (c->setter) {
119 if (!n->value && c->default_value) {
120 c->setter(c->default_value);
121 }else{
122 c->setter(n->value);
127 /* set a config setting from a command */
128 int config_set_command(array_t *args)
130 char* n;
131 char* v;
132 if (!args)
133 return 1;
135 n = array_get_string(args,0);
136 v = array_join(args," ",1);
137 config_set(n,v);
139 return 0;
142 /* set a config setting to an int value */
143 void config_set_int(char* name, int value)
145 char str[20];
146 sprintf(str,"%d",value);
147 config_set(name,str);
150 /* set a config setting to a float value */
151 void config_set_float(char* name, float value)
153 char str[50];
154 sprintf(str,"%f",value);
155 config_set(name,str);
158 /* set the default value of a config setting */
159 void config_set_default(char* name, char* value, int (*setter)(char* v))
161 config_t *c;
162 nvp_t *n = nvp_get(&config.items,name);
164 if (!n) {
165 if (!value && !setter)
166 return;
168 c = malloc(sizeof(config_t));
169 if (value) {
170 c->default_value = strdup(value);
171 }else{
172 c->default_value = NULL;
174 c->setter = setter;
176 nvp_set(&config.items,name,NULL,c);
178 if (setter)
179 setter(value);
181 return;
184 c = n->data;
186 if (c->default_value)
187 free(c->default_value);
188 c->default_value = NULL;
190 if (value)
191 c->default_value = strdup(value);
194 /* set the default of a config setting to an int value */
195 void config_set_default_int(char* name, int value, int (*setter)(char* v))
197 char str[20];
198 sprintf(str,"%d",value);
199 config_set_default(name,str,setter);
202 /* set the default of a config setting to a float value */
203 void config_set_default_float(char* name, float value, int (*setter)(char* v))
205 char str[50];
206 sprintf(str,"%f",value);
207 config_set_default(name,str,setter);
210 /* load a config file */
211 void config_load(char* file)
213 char buff[2048];
214 int s;
215 char* l;
217 file_t *f = file_load("config",file);
218 if (!f)
219 return;
221 while ((s = file_readline(f,buff,2048)) > -1) {
222 if (!s || buff[0] == '#')
223 continue;
224 l = trim(buff);
225 if (l && l[0])
226 command_exec(l);
229 file_free(f);
232 /* load a config file from a command */
233 int config_load_command(array_t *args)
235 char* f;
236 if (!args)
237 return 1;
239 f = array_get_string(args,0);
240 nvp_set(&config.files,f,"true",NULL);
241 config_load(f);
243 return 0;
246 /* set the ignore flag for a config file from a command */
247 int config_ignore_command(array_t *args)
249 char* f;
250 if (!args)
251 return 1;
253 f = array_get_string(args,0);
255 nvp_set(&config.files,f,"false",NULL);
257 return 0;
260 /* initialise configuration, load config files and defaults, etc */
261 void config_init(int argc, char** argv)
263 int i;
264 nvp_t *n;
266 config_default_init();
268 /* add the default config file to the to-exec list */
269 nvp_set(&config.files,"default.cfg","true",NULL);
271 for (i=1; i<(argc-1); i++) {
272 if (!strcmp(argv[i],"exec")) {
273 i += 1;
274 nvp_set(&config.files,argv[i],"true",NULL);
275 }else if (!strcmp(argv[i],"ignore")) {
276 i += 1;
277 nvp_set(&config.files,argv[i],"false",NULL);
281 n = config.files;
282 while (n) {
283 if (n->value && !strcmp(n->value,"true"))
284 config_load(n->name);
285 n = n->next;
288 for (i=0; i<argc; i++) {
289 if (!strcmp(argv[i],"set") && i+2 < argc) {
290 config_set(argv[i+1],argv[i+2]);
291 i+=2;
292 }else if (!strcmp(argv[i],"unset") && i+1 < argc) {
293 i+=1;
294 config_set(argv[i],NULL);
295 }else if (!strcmp(argv[i],"exec")) {
296 i += 1;
297 }else if (!strcmp(argv[i],"ignore")) {
298 i += 1;
302 config.isinit = 1;
305 /* save the current config */
306 void config_save(char* section, char* type, char* file)
308 file_t *f;
309 nvp_t *n;
311 if (!type && !file) {
312 n = config.files;
313 while (n) {
314 if (n->value && !strcmp(n->value,"true"))
315 break;
316 n = n->next;
319 /* TODO: should probably force saving to somewhere, custom.cfg? */
320 if (!n)
321 return;
323 f = file_create("config",n->name);
324 }else{
325 f = file_create(type,file);
328 if (!f)
329 return;
331 n = config.items;
332 while (n) {
333 if (n->value) {
334 if (!section || strstr(n->name,section) == n->name)
335 file_writef(f,"set %s %s\n",n->name,n->value);
337 n = n->next;
340 if (!section) {
341 events_save(f);
342 command_save(f);
345 file_flush(f);
346 file_free(f);