Mercurial > repos > blastem
comparison config.c @ 2158:bdd83b47d78a
Implement config file migrations and add iso and cue to extension list
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 24 May 2022 09:10:54 -0700 |
parents | 193b804c9845 |
children | 1270fe86eb89 |
comparison
equal
deleted
inserted
replaced
2157:da7890445962 | 2158:bdd83b47d78a |
---|---|
248 } | 248 } |
249 | 249 |
250 return ret; | 250 return ret; |
251 } | 251 } |
252 | 252 |
253 static tern_node *dupe_tree(tern_node *head) | |
254 { | |
255 if (!head) { | |
256 return head; | |
257 } | |
258 tern_node *out = calloc(1, sizeof(tern_node)); | |
259 out->left = dupe_tree(head->left); | |
260 out->right = dupe_tree(head->right); | |
261 out->el = head->el; | |
262 out->valtype = head->valtype; | |
263 if (out->el) { | |
264 out->straight.next = dupe_tree(head->straight.next); | |
265 } else if (out->valtype == TVAL_NODE) { | |
266 out->straight.value.ptrval = dupe_tree(head->straight.value.ptrval); | |
267 } else if (out->valtype == TVAL_PTR) { | |
268 out->straight.value.ptrval = strdup(head->straight.value.ptrval); | |
269 } else { | |
270 out->straight.value = head->straight.value; | |
271 } | |
272 return out; | |
273 } | |
274 | |
275 static void migrate_pads(char *key, tern_val val, uint8_t valtype, void *data) | |
276 { | |
277 tern_node **pads = data; | |
278 if (valtype != TVAL_NODE) { | |
279 return; | |
280 } | |
281 tern_node *existing = tern_find_node(*pads, key); | |
282 if (existing) { | |
283 return; | |
284 } | |
285 *pads = tern_insert_node(*pads, key, dupe_tree(val.ptrval)); | |
286 } | |
287 | |
288 #define CONFIG_VERSION 1 | |
289 static tern_node *migrate_config(tern_node *config, int from_version) | |
290 { | |
291 tern_node *def_config = parse_bundled_config("default.cfg"); | |
292 switch(from_version) | |
293 { | |
294 case 0: { | |
295 //Add CD image formats to ui.extensions | |
296 uint32_t num_exts; | |
297 char **ext_list = get_extension_list(config, &num_exts); | |
298 char *old = num_exts ? ext_list[0] : NULL; | |
299 uint32_t new_size = num_exts + 2; | |
300 uint8_t need_cue = 1, need_iso = 1; | |
301 for (uint32_t i = 0; i < num_exts; i++) | |
302 { | |
303 if (!strcmp(ext_list[i], "cue")) { | |
304 need_cue = 0; | |
305 new_size--; | |
306 } else if (!strcmp(ext_list[i], "iso")) { | |
307 need_iso = 0; | |
308 new_size--; | |
309 } | |
310 } | |
311 if (new_size != num_exts) { | |
312 ext_list = realloc(ext_list, sizeof(char*) * new_size); | |
313 if (need_cue) { | |
314 ext_list[num_exts++] = "cue"; | |
315 } | |
316 if (need_iso) { | |
317 ext_list[num_exts++] = "iso"; | |
318 } | |
319 } | |
320 char *combined = alloc_join(new_size, (char const **)ext_list, ' '); | |
321 config = tern_insert_path(config, "ui\0extensions\0", (tern_val){.ptrval = combined}, TVAL_PTR); | |
322 //Copy default pad configs if missing | |
323 tern_node *pads = tern_find_path(config, "bindings\0pads\0", TVAL_NODE).ptrval; | |
324 tern_node *def_pads = tern_find_path(def_config, "bindings\0pads\0", TVAL_NODE).ptrval; | |
325 tern_foreach(def_pads, migrate_pads, &pads); | |
326 config = tern_insert_path(config, "bindings\0pads\0", (tern_val){.ptrval = pads}, TVAL_NODE); | |
327 break; | |
328 } | |
329 } | |
330 char buffer[16]; | |
331 sprintf(buffer, "%d", CONFIG_VERSION); | |
332 return tern_insert_ptr(config, "version", strdup(buffer)); | |
333 } | |
334 | |
253 static uint8_t app_config_in_config_dir; | 335 static uint8_t app_config_in_config_dir; |
254 tern_node *load_config() | 336 tern_node *load_config() |
255 { | 337 { |
256 tern_node *ret = load_overrideable_config("blastem.cfg", "default.cfg", &app_config_in_config_dir); | 338 tern_node *ret = load_overrideable_config("blastem.cfg", "default.cfg", &app_config_in_config_dir); |
257 | 339 |
259 if (get_config_dir()) { | 341 if (get_config_dir()) { |
260 fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", get_config_dir()); | 342 fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", get_config_dir()); |
261 } else { | 343 } else { |
262 fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n"); | 344 fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n"); |
263 } | 345 } |
346 } | |
347 int config_version = atoi(tern_find_ptr_default(ret, "version", "0")); | |
348 if (config_version < CONFIG_VERSION) { | |
349 migrate_config(ret, config_version); | |
264 } | 350 } |
265 return ret; | 351 return ret; |
266 } | 352 } |
267 | 353 |
268 void persist_config_at(tern_node *app_config, tern_node *to_save, char *fname) | 354 void persist_config_at(tern_node *app_config, tern_node *to_save, char *fname) |
313 delete_custom_config_at("blastem.cfg"); | 399 delete_custom_config_at("blastem.cfg"); |
314 } | 400 } |
315 | 401 |
316 char **get_extension_list(tern_node *config, uint32_t *num_exts_out) | 402 char **get_extension_list(tern_node *config, uint32_t *num_exts_out) |
317 { | 403 { |
318 char *ext_filter = strdup(tern_find_path_default(config, "ui\0extensions\0", (tern_val){.ptrval = "bin gen md smd sms gg"}, TVAL_PTR).ptrval); | 404 char *ext_filter = strdup(tern_find_path_default(config, "ui\0extensions\0", (tern_val){.ptrval = "bin gen md smd sms gg cue iso"}, TVAL_PTR).ptrval); |
319 uint32_t num_exts = 0, ext_storage = 5; | 405 uint32_t num_exts = 0, ext_storage = 5; |
320 char **ext_list = malloc(sizeof(char *) * ext_storage); | 406 char **ext_list = malloc(sizeof(char *) * ext_storage); |
321 char *cur_filter = ext_filter; | 407 char *cur_filter = ext_filter; |
322 while (*cur_filter) | 408 while (*cur_filter) |
323 { | 409 { |