From e00a47d47dbe0b5ef7c2425e5704220da7108fa9 Mon Sep 17 00:00:00 2001 From: Darkvater Date: Sat, 30 Dec 2006 23:09:27 +0000 Subject: [PATCH] (svn r7667) -Backport from trunk (r7549, r7551, r7554, r7582, r7594): - change size of newgrf GUI to same size as TTDP (no overflows) (r7549). - segmentation fault on showing NewGRF settings of a network game (r7551). - in Action 0xE, don't deactivate the current GRF (r7554). - appending static GRF's could cause duplicate GRF's in the list (r7582). - GRF config not cleared when no GRF's are used (r7594). --- newgrf.c | 5 +---- newgrf_config.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- newgrf_config.h | 1 + newgrf_gui.c | 20 ++++++++--------- 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/newgrf.c b/newgrf.c index 73b9009600..a664778f19 100644 --- a/newgrf.c +++ b/newgrf.c @@ -2966,13 +2966,10 @@ static void GRFInhibit(byte *buf, int len) GRFConfig *file = GetGRFConfig(grfid); /* Unset activation flag */ - if (file != NULL) { + if (file != NULL && file != _cur_grfconfig) { grfmsg(GMS_NOTICE, "GRFInhibit: Deactivating file ``%s''", file->filename); SETBIT(file->flags, GCF_DISABLED); CLRBIT(file->flags, GCF_ACTIVATED); - - /* Skip processing if the GRF deactivated itself */ - if (file == _cur_grfconfig) _skip_sprites = -1; } } } diff --git a/newgrf_config.c b/newgrf_config.c index b70c8354f0..95511c829e 100644 --- a/newgrf_config.c +++ b/newgrf_config.c @@ -120,9 +120,9 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src) for (; src != NULL; src = src->next) { c = calloc(1, sizeof(*c)); *c = *src; - c->filename = strdup(src->filename); - if (src->name != NULL) c->name = strdup(src->name); - if (src->info != NULL) c->info = strdup(src->info); + if (src->filename != NULL) c->filename = strdup(src->filename); + if (src->name != NULL) c->name = strdup(src->name); + if (src->info != NULL) c->info = strdup(src->info); *dst = c; dst = &c->next; @@ -131,14 +131,63 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src) return dst; } +/** + * Removes duplicates from lists of GRFConfigs. These duplicates + * are introduced when the _grfconfig_static GRFs are appended + * to the _grfconfig on a newgame or savegame. As the parameters + * of the static GRFs could be different that the parameters of + * the ones used non-statically. This can result in desyncs in + * multiplayers, so the duplicate static GRFs have to be removed. + * + * This function _assumes_ that all static GRFs are placed after + * the non-static GRFs. + * + * @param list the list to remove the duplicates from + */ +static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list) +{ + GRFConfig *prev; + GRFConfig *cur; + + if (list == NULL) return; + + for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) { + if (cur->grfid != list->grfid) continue; + assert(HASBIT(cur->flags, GCF_STATIC)); + prev->next = cur->next; + ClearGRFConfig(&cur); + cur = prev; // Just go back one so it continues as normal later on + } + + RemoveDuplicatesFromGRFConfigList(list->next); +} + +/** + * Appends the static GRFs to a list of GRFs + * @param dst the head of the list to add to + */ +void AppendStaticGRFConfigs(GRFConfig **dst) +{ + GRFConfig **tail = dst; + while (*tail != NULL) tail = &(*tail)->next; + + CopyGRFConfigList(tail, _grfconfig_static); + RemoveDuplicatesFromGRFConfigList(*dst); +} + /* Reset the current GRF Config to either blank or newgame settings */ void ResetGRFConfig(bool defaults) { GRFConfig **c = &_grfconfig; - if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame); - CopyGRFConfigList(c, _grfconfig_static); + if (defaults) { + c = CopyGRFConfigList(c, _grfconfig_newgame); + } else { + ClearGRFConfigList(c); + } + + AppendStaticGRFConfigs(&_grfconfig); } @@ -400,6 +449,7 @@ static void Load_NGRF(void) ClearGRFConfigList(&_grfconfig); _grfconfig = first; + AppendStaticGRFConfigs(&_grfconfig); } const ChunkHandler _newgrf_chunk_handlers[] = { diff --git a/newgrf_config.h b/newgrf_config.h index 24721a555d..37f5c6d866 100644 --- a/newgrf_config.h +++ b/newgrf_config.h @@ -44,6 +44,7 @@ void ScanNewGRFFiles(void); const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum); GRFConfig *GetGRFConfig(uint32 grfid); GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src); +void AppendStaticGRFConfigs(GRFConfig **dst); void ClearGRFConfig(GRFConfig **config); void ClearGRFConfigList(GRFConfig **config); void ResetGRFConfig(bool defaults); diff --git a/newgrf_gui.c b/newgrf_gui.c index 6771174faa..9babf017e0 100644 --- a/newgrf_gui.c +++ b/newgrf_gui.c @@ -200,17 +200,17 @@ static const Widget _newgrf_add_dlg_widgets[] = { { WWT_SCROLLBAR, RESIZE_LRB, 14, 295, 306, 14, 221, 0x0, STR_NULL }, /* NewGRF file info */ -{ WWT_PANEL, RESIZE_RTB, 14, 0, 306, 222, 311, 0x0, STR_NULL }, +{ WWT_PANEL, RESIZE_RTB, 14, 0, 306, 222, 324, 0x0, STR_NULL }, -{ WWT_PUSHTXTBTN, RESIZE_RTB, 14, 0, 146, 312, 323, STR_NEWGRF_ADD_FILE, STR_NEWGRF_ADD_FILE_TIP }, -{ WWT_PUSHTXTBTN, RESIZE_LRTB, 14, 147, 294, 312, 323, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP }, -{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 295, 306, 312, 323, 0x0, STR_RESIZE_BUTTON }, +{ WWT_PUSHTXTBTN, RESIZE_RTB, 14, 0, 146, 325, 336, STR_NEWGRF_ADD_FILE, STR_NEWGRF_ADD_FILE_TIP }, +{ WWT_PUSHTXTBTN, RESIZE_LRTB, 14, 147, 294, 325, 336, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP }, +{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 295, 306, 325, 336, 0x0, STR_RESIZE_BUTTON }, { WIDGETS_END }, }; static const WindowDesc _newgrf_add_dlg_desc = { - WDP_CENTER, WDP_CENTER, 307, 324, + WDP_CENTER, WDP_CENTER, 307, 337, WC_SAVELOAD, 0, WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE, _newgrf_add_dlg_widgets, @@ -485,20 +485,20 @@ static const Widget _newgrf_widgets[] = { { WWT_SCROLLBAR, RESIZE_LRB, 10, 288, 299, 30, 99, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST }, /* NewGRF file info */ -{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 199, STR_NULL, STR_NULL }, +{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 212, STR_NULL, STR_NULL }, /* Edit parameter and apply changes button... */ -{ WWT_PUSHTXTBTN, RESIZE_TB, 10, 0, 143, 200, 211, STR_NEWGRF_SET_PARAMETERS, STR_NULL }, -{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 144, 287, 200, 211, STR_NEWGRF_APPLY_CHANGES, STR_NULL }, +{ WWT_PUSHTXTBTN, RESIZE_TB, 10, 0, 143, 213, 224, STR_NEWGRF_SET_PARAMETERS, STR_NULL }, +{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 144, 287, 213, 224, STR_NEWGRF_APPLY_CHANGES, STR_NULL }, -{ WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 200, 211, 0x0, STR_RESIZE_BUTTON }, +{ WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 213, 224, 0x0, STR_RESIZE_BUTTON }, { WIDGETS_END }, }; static const WindowDesc _newgrf_desc = { - WDP_CENTER, WDP_CENTER, 300, 212, + WDP_CENTER, WDP_CENTER, 300, 225, WC_GAME_OPTIONS, 0, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE, _newgrf_widgets,