diff --git a/newgrf.c b/newgrf.c index 3225cf77e3..dc1487f586 100644 --- a/newgrf.c +++ b/newgrf.c @@ -41,6 +41,7 @@ extern int _traininfo_vehicle_pitch; static GRFFile *_cur_grffile; GRFFile *_first_grffile; +GRFConfig *_first_grfconfig; static int _cur_spriteid; static int _cur_stage; static uint32 _nfo_line; @@ -2492,11 +2493,11 @@ static void ClearTemporaryNewGRFData(void) _cur_grffile->spritegroups_count = 0; } -static void InitNewGRFFile(const char* filename, int sprite_offset) +static void InitNewGRFFile(const GRFConfig *config, int sprite_offset) { GRFFile *newfile; - newfile = GetFileByFilename(filename); + newfile = GetFileByFilename(config->filename); if (newfile != NULL) { /* We already loaded it once. */ newfile->sprite_offset = sprite_offset; @@ -2508,9 +2509,14 @@ static void InitNewGRFFile(const char* filename, int sprite_offset) if (newfile == NULL) error ("Out of memory"); - newfile->filename = strdup(filename); + newfile->filename = strdup(config->filename); newfile->sprite_offset = sprite_offset; + /* Copy the initial parameter list */ + assert(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80); + newfile->param_end = config->num_params; + memcpy(newfile->param, config->param, 0x80 * sizeof(newfile->param[0])); + if (_first_grffile == NULL) { _cur_grffile = newfile; _first_grffile = newfile; @@ -2707,17 +2713,18 @@ void LoadNewGRF(uint load_index, uint file_index) _custom_sprites_base = load_index; for (stage = 0; stage <= 2; stage++) { uint slot = file_index; - uint j; + GRFConfig *c; _cur_stage = stage; _cur_spriteid = load_index; - for (j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j] != NULL; j++) { - if (!FiosCheckFileExists(_newgrf_files[j])) { + for (c = _first_grfconfig; c != NULL; c = c->next) { + if (!FiosCheckFileExists(c->filename)) { // TODO: usrerror() - error("NewGRF file missing: %s", _newgrf_files[j]); + error("NewGRF file missing: %s", c->filename); } - if (stage == 0) InitNewGRFFile(_newgrf_files[j], _cur_spriteid); - LoadNewGRFFile(_newgrf_files[j], slot++, stage); + + if (stage == 0) InitNewGRFFile(c, _cur_spriteid); + LoadNewGRFFile(c->filename, slot++, stage); if (stage == 2) ClearTemporaryNewGRFData(); DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index); } diff --git a/newgrf.h b/newgrf.h index f3abac6e6e..904d444192 100644 --- a/newgrf.h +++ b/newgrf.h @@ -13,14 +13,13 @@ typedef struct GRFLabel { struct GRFLabel *next; } GRFLabel; -typedef struct GRFFile GRFFile; -struct GRFFile { +typedef struct GRFFile { char *filename; uint32 grfid; uint16 flags; uint16 sprite_offset; SpriteID first_spriteset; ///< Holds the first spriteset's sprite offset. - GRFFile *next; + struct GRFFile *next; /* A sprite group contains all sprites of a given vehicle (or multiple * vehicles) when carrying given cargo. It consists of several sprite @@ -48,10 +47,19 @@ struct GRFFile { uint param_end; /// one more than the highest set parameter GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array. -}; +} GRFFile; extern GRFFile *_first_grffile; +typedef struct GRFConfig { + const char *filename; + uint32 param[0x80]; + byte num_params; + + struct GRFConfig *next; +} GRFConfig; + +extern GRFConfig *_first_grfconfig; void LoadNewGRF(uint load_index, uint file_index); diff --git a/settings.c b/settings.c index b6f239e929..1372eec94f 100644 --- a/settings.c +++ b/settings.c @@ -34,6 +34,7 @@ #include "console.h" #include "saveload.h" #include "npf.h" +#include "newgrf.h" /** The patch values that are used for new games and/or modified in config file */ Patches _patches_newgame; @@ -43,6 +44,10 @@ typedef struct IniItem IniItem; typedef struct IniGroup IniGroup; typedef struct SettingsMemoryPool SettingsMemoryPool; +typedef const char *SettingListCallbackProc(const IniItem *item, uint index); +typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object); +typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc); + static void pool_init(SettingsMemoryPool **pool); static void *pool_alloc(SettingsMemoryPool **pool, uint size); static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size); @@ -817,20 +822,25 @@ static void ini_save_settings(IniFile *ini, const SettingDesc *sd, const char *g * file that will be parsed * @param list pointer to an string(pointer) array that will store the parsed * entries of the given section - * @param len the maximum number of items available for the above list */ -static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len) + * @param len the maximum number of items available for the above list + * @param proc callback function that can override how the values are stored + * inside the list */ +static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc) { IniGroup *group = ini_getgroup(ini, grpname, -1); IniItem *item; - uint i; + const char *entry; + uint i, j; if (group == NULL) return; - item = group->item; - for (i = 0; i != len; i++) { - if (item == NULL) break; - list[i] = strdup(item->name); - item = item->next; + for (i = j = 0, item = group->item; item != NULL; item = item->next) { + entry = (proc != NULL) ? proc(item, i++) : item->name; + + if (entry == NULL || list == NULL) continue; + + if (j == len) break; + list[j++] = strdup(entry); } } @@ -843,26 +853,30 @@ static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list * source to be saved into the relevant ini section * @param len the maximum number of items available for the above list * @param proc callback function that can will provide the source data if defined */ -static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len) +static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc) { IniGroup *group = ini_getgroup(ini, grpname, -1); IniItem *item = NULL; + const char *entry; uint i; bool first = true; + if (proc == NULL && list == NULL) return; if (group == NULL) return; group->item = NULL; for (i = 0; i != len; i++) { - if (list[i] == NULL || list[i][0] == '\0') continue; + entry = (proc != NULL) ? proc(NULL, i) : list[i]; + + if (entry == NULL || *entry == '\0') continue; if (first) { // add first item to the head of the group - item = ini_item_alloc(group, list[i], strlen(list[i])); + item = ini_item_alloc(group, entry, strlen(entry)); item->value = item->name; group->item = item; first = false; } else { // all other items are attached to the previous one - item->next = ini_item_alloc(group, list[i], strlen(list[i])); + item->next = ini_item_alloc(group, entry, strlen(entry)); item = item->next; item->value = item->name; } @@ -1385,8 +1399,33 @@ static const SettingDesc _currency_settings[] = { #undef NO #undef CR -typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object); -typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len); +const char *GRFProcessParams(const IniItem *item, uint index) +{ + GRFConfig *c; + + /* Saving newgrf stuff to configuration, not done since it is kept the same */ + if (item == NULL) return NULL; + + /* Loading newgrf stuff from configuration file */ + c = calloc(1, sizeof(*c)); + c->filename = strdup(item->name); + c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param)); + if (c->num_params == (byte)-1) { + ShowInfoF("ini: error in array '%s'", item->name); + c->num_params = 0; + } + + if (_first_grfconfig == NULL) { + _first_grfconfig = c; + } else { + GRFConfig *c2; + /* Attach the label to the end of the list */ + for (c2 = _first_grfconfig; c2->next != NULL; c2 = c2->next); + c2->next = c; + } + + return c->filename; +} /* Common handler for saving/loading variables to the configuration file */ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list) @@ -1403,8 +1442,8 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP #ifdef ENABLE_NETWORK proc(ini, (const SettingDesc*)_network_settings, "network", NULL); - proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list)); - proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list)); + proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL); + proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list), NULL); #endif /* ENABLE_NETWORK */ } @@ -1413,7 +1452,7 @@ void LoadFromConfig(void) { IniFile *ini = ini_load(_config_file); HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list); - ini_load_setting_list(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files)); + ini_load_setting_list(ini, "newgrf", NULL, 0, GRFProcessParams); ini_free(ini); }