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 {