summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/newgrf.cpp35
-rw-r--r--src/newgrf_commons.cpp31
-rw-r--r--src/newgrf_commons.h30
-rw-r--r--src/newgrf_spritegroup.cpp3
-rw-r--r--src/newgrf_spritegroup.h2
-rw-r--r--src/newgrf_station.h2
-rw-r--r--src/sprite.cpp14
-rw-r--r--src/sprite.h8
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