From 261b34b70503ba2e2a803cd9664f35b2f2c4ae14 Mon Sep 17 00:00:00 2001 From: yexo Date: Thu, 3 Mar 2011 21:24:03 +0000 Subject: (svn r22175) -Fix: [NewGRF] memory leak if a station newgrf contains prop 09 twice for the same station id --- src/newgrf.cpp | 24 ++++++++++++++---------- src/newgrf_station.h | 1 - src/sprite.cpp | 16 ++++++++++++++++ src/sprite.h | 2 ++ src/table/station_land.h | 2 +- 5 files changed, 33 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/newgrf.cpp b/src/newgrf.cpp index a60e76789..017fb36a0 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1199,7 +1199,6 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte case 0x09: // Define sprite layout statspec->tiles = buf->ReadExtendedByte(); statspec->renderdata = CallocT(statspec->tiles); - statspec->copied_renderdata = false; for (uint t = 0; t < statspec->tiles; t++) { DrawTileSprites *dts = &statspec->renderdata[t]; @@ -1208,7 +1207,12 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte dts->seq = NULL; dts->ground.sprite = buf->ReadWord(); dts->ground.pal = buf->ReadWord(); - if (dts->ground.sprite == 0) continue; + if (dts->ground.sprite == 0 && dts->ground.pal == 0) { + extern const DrawTileSprites _station_display_datas_rail[8]; + dts->ground = _station_display_datas_rail[t % 8].ground; + dts->seq = CopyDrawTileSeqStruct(_station_display_datas_rail[t % 8].seq); + continue; + } if (HasBit(dts->ground.pal, 15)) { /* Use sprite from Action 1 */ ClrBit(dts->ground.pal, 15); @@ -1254,8 +1258,11 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte } statspec->tiles = srcstatspec->tiles; - statspec->renderdata = srcstatspec->renderdata; - statspec->copied_renderdata = true; + statspec->renderdata = MallocT(statspec->tiles); + for (uint t = 0; t < statspec->tiles; t++) { + statspec->renderdata[t].ground = srcstatspec->renderdata[t].ground; + statspec->renderdata[t].seq = CopyDrawTileSeqStruct(srcstatspec->renderdata[t].seq); + } break; } @@ -7050,13 +7057,10 @@ static void ResetCustomStations() if (stations[i] == NULL) continue; StationSpec *statspec = stations[i]; - /* Release renderdata, if it wasn't copied from another custom station spec */ - if (!statspec->copied_renderdata) { - for (uint t = 0; t < statspec->tiles; t++) { - free((void*)statspec->renderdata[t].seq); - } - free(statspec->renderdata); + for (uint t = 0; t < statspec->tiles; t++) { + free((void*)statspec->renderdata[t].seq); } + free(statspec->renderdata); /* Release platforms and layouts */ if (!statspec->copied_layouts) { diff --git a/src/newgrf_station.h b/src/newgrf_station.h index cd7182d87..df474774c 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -78,7 +78,6 @@ struct StationSpec { */ uint tiles; DrawTileSprites *renderdata; ///< Array of tile layouts. - bool copied_renderdata; /** * Cargo threshold for choosing between little and lots of cargo diff --git a/src/sprite.cpp b/src/sprite.cpp index 2e453941a..4e41be4f1 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -14,6 +14,8 @@ #include "viewport_func.h" #include "landscape.h" #include "spritecache.h" +#include "core/alloc_func.hpp" +#include "core/mem_func.hpp" /** @@ -108,3 +110,17 @@ void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 orig } } } + +/** Create a copy of an existing DrawTileSeqStruct array. */ +const DrawTileSeqStruct *CopyDrawTileSeqStruct(const DrawTileSeqStruct *dtss) +{ + const DrawTileSeqStruct *element; + + size_t count = 1; // 1 for the terminator + foreach_draw_tile_seq(element, dtss) count++; + + DrawTileSeqStruct *copy = MallocT(count); + MemCpyT(copy, dtss, count); + + return copy; +} diff --git a/src/sprite.h b/src/sprite.h index 3e03aee6a..9321ba534 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -52,6 +52,8 @@ struct DrawTileSeqStruct { } }; +const DrawTileSeqStruct *CopyDrawTileSeqStruct(const DrawTileSeqStruct *dtss); + /** Ground palette sprite of a tile, together with its child sprites */ struct DrawTileSprites { PalSpriteID ground; ///< Palette and sprite for the ground diff --git a/src/table/station_land.h b/src/table/station_land.h index 2e46ba9f3..8b3b456c0 100644 --- a/src/table/station_land.h +++ b/src/table/station_land.h @@ -791,7 +791,7 @@ static const DrawTileSeqStruct _station_display_datas_waypoint_Y[] = { #define TILE_SPRITE_LINE(img, dtss) { {img, PAL_NONE}, dtss }, #define TILE_SPRITE_NULL() { {0, 0}, NULL }, -static const DrawTileSprites _station_display_datas_rail[] = { +extern const DrawTileSprites _station_display_datas_rail[] = { TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_0) TILE_SPRITE_LINE(SPR_RAIL_TRACK_Y, _station_display_datas_1) TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_2) -- cgit v1.2.3-70-g09d2