diff options
author | yexo <yexo@openttd.org> | 2011-03-03 21:24:03 +0000 |
---|---|---|
committer | yexo <yexo@openttd.org> | 2011-03-03 21:24:03 +0000 |
commit | 261b34b70503ba2e2a803cd9664f35b2f2c4ae14 (patch) | |
tree | f2019a81e19e9f4f5c2922965f0a057b6fb64517 | |
parent | 91ddf07c80b82e780fae8e6212a20f9afc031a80 (diff) | |
download | openttd-261b34b70503ba2e2a803cd9664f35b2f2c4ae14.tar.xz |
(svn r22175) -Fix: [NewGRF] memory leak if a station newgrf contains prop 09 twice for the same station id
-rw-r--r-- | src/newgrf.cpp | 24 | ||||
-rw-r--r-- | src/newgrf_station.h | 1 | ||||
-rw-r--r-- | src/sprite.cpp | 16 | ||||
-rw-r--r-- | src/sprite.h | 2 | ||||
-rw-r--r-- | src/table/station_land.h | 2 |
5 files changed, 33 insertions, 12 deletions
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<DrawTileSprites>(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<DrawTileSprites>(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<DrawTileSeqStruct>(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) |