diff options
-rw-r--r-- | src/newgrf.cpp | 35 | ||||
-rw-r--r-- | src/newgrf_commons.cpp | 31 | ||||
-rw-r--r-- | src/newgrf_commons.h | 30 | ||||
-rw-r--r-- | src/newgrf_spritegroup.cpp | 3 | ||||
-rw-r--r-- | src/newgrf_spritegroup.h | 2 | ||||
-rw-r--r-- | src/newgrf_station.h | 2 | ||||
-rw-r--r-- | src/sprite.cpp | 14 | ||||
-rw-r--r-- | src/sprite.h | 8 |
8 files changed, 81 insertions, 44 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp index e837ba078..0b89b81e0 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1222,19 +1222,16 @@ 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->renderdata = new NewGRFSpriteLayout[statspec->tiles]; for (uint t = 0; t < statspec->tiles; t++) { - DrawTileSprites *dts = &statspec->renderdata[t]; - uint seq_count = 0; + NewGRFSpriteLayout *dts = &statspec->renderdata[t]; - dts->seq = NULL; dts->ground.sprite = buf->ReadWord(); dts->ground.pal = buf->ReadWord(); 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); + dts->Clone(&_station_display_datas_rail[t % 8]); continue; } if (HasBit(dts->ground.pal, 15)) { @@ -1245,10 +1242,12 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte MapSpriteMappingRecolour(&dts->ground); + static SmallVector<DrawTileSeqStruct, 8> tmp_layout; + tmp_layout.Clear(); for (;;) { /* no relative bounding box support */ - dts->seq = ReallocT(const_cast<DrawTileSeqStruct *>(dts->seq), ++seq_count); - DrawTileSeqStruct *dtss = const_cast<DrawTileSeqStruct *>(&dts->seq[seq_count - 1]); + DrawTileSeqStruct *dtss = tmp_layout.Append(); + MemSetT(dtss, 0); dtss->delta_x = buf->ReadByte(); if (dtss->IsTerminator()) break; @@ -1269,6 +1268,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte MapSpriteMappingRecolour(&dtss->image); } + dts->Clone(tmp_layout.Begin()); } break; @@ -1282,10 +1282,9 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte } statspec->tiles = srcstatspec->tiles; - statspec->renderdata = MallocT<DrawTileSprites>(statspec->tiles); + statspec->renderdata = new NewGRFSpriteLayout[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); + statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]); } break; } @@ -3947,7 +3946,7 @@ static void NewSpriteGroup(ByteReader *buf) act_group = group; /* num_building_stages should be 1, if we are only using non-custom sprites */ group->num_building_stages = max((uint8)1, num_spriteset_ents); - group->dts = CallocT<DrawTileSprites>(1); + group->dts = new NewGRFSpriteLayout(); /* Groundsprite */ group->dts->ground.sprite = buf->ReadWord(); @@ -3972,8 +3971,7 @@ static void NewSpriteGroup(ByteReader *buf) } } - group->dts->seq = CallocT<DrawTileSeqStruct>(num_building_sprites + 1); - + group->dts->Allocate(num_building_sprites); for (i = 0; i < num_building_sprites; i++) { DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts->seq[i]); @@ -4009,10 +4007,6 @@ static void NewSpriteGroup(ByteReader *buf) seq->size_y = buf->ReadByte(); seq->size_z = buf->ReadByte(); } - - /* Set the terminator value. */ - const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].MakeTerminator(); - break; } @@ -7063,10 +7057,7 @@ static void ResetCustomStations() if (stations[i] == NULL) continue; StationSpec *statspec = stations[i]; - for (uint t = 0; t < statspec->tiles; t++) { - free((void*)statspec->renderdata[t].seq); - } - free(statspec->renderdata); + delete[] statspec->renderdata; /* Release platforms and layouts */ if (!statspec->copied_layouts) { diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index edb3212bf..ce4a6807a 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -434,3 +434,34 @@ uint32 GetNearbyTileInformation(TileIndex tile) byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1; return tile_type << 24 | z << 16 | terrain_type << 8 | tileh; } + +/** + * Clone the building sprites of a spritelayout. + * @param source The building sprites to copy. + */ +void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source) +{ + assert(this->seq == NULL); + assert(source != NULL); + + size_t count = 1; // 1 for the terminator + const DrawTileSeqStruct *element; + foreach_draw_tile_seq(element, source) count++; + + DrawTileSeqStruct *sprites = MallocT<DrawTileSeqStruct>(count); + MemCpyT(sprites, source, count); + this->seq = sprites; +} + +/** + * Allocate a spritelayout for \a num_sprites building sprites. + * @param num_sprites Number of building sprites to allocate memory for. (not counting the terminator) + */ +void NewGRFSpriteLayout::Allocate(uint num_sprites) +{ + assert(this->seq == NULL); + + DrawTileSeqStruct *sprites = CallocT<DrawTileSeqStruct>(num_sprites + 1); + sprites[num_sprites].MakeTerminator(); + this->seq = sprites; +} diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 171ccf759..1ddfdc181 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -16,8 +16,10 @@ #define NEWGRF_COMMONS_H #include "tile_type.h" +#include "sprite.h" +#include "core/alloc_type.hpp" -/** Contextx for tile accesses */ +/** Context for tile accesses */ enum TileContext { TCX_NORMAL, ///< Nothing special. TCX_UPPER_HALFTILE, ///< Querying information about the upper part of a tile with halftile foundation. @@ -25,6 +27,32 @@ enum TileContext { }; /** + * NewGRF supplied spritelayout. + * In contrast to #DrawTileSprites this struct is for allocated + * layouts on the heap. It allocates data and frees them on destruction. + */ +struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { + void Allocate(uint num_sprites); + void Clone(const DrawTileSeqStruct *source); + + /** + * Clone a spritelayout. + * @param source The spritelayout to copy. + */ + void Clone(const DrawTileSprites *source) + { + assert(source != NULL && this != source); + this->ground = source->ground; + this->Clone(source->seq); + } + + virtual ~NewGRFSpriteLayout() + { + free(const_cast<DrawTileSeqStruct*>(this->seq)); + } +}; + +/** * Maps an entity id stored on the map to a GRF file. * Entities are objects used ingame (houses, industries, industry tiles) for * which we need to correlate the ids from the grf files with the ones in the diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 5edf44b28..6b041f0e6 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -37,8 +37,7 @@ RandomizedSpriteGroup::~RandomizedSpriteGroup() TileLayoutSpriteGroup::~TileLayoutSpriteGroup() { - free((void*)this->dts->seq); - free(this->dts); + delete this->dts; } TemporaryStorageArray<int32, 0x110> _temp_store; diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 2541195d9..3d4134af3 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -283,7 +283,7 @@ struct TileLayoutSpriteGroup : SpriteGroup { ~TileLayoutSpriteGroup(); byte num_building_stages; ///< Number of building stages to show for this house/industry tile - struct DrawTileSprites *dts; + NewGRFSpriteLayout *dts; }; struct IndustryProductionSpriteGroup : SpriteGroup { diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 7363c9e56..e82747bf7 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -77,7 +77,7 @@ struct StationSpec { * 6-7 = platform with roof, right side */ uint tiles; - DrawTileSprites *renderdata; ///< Array of tile layouts. + NewGRFSpriteLayout *renderdata; ///< Array of tile layouts. /** * Cargo threshold for choosing between little and lots of cargo diff --git a/src/sprite.cpp b/src/sprite.cpp index 4e41be4f1..e9a83052c 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -110,17 +110,3 @@ 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 9321ba534..acb19ed4e 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -52,9 +52,11 @@ struct DrawTileSeqStruct { } }; -const DrawTileSeqStruct *CopyDrawTileSeqStruct(const DrawTileSeqStruct *dtss); - -/** Ground palette sprite of a tile, together with its child sprites */ +/** + * Ground palette sprite of a tile, together with its sprite layout. + * This struct is used for static sprite layouts in the code. + * For allocated ones from NewGRF see #NewGRFSpriteLayout. + */ struct DrawTileSprites { PalSpriteID ground; ///< Palette and sprite for the ground const DrawTileSeqStruct *seq; ///< Array of child sprites. Terminated with a terminator entry |