Changeset - r17671:6321f2c5c4f2
[Not reviewed]
master
0 8 0
frosch - 13 years ago 2011-05-14 17:25:45
frosch@openttd.org
(svn r22456) -Codechange: Derive NewGRFSpriteLayout from DrawTileSprites for spritelayouts allocated on the heap, and make use of constructors and destructors.
8 files changed with 82 insertions and 45 deletions:
0 comments (0 inline, 0 general)
src/newgrf.cpp
Show inline comments
 
@@ -1219,39 +1219,38 @@ static ChangeInfoResult StationChangeInf
 
				(*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
 
				break;
 
			}
 

	
 
			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)) {
 
						/* Use sprite from Action 1 */
 
						ClrBit(dts->ground.pal, 15);
 
						SetBit(dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
 
					}
 

	
 
					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;
 
						dtss->delta_y = buf->ReadByte();
 
						dtss->delta_z = buf->ReadByte();
 
						dtss->size_x = buf->ReadByte();
 
@@ -1266,12 +1265,13 @@ static ChangeInfoResult StationChangeInf
 
							/* Use sprite from Action 1 (yes, this is inverse to above) */
 
							SetBit(dtss->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
 
						}
 

	
 
						MapSpriteMappingRecolour(&dtss->image);
 
					}
 
					dts->Clone(tmp_layout.Begin());
 
				}
 
				break;
 

	
 
			case 0x0A: { // Copy sprite layout
 
				byte srcid = buf->ReadByte();
 
				const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
 
@@ -1279,16 +1279,15 @@ static ChangeInfoResult StationChangeInf
 
				if (srcstatspec == NULL) {
 
					grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
 
					continue;
 
				}
 

	
 
				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;
 
			}
 

	
 
			case 0x0B: // Callback mask
 
				statspec->callback_mask = buf->ReadByte();
 
@@ -3944,13 +3943,13 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
					assert(TileLayoutSpriteGroup::CanAllocateItem());
 
					TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
 
					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();
 
					group->dts->ground.pal    = buf->ReadWord();
 

	
 
					/* Remap transparent/colour modifier bits */
 
@@ -3969,14 +3968,13 @@ static void NewSpriteGroup(ByteReader *b
 
							SB(group->dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
 
							ClrBit(group->dts->ground.pal, 15);
 
							SetBit(group->dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
 
						}
 
					}
 

	
 
					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]);
 

	
 
						seq->image.sprite = buf->ReadWord();
 
						seq->image.pal    = buf->ReadWord();
 
						seq->delta_x = buf->ReadByte();
 
@@ -4006,16 +4004,12 @@ static void NewSpriteGroup(ByteReader *b
 
						}
 

	
 
						seq->size_x = buf->ReadByte();
 
						seq->size_y = buf->ReadByte();
 
						seq->size_z = buf->ReadByte();
 
					}
 

	
 
					/* Set the terminator value. */
 
					const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].MakeTerminator();
 

	
 
					break;
 
				}
 

	
 
				case GSF_INDUSTRIES: {
 
					if (type > 1) {
 
						grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
 
@@ -7060,16 +7054,13 @@ static void ResetCustomStations()
 
		StationSpec **&stations = (*file)->stations;
 
		if (stations == NULL) continue;
 
		for (uint i = 0; i < MAX_STATIONS; i++) {
 
			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) {
 
				for (uint l = 0; l < statspec->lengths; l++) {
 
					for (uint p = 0; p < statspec->platforms[l]; p++) {
 
						free(statspec->layouts[l][p]);
src/newgrf_commons.cpp
Show inline comments
 
@@ -431,6 +431,37 @@ uint32 GetNearbyTileInformation(TileInde
 

	
 
	uint z;
 
	Slope tileh = GetTileSlope(tile, &z);
 
	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;
 
}
src/newgrf_commons.h
Show inline comments
 
@@ -13,21 +13,49 @@
 
 */
 

	
 
#ifndef NEWGRF_COMMONS_H
 
#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.
 
	TCX_ON_BRIDGE,      ///< Querying information about stuff on the bridge (via some bridgehead).
 
};
 

	
 
/**
 
 * 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
 
 * the savegames themselves.
 
 * An array of EntityIDMapping structs is saved with the savegame so
 
 * that those GRFs can be loaded in a different order, or removed safely. The
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -34,14 +34,13 @@ RandomizedSpriteGroup::~RandomizedSprite
 
{
 
	free((void*)this->groups);
 
}
 

	
 
TileLayoutSpriteGroup::~TileLayoutSpriteGroup()
 
{
 
	free((void*)this->dts->seq);
 
	free(this->dts);
 
	delete this->dts;
 
}
 

	
 
TemporaryStorageArray<int32, 0x110> _temp_store;
 

	
 

	
 
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
src/newgrf_spritegroup.h
Show inline comments
 
@@ -280,13 +280,13 @@ struct ResultSpriteGroup : SpriteGroup {
 

	
 
struct TileLayoutSpriteGroup : SpriteGroup {
 
	TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
 
	~TileLayoutSpriteGroup();
 

	
 
	byte num_building_stages;    ///< Number of building stages to show for this house/industry tile
 
	struct DrawTileSprites *dts;
 
	NewGRFSpriteLayout *dts;
 
};
 

	
 
struct IndustryProductionSpriteGroup : SpriteGroup {
 
	IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
 

	
 
	uint8 version;
src/newgrf_station.h
Show inline comments
 
@@ -74,13 +74,13 @@ struct StationSpec {
 
	 * 0-1 = plain platform
 
	 * 2-3 = platform with building
 
	 * 4-5 = platform with roof, left side
 
	 * 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
 
	 * @note little/lots are equivalent to the moving/loading states for vehicles
 
	 */
 
	uint16 cargo_threshold;
src/sprite.cpp
Show inline comments
 
@@ -107,20 +107,6 @@ void DrawCommonTileSeqInGUI(int x, int y
 
			int offs_x = child_offset_is_unsigned ? (uint8)dtss->delta_x : dtss->delta_x;
 
			int offs_y = child_offset_is_unsigned ? (uint8)dtss->delta_y : dtss->delta_y;
 
			DrawSprite(image, pal, x + child_offset.x + offs_x, y + child_offset.y + offs_y);
 
		}
 
	}
 
}
 

	
 
/** 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;
 
}
src/sprite.h
Show inline comments
 
@@ -49,15 +49,17 @@ struct DrawTileSeqStruct {
 
	bool IsParentSprite() const
 
	{
 
		return (byte)this->delta_z != 0x80;
 
	}
 
};
 

	
 
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
 
};
 

	
 
/**
0 comments (0 inline, 0 general)