changeset 17681:ee997a9d7f63 draft

(svn r22456) -Codechange: Derive NewGRFSpriteLayout from DrawTileSprites for spritelayouts allocated on the heap, and make use of constructors and destructors.
author frosch <frosch@openttd.org>
date Sat, 14 May 2011 17:25:45 +0000
parents bbe4f200d1f2
children 5bef61d6741d
files src/newgrf.cpp src/newgrf_commons.cpp src/newgrf_commons.h src/newgrf_spritegroup.cpp src/newgrf_spritegroup.h src/newgrf_station.h src/sprite.cpp src/sprite.h
diffstat 8 files changed, 82 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -1222,19 +1222,16 @@
 
 			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;
-
-					dts->seq = NULL;
+					NewGRFSpriteLayout *dts = &statspec->renderdata[t];
+
 					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 @@
 
 					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 @@
 
 						MapSpriteMappingRecolour(&dtss->image);
 					}
+					dts->Clone(tmp_layout.Begin());
 				}
 				break;
 
@@ -1282,10 +1282,9 @@
 				}
 
 				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 @@
 					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 @@
 						}
 					}
 
-					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 @@
 						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 @@
 			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) {
--- a/src/newgrf_commons.cpp
+++ b/src/newgrf_commons.cpp
@@ -434,3 +434,34 @@
 	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;
+}
--- 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 @@
 };
 
 /**
+ * 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
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -37,8 +37,7 @@
 
 TileLayoutSpriteGroup::~TileLayoutSpriteGroup()
 {
-	free((void*)this->dts->seq);
-	free(this->dts);
+	delete this->dts;
 }
 
 TemporaryStorageArray<int32, 0x110> _temp_store;
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -283,7 +283,7 @@
 	~TileLayoutSpriteGroup();
 
 	byte num_building_stages;    ///< Number of building stages to show for this house/industry tile
-	struct DrawTileSprites *dts;
+	NewGRFSpriteLayout *dts;
 };
 
 struct IndustryProductionSpriteGroup : SpriteGroup {
--- a/src/newgrf_station.h
+++ b/src/newgrf_station.h
@@ -77,7 +77,7 @@
 	 * 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
--- a/src/sprite.cpp
+++ b/src/sprite.cpp
@@ -110,17 +110,3 @@
 		}
 	}
 }
-
-/** 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;
-}
--- a/src/sprite.h
+++ b/src/sprite.h
@@ -52,9 +52,11 @@
 	}
 };
 
-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