32 #include "settings.h" |
32 #include "settings.h" |
33 #include "command.h" |
33 #include "command.h" |
34 #include "console.h" |
34 #include "console.h" |
35 #include "saveload.h" |
35 #include "saveload.h" |
36 #include "npf.h" |
36 #include "npf.h" |
|
37 #include "newgrf.h" |
37 |
38 |
38 /** The patch values that are used for new games and/or modified in config file */ |
39 /** The patch values that are used for new games and/or modified in config file */ |
39 Patches _patches_newgame; |
40 Patches _patches_newgame; |
40 |
41 |
41 typedef struct IniFile IniFile; |
42 typedef struct IniFile IniFile; |
42 typedef struct IniItem IniItem; |
43 typedef struct IniItem IniItem; |
43 typedef struct IniGroup IniGroup; |
44 typedef struct IniGroup IniGroup; |
44 typedef struct SettingsMemoryPool SettingsMemoryPool; |
45 typedef struct SettingsMemoryPool SettingsMemoryPool; |
|
46 |
|
47 typedef const char *SettingListCallbackProc(const IniItem *item, uint index); |
|
48 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object); |
|
49 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc); |
45 |
50 |
46 static void pool_init(SettingsMemoryPool **pool); |
51 static void pool_init(SettingsMemoryPool **pool); |
47 static void *pool_alloc(SettingsMemoryPool **pool, uint size); |
52 static void *pool_alloc(SettingsMemoryPool **pool, uint size); |
48 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size); |
53 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size); |
49 static void pool_free(SettingsMemoryPool **pool); |
54 static void pool_free(SettingsMemoryPool **pool); |
815 * @param IniFile handle to the ini file with the source data |
820 * @param IniFile handle to the ini file with the source data |
816 * @param grpname character string identifying the section-header of the ini |
821 * @param grpname character string identifying the section-header of the ini |
817 * file that will be parsed |
822 * file that will be parsed |
818 * @param list pointer to an string(pointer) array that will store the parsed |
823 * @param list pointer to an string(pointer) array that will store the parsed |
819 * entries of the given section |
824 * entries of the given section |
820 * @param len the maximum number of items available for the above list */ |
825 * @param len the maximum number of items available for the above list |
821 static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len) |
826 * @param proc callback function that can override how the values are stored |
|
827 * inside the list */ |
|
828 static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc) |
822 { |
829 { |
823 IniGroup *group = ini_getgroup(ini, grpname, -1); |
830 IniGroup *group = ini_getgroup(ini, grpname, -1); |
824 IniItem *item; |
831 IniItem *item; |
825 uint i; |
832 const char *entry; |
|
833 uint i, j; |
826 |
834 |
827 if (group == NULL) return; |
835 if (group == NULL) return; |
828 |
836 |
829 item = group->item; |
837 for (i = j = 0, item = group->item; item != NULL; item = item->next) { |
830 for (i = 0; i != len; i++) { |
838 entry = (proc != NULL) ? proc(item, i++) : item->name; |
831 if (item == NULL) break; |
839 |
832 list[i] = strdup(item->name); |
840 if (entry == NULL || list == NULL) continue; |
833 item = item->next; |
841 |
|
842 if (j == len) break; |
|
843 list[j++] = strdup(entry); |
834 } |
844 } |
835 } |
845 } |
836 |
846 |
837 /** Saves all items from a list into the 'grpname' section |
847 /** Saves all items from a list into the 'grpname' section |
838 * The list parameter can be a NULL pointer, in this case a callback function |
848 * The list parameter can be a NULL pointer, in this case a callback function |
841 * @param grpname character string identifying the section-header of the ini file |
851 * @param grpname character string identifying the section-header of the ini file |
842 * @param list pointer to an string(pointer) array that will be used as the |
852 * @param list pointer to an string(pointer) array that will be used as the |
843 * source to be saved into the relevant ini section |
853 * source to be saved into the relevant ini section |
844 * @param len the maximum number of items available for the above list |
854 * @param len the maximum number of items available for the above list |
845 * @param proc callback function that can will provide the source data if defined */ |
855 * @param proc callback function that can will provide the source data if defined */ |
846 static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len) |
856 static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc) |
847 { |
857 { |
848 IniGroup *group = ini_getgroup(ini, grpname, -1); |
858 IniGroup *group = ini_getgroup(ini, grpname, -1); |
849 IniItem *item = NULL; |
859 IniItem *item = NULL; |
|
860 const char *entry; |
850 uint i; |
861 uint i; |
851 bool first = true; |
862 bool first = true; |
852 |
863 |
|
864 if (proc == NULL && list == NULL) return; |
853 if (group == NULL) return; |
865 if (group == NULL) return; |
854 group->item = NULL; |
866 group->item = NULL; |
855 |
867 |
856 for (i = 0; i != len; i++) { |
868 for (i = 0; i != len; i++) { |
857 if (list[i] == NULL || list[i][0] == '\0') continue; |
869 entry = (proc != NULL) ? proc(NULL, i) : list[i]; |
|
870 |
|
871 if (entry == NULL || *entry == '\0') continue; |
858 |
872 |
859 if (first) { // add first item to the head of the group |
873 if (first) { // add first item to the head of the group |
860 item = ini_item_alloc(group, list[i], strlen(list[i])); |
874 item = ini_item_alloc(group, entry, strlen(entry)); |
861 item->value = item->name; |
875 item->value = item->name; |
862 group->item = item; |
876 group->item = item; |
863 first = false; |
877 first = false; |
864 } else { // all other items are attached to the previous one |
878 } else { // all other items are attached to the previous one |
865 item->next = ini_item_alloc(group, list[i], strlen(list[i])); |
879 item->next = ini_item_alloc(group, entry, strlen(entry)); |
866 item = item->next; |
880 item = item->next; |
867 item->value = item->name; |
881 item->value = item->name; |
868 } |
882 } |
869 } |
883 } |
870 } |
884 } |
1383 #undef NC |
1397 #undef NC |
1384 #undef MS |
1398 #undef MS |
1385 #undef NO |
1399 #undef NO |
1386 #undef CR |
1400 #undef CR |
1387 |
1401 |
1388 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object); |
1402 const char *GRFProcessParams(const IniItem *item, uint index) |
1389 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len); |
1403 { |
|
1404 GRFConfig *c; |
|
1405 |
|
1406 /* Saving newgrf stuff to configuration, not done since it is kept the same */ |
|
1407 if (item == NULL) return NULL; |
|
1408 |
|
1409 /* Loading newgrf stuff from configuration file */ |
|
1410 c = calloc(1, sizeof(*c)); |
|
1411 c->filename = strdup(item->name); |
|
1412 c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param)); |
|
1413 if (c->num_params == (byte)-1) { |
|
1414 ShowInfoF("ini: error in array '%s'", item->name); |
|
1415 c->num_params = 0; |
|
1416 } |
|
1417 |
|
1418 if (_first_grfconfig == NULL) { |
|
1419 _first_grfconfig = c; |
|
1420 } else { |
|
1421 GRFConfig *c2; |
|
1422 /* Attach the label to the end of the list */ |
|
1423 for (c2 = _first_grfconfig; c2->next != NULL; c2 = c2->next); |
|
1424 c2->next = c; |
|
1425 } |
|
1426 |
|
1427 return c->filename; |
|
1428 } |
1390 |
1429 |
1391 /* Common handler for saving/loading variables to the configuration file */ |
1430 /* Common handler for saving/loading variables to the configuration file */ |
1392 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list) |
1431 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list) |
1393 { |
1432 { |
1394 proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL); |
1433 proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL); |
1401 proc(ini, _patch_settings, "patches", &_patches_newgame); |
1440 proc(ini, _patch_settings, "patches", &_patches_newgame); |
1402 proc(ini, _currency_settings,"currency", &_custom_currency); |
1441 proc(ini, _currency_settings,"currency", &_custom_currency); |
1403 |
1442 |
1404 #ifdef ENABLE_NETWORK |
1443 #ifdef ENABLE_NETWORK |
1405 proc(ini, (const SettingDesc*)_network_settings, "network", NULL); |
1444 proc(ini, (const SettingDesc*)_network_settings, "network", NULL); |
1406 proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list)); |
1445 proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL); |
1407 proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list)); |
1446 proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list), NULL); |
1408 #endif /* ENABLE_NETWORK */ |
1447 #endif /* ENABLE_NETWORK */ |
1409 } |
1448 } |
1410 |
1449 |
1411 /** Load the values from the configuration files */ |
1450 /** Load the values from the configuration files */ |
1412 void LoadFromConfig(void) |
1451 void LoadFromConfig(void) |
1413 { |
1452 { |
1414 IniFile *ini = ini_load(_config_file); |
1453 IniFile *ini = ini_load(_config_file); |
1415 HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list); |
1454 HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list); |
1416 ini_load_setting_list(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files)); |
1455 ini_load_setting_list(ini, "newgrf", NULL, 0, GRFProcessParams); |
1417 ini_free(ini); |
1456 ini_free(ini); |
1418 } |
1457 } |
1419 |
1458 |
1420 /** Save the values to the configuration file */ |
1459 /** Save the values to the configuration file */ |
1421 void SaveToConfig(void) |
1460 void SaveToConfig(void) |