Changeset - r24570:4fa1d23595bf
[Not reviewed]
master
0 11 0
Matt Kimber - 4 years ago 2021-01-03 13:32:58
github@mattkimber.org.uk
Codechange: create MutableSpriteCache to remove the need to cast Vehicle to a mutable type in render methods
11 files changed with 74 insertions and 77 deletions:
0 comments (0 inline, 0 general)
src/aircraft_cmd.cpp
Show inline comments
 
@@ -341,8 +341,8 @@ CommandCost CmdBuildAircraft(TileIndex t
 
		v->date_of_last_service = _date;
 
		v->build_year = u->build_year = _cur_year;
 

	
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		u->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 

	
 
		v->random_bits = VehicleRandomBits();
 
		u->random_bits = VehicleRandomBits();
 
@@ -374,7 +374,7 @@ CommandCost CmdBuildAircraft(TileIndex t
 
			w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
 
			w->spritenum = 0xFF;
 
			w->subtype = AIR_ROTOR;
 
			w->sprite_seq.Set(SPR_ROTOR_STOPPED);
 
			w->sprite_cache.sprite_seq.Set(SPR_ROTOR_STOPPED);
 
			w->random_bits = VehicleRandomBits();
 
			/* Use rotor's air.state to store the rotor animation frame */
 
			w->state = HRS_ROTOR_STOPPED;
 
@@ -497,7 +497,7 @@ static void HelicopterTickHandler(Aircra
 
	if (spd == 0) {
 
		u->state = HRS_ROTOR_STOPPED;
 
		GetRotorImage(v, EIT_ON_MAP, &seq);
 
		if (u->sprite_seq == seq) return;
 
		if (u->sprite_cache.sprite_seq == seq) return;
 
	} else if (tick >= spd) {
 
		u->tick_counter = 0;
 
		u->state++;
 
@@ -507,7 +507,7 @@ static void HelicopterTickHandler(Aircra
 
		return;
 
	}
 

	
 
	u->sprite_seq = seq;
 
	u->sprite_cache.sprite_seq = seq;
 

	
 
	u->UpdatePositionAndViewport();
 
}
 
@@ -528,7 +528,7 @@ void SetAircraftPosition(Aircraft *v, in
 
	v->UpdatePosition();
 
	v->UpdateViewport(true, false);
 
	if (v->subtype == AIR_HELICOPTER) {
 
		GetRotorImage(v, EIT_ON_MAP, &v->Next()->Next()->sprite_seq);
 
		GetRotorImage(v, EIT_ON_MAP, &v->Next()->Next()->sprite_cache.sprite_seq);
 
	}
 

	
 
	Aircraft *u = v->Next();
 
@@ -540,7 +540,7 @@ void SetAircraftPosition(Aircraft *v, in
 

	
 
	safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
 
	u->z_pos = GetSlopePixelZ(safe_x, safe_y);
 
	u->sprite_seq.CopyWithoutPalette(v->sprite_seq); // the shadow is never coloured
 
	u->sprite_cache.sprite_seq.CopyWithoutPalette(v->sprite_cache.sprite_seq); // the shadow is never coloured
 

	
 
	u->UpdatePositionAndViewport();
 

	
 
@@ -1278,7 +1278,7 @@ void Aircraft::MarkDirty()
 
	this->colourmap = PAL_NONE;
 
	this->UpdateViewport(true, false);
 
	if (this->subtype == AIR_HELICOPTER) {
 
		GetRotorImage(this, EIT_ON_MAP, &this->Next()->Next()->sprite_seq);
 
		GetRotorImage(this, EIT_ON_MAP, &this->Next()->Next()->sprite_cache.sprite_seq);
 
	}
 
}
 

	
src/articulated_vehicles.cpp
Show inline comments
 
@@ -439,7 +439,7 @@ void AddArticulatedParts(Vehicle *first)
 
		v->max_age = 0;
 
		v->engine_type = engine_type;
 
		v->value = 0;
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		v->random_bits = VehicleRandomBits();
 

	
 
		if (flip_image) v->spritenum++;
src/disaster_vehicle.cpp
Show inline comments
 
@@ -110,7 +110,7 @@ void DisasterVehicle::UpdateImage()
 
{
 
	SpriteID img = this->image_override;
 
	if (img == 0) img = _disaster_images[this->subtype][this->direction];
 
	this->sprite_seq.Set(img);
 
	this->sprite_cache.sprite_seq.Set(img);
 
}
 

	
 
/**
 
@@ -498,7 +498,7 @@ static bool DisasterTick_Helicopter_Roto
 
	v->tick_counter++;
 
	if (HasBit(v->tick_counter, 0)) return true;
 

	
 
	SpriteID &cur_image = v->sprite_seq.seq[0].sprite;
 
	SpriteID &cur_image = v->sprite_cache.sprite_seq.seq[0].sprite;
 
	if (++cur_image > SPR_ROTOR_MOVING_3) cur_image = SPR_ROTOR_MOVING_1;
 

	
 
	v->UpdatePositionAndViewport();
src/effectvehicle.cpp
Show inline comments
 
@@ -28,8 +28,8 @@
 
 */
 
static bool IncrementSprite(EffectVehicle *v, SpriteID last)
 
{
 
	if (v->sprite_seq.seq[0].sprite != last) {
 
		v->sprite_seq.seq[0].sprite++;
 
	if (v->sprite_cache.sprite_seq.seq[0].sprite != last) {
 
		v->sprite_cache.sprite_seq.seq[0].sprite++;
 
		return true;
 
	} else {
 
		return false;
 
@@ -39,7 +39,7 @@ static bool IncrementSprite(EffectVehicl
 
static void ChimneySmokeInit(EffectVehicle *v)
 
{
 
	uint32 r = Random();
 
	v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3));
 
	v->sprite_cache.sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3));
 
	v->progress = GB(r, 16, 3);
 
}
 

	
 
@@ -55,7 +55,7 @@ static bool ChimneySmokeTick(EffectVehic
 
		}
 

	
 
		if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) {
 
			v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0);
 
			v->sprite_cache.sprite_seq.Set(SPR_CHIMNEY_SMOKE_0);
 
		}
 
		v->progress = 7;
 
		v->UpdatePositionAndViewport();
 
@@ -66,7 +66,7 @@ static bool ChimneySmokeTick(EffectVehic
 

	
 
static void SteamSmokeInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_STEAM_SMOKE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_STEAM_SMOKE_0);
 
	v->progress = 12;
 
}
 

	
 
@@ -96,7 +96,7 @@ static bool SteamSmokeTick(EffectVehicle
 

	
 
static void DieselSmokeInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_DIESEL_SMOKE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_DIESEL_SMOKE_0);
 
	v->progress = 0;
 
}
 

	
 
@@ -120,7 +120,7 @@ static bool DieselSmokeTick(EffectVehicl
 

	
 
static void ElectricSparkInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_ELECTRIC_SPARK_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_ELECTRIC_SPARK_0);
 
	v->progress = 1;
 
}
 

	
 
@@ -143,7 +143,7 @@ static bool ElectricSparkTick(EffectVehi
 

	
 
static void SmokeInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_SMOKE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_SMOKE_0);
 
	v->progress = 12;
 
}
 

	
 
@@ -173,7 +173,7 @@ static bool SmokeTick(EffectVehicle *v)
 

	
 
static void ExplosionLargeInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_EXPLOSION_LARGE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_EXPLOSION_LARGE_0);
 
	v->progress = 0;
 
}
 

	
 
@@ -193,7 +193,7 @@ static bool ExplosionLargeTick(EffectVeh
 

	
 
static void BreakdownSmokeInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
 
	v->progress = 0;
 
}
 

	
 
@@ -202,7 +202,7 @@ static bool BreakdownSmokeTick(EffectVeh
 
	v->progress++;
 
	if ((v->progress & 7) == 0) {
 
		if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) {
 
			v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
 
			v->sprite_cache.sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
 
		}
 
		v->UpdatePositionAndViewport();
 
	}
 
@@ -218,7 +218,7 @@ static bool BreakdownSmokeTick(EffectVeh
 

	
 
static void ExplosionSmallInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_EXPLOSION_SMALL_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_EXPLOSION_SMALL_0);
 
	v->progress = 0;
 
}
 

	
 
@@ -238,7 +238,7 @@ static bool ExplosionSmallTick(EffectVeh
 

	
 
static void BulldozerInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_BULLDOZER_NE);
 
	v->sprite_cache.sprite_seq.Set(SPR_BULLDOZER_NE);
 
	v->progress = 0;
 
	v->animation_state = 0;
 
	v->animation_substate = 0;
 
@@ -289,7 +289,7 @@ static bool BulldozerTick(EffectVehicle 
 
	if ((v->progress & 7) == 0) {
 
		const BulldozerMovement *b = &_bulldozer_movement[v->animation_state];
 

	
 
		v->sprite_seq.Set(SPR_BULLDOZER_NE + b->image);
 
		v->sprite_cache.sprite_seq.Set(SPR_BULLDOZER_NE + b->image);
 

	
 
		v->x_pos += _inc_by_dir[b->direction].x;
 
		v->y_pos += _inc_by_dir[b->direction].y;
 
@@ -311,7 +311,7 @@ static bool BulldozerTick(EffectVehicle 
 

	
 
static void BubbleInit(EffectVehicle *v)
 
{
 
	v->sprite_seq.Set(SPR_BUBBLE_GENERATE_0);
 
	v->sprite_cache.sprite_seq.Set(SPR_BUBBLE_GENERATE_0);
 
	v->spritenum = 0;
 
	v->progress = 0;
 
}
 
@@ -474,8 +474,8 @@ static bool BubbleTick(EffectVehicle *v)
 
	if ((v->progress & 3) != 0) return true;
 

	
 
	if (v->spritenum == 0) {
 
		v->sprite_seq.seq[0].sprite++;
 
		if (v->sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
 
		v->sprite_cache.sprite_seq.seq[0].sprite++;
 
		if (v->sprite_cache.sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
 
			v->UpdatePositionAndViewport();
 
			return true;
 
		}
 
@@ -520,7 +520,7 @@ static bool BubbleTick(EffectVehicle *v)
 
	v->x_pos += b->x;
 
	v->y_pos += b->y;
 
	v->z_pos += b->z;
 
	v->sprite_seq.Set(SPR_BUBBLE_0 + b->image);
 
	v->sprite_cache.sprite_seq.Set(SPR_BUBBLE_0 + b->image);
 

	
 
	v->UpdatePositionAndViewport();
 

	
src/roadveh_cmd.cpp
Show inline comments
 
@@ -301,7 +301,7 @@ CommandCost CmdBuildRoadVehicle(TileInde
 
		v->date_of_last_service = _date;
 
		v->build_year = _cur_year;
 

	
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		v->random_bits = VehicleRandomBits();
 
		v->SetFrontEngine();
 

	
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -1153,7 +1153,7 @@ static const OldChunks vehicle_chunk[] =
 

	
 
	OCL_SVAR(  OC_UINT8, Vehicle, owner ),
 
	OCL_SVAR(   OC_TILE, Vehicle, tile ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_seq.seq[0].sprite ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_cache.sprite_seq.seq[0].sprite ),
 

	
 
	OCL_NULL( 8 ),        ///< Vehicle sprite box, calculated automatically
 

	
 
@@ -1246,7 +1246,7 @@ bool LoadOldVehicle(LoadgameState *ls, i
 
			if (v == nullptr) continue;
 
			v->refit_cap = v->cargo_cap;
 

	
 
			SpriteID sprite = v->sprite_seq.seq[0].sprite;
 
			SpriteID sprite = v->sprite_cache.sprite_seq.seq[0].sprite;
 
			/* no need to override other sprites */
 
			if (IsInsideMM(sprite, 1460, 1465)) {
 
				sprite += 580; // aircraft smoke puff
 
@@ -1257,7 +1257,7 @@ bool LoadOldVehicle(LoadgameState *ls, i
 
			} else if (IsInsideMM(sprite, 2516, 2539)) {
 
				sprite += 1385; // rotor or disaster-related vehicles
 
			}
 
			v->sprite_seq.seq[0].sprite = sprite;
 
			v->sprite_cache.sprite_seq.seq[0].sprite = sprite;
 

	
 
			switch (v->type) {
 
				case VEH_TRAIN: {
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -445,21 +445,21 @@ void AfterLoadVehicles(bool part_of_load
 
			case VEH_ROAD:
 
			case VEH_TRAIN:
 
			case VEH_SHIP:
 
				v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
 
				v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_cache.sprite_seq);
 
				break;
 

	
 
			case VEH_AIRCRAFT:
 
				if (Aircraft::From(v)->IsNormalAircraft()) {
 
					v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
 
					v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_cache.sprite_seq);
 

	
 
					/* The plane's shadow will have the same image as the plane, but no colour */
 
					Vehicle *shadow = v->Next();
 
					shadow->sprite_seq.CopyWithoutPalette(v->sprite_seq);
 
					shadow->sprite_cache.sprite_seq.CopyWithoutPalette(v->sprite_cache.sprite_seq);
 

	
 
					/* In the case of a helicopter we will update the rotor sprites */
 
					if (v->subtype == AIR_HELICOPTER) {
 
						Vehicle *rotor = shadow->Next();
 
						GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq);
 
						GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_cache.sprite_seq);
 
					}
 

	
 
					UpdateAircraftCache(Aircraft::From(v), true);
 
@@ -808,7 +808,7 @@ const SaveLoad *GetVehicleDescription(Ve
 
		 SLE_CONDVAR(Vehicle, z_pos,                 SLE_FILE_U8  | SLE_VAR_I32,   SL_MIN_VERSION, SLV_164),
 
		 SLE_CONDVAR(Vehicle, z_pos,                 SLE_INT32,                  SLV_164, SL_MAX_VERSION),
 

	
 
		     SLE_VAR(Vehicle, sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
 
		     SLE_VAR(Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
 
		SLE_CONDNULL(5,                                                            SL_MIN_VERSION,  SLV_59),
 
		     SLE_VAR(Vehicle, progress,              SLE_UINT8),
 
		     SLE_VAR(Vehicle, vehstatus,             SLE_UINT8),
 
@@ -848,7 +848,7 @@ const SaveLoad *GetVehicleDescription(Ve
 
		 SLE_CONDVAR(Vehicle, current_order.dest,    SLE_FILE_U8 | SLE_VAR_U16,    SL_MIN_VERSION,   SLV_5),
 
		 SLE_CONDVAR(Vehicle, current_order.dest,    SLE_UINT16,                   SLV_5, SL_MAX_VERSION),
 

	
 
		     SLE_VAR(Vehicle, sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
 
		     SLE_VAR(Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
 
		 SLE_CONDVAR(Vehicle, age,                   SLE_FILE_U16 | SLE_VAR_I32,   SL_MIN_VERSION,  SLV_31),
 
		 SLE_CONDVAR(Vehicle, age,                   SLE_INT32,                   SLV_31, SL_MAX_VERSION),
 
		     SLE_VAR(Vehicle, tick_counter,          SLE_UINT8),
src/ship_cmd.cpp
Show inline comments
 
@@ -864,7 +864,7 @@ CommandCost CmdBuildShip(TileIndex tile,
 
		v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
 
		v->date_of_last_service = _date;
 
		v->build_year = _cur_year;
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		v->random_bits = VehicleRandomBits();
 

	
 
		v->UpdateCache();
src/train_cmd.cpp
Show inline comments
 
@@ -624,7 +624,7 @@ static CommandCost CmdBuildRailWagon(Til
 

	
 
		v->date_of_last_service = _date;
 
		v->build_year = _cur_year;
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		v->random_bits = VehicleRandomBits();
 

	
 
		v->group_id = DEFAULT_GROUP;
 
@@ -690,7 +690,7 @@ static void AddRearEngineToMultiheadedTr
 
	u->engine_type = v->engine_type;
 
	u->date_of_last_service = v->date_of_last_service;
 
	u->build_year = v->build_year;
 
	u->sprite_seq.Set(SPR_IMG_QUERY);
 
	u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
	u->random_bits = VehicleRandomBits();
 
	v->SetMultiheaded();
 
	u->SetMultiheaded();
 
@@ -756,7 +756,7 @@ CommandCost CmdBuildRailVehicle(TileInde
 
		v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
 
		v->date_of_last_service = _date;
 
		v->build_year = _cur_year;
 
		v->sprite_seq.Set(SPR_IMG_QUERY);
 
		v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
 
		v->random_bits = VehicleRandomBits();
 

	
 
		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
src/vehicle.cpp
Show inline comments
 
@@ -1094,25 +1094,19 @@ static void DoDrawVehicle(const Vehicle 
 
	/*
 
	 * If the vehicle sprite was not updated despite further viewport changes, we need
 
	 * to update it before drawing.
 
	 *
 
	 * I'm not keen on casting to mutable - it's the approach JGR uses in JGRPP but I
 
	 * wonder if there's a cleaner option (even though we can only take the decision
 
	 * whether to update once we already know the vehicle is going to appear in a
 
	 * viewport)
 
	 */
 
	if (v->rstate.sprite_has_viewport_changes) {
 
		Vehicle* v_mutable = const_cast<Vehicle*>(v);
 
	if (v->sprite_cache.sprite_has_viewport_changes) {
 
		VehicleSpriteSeq seq;
 
		v_mutable->GetImage(v_mutable->direction, EIT_ON_MAP, &seq);
 
		v_mutable->sprite_seq = seq;
 
		v_mutable->rstate.sprite_has_viewport_changes = false;
 
		v->GetImage(v->direction, EIT_ON_MAP, &seq);
 
		v->sprite_cache.sprite_seq = seq;
 
		v->sprite_cache.sprite_has_viewport_changes = false;
 
	}
 

	
 
	StartSpriteCombine();
 
	for (uint i = 0; i < v->sprite_seq.count; ++i) {
 
		PaletteID pal2 = v->sprite_seq.seq[i].pal;
 
	for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
 
		PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
 
		if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
 
		AddSortableSpriteToDraw(v->sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
 
		AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
 
			v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
 
	}
 
	EndSpriteCombine();
 
@@ -1175,10 +1169,10 @@ void ViewportAddVehicles(DrawPixelInfo *
 
					 * are part of a newgrf vehicle set which changes bounding boxes within a
 
					 * single vehicle direction.
 
					 *
 
					 * TODO: is there a cleaner solution than casting to a mutable type?
 
					 * TODO: this will consider too many false positives, use the bounding box
 
					 * information or something which better narrows down the candidates.
 
					 */
 
					Vehicle* v_mutable = const_cast<Vehicle*>(v);
 
					v_mutable->rstate.is_viewport_candidate = true;
 
					v->sprite_cache.is_viewport_candidate = true;
 
				}
 

	
 
				v = v->hash_viewport_next;
 
@@ -1605,7 +1599,7 @@ void Vehicle::UpdatePosition()
 
void Vehicle::UpdateViewport(bool dirty)
 
{
 
	Rect new_coord;
 
	this->sprite_seq.GetBounds(&new_coord);
 
	this->sprite_cache.sprite_seq.GetBounds(&new_coord);
 

	
 
	Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
 
	new_coord.left   += pt.x;
src/vehicle_base.h
Show inline comments
 
@@ -124,13 +124,6 @@ struct VehicleCache {
 
	byte cached_vis_effect;  ///< Visual effect to show (see #VisualEffect)
 
};
 

	
 
/** Values for controlling how a vehicle's sprites are refreshed */
 
struct VehicleSpriteRefreshState {
 
	Direction last_direction;         ///< Last direction we obtained sprites for
 
	bool is_viewport_candidate;       ///< The vehicle has been in the hash for a shown viewport recently
 
	bool sprite_has_viewport_changes; ///< There have been viewport changes since the sprite was last updated
 
};
 

	
 
/** Sprite sequence for a vehicle part. */
 
struct VehicleSpriteSeq {
 
	PalSpriteID seq[4];
 
@@ -188,6 +181,17 @@ struct VehicleSpriteSeq {
 
	void Draw(int x, int y, PaletteID default_pal, bool force_pal) const;
 
};
 

	
 
/**
 
 * Cache for vehicle sprites and values relating to whether they should be updated before drawing,
 
 * or calculating the viewport.
 
 */
 
struct MutableSpriteCache {
 
	Direction last_direction;                 ///< Last direction we obtained sprites for
 
	mutable bool is_viewport_candidate;       ///< The vehicle has been in the hash for a shown viewport recently
 
	mutable bool sprite_has_viewport_changes; ///< There have been viewport changes since the sprite was last updated
 
	mutable VehicleSpriteSeq sprite_seq;      ///< Vehicle appearance.
 
};
 

	
 
/** A vehicle pool for a little over 1 million vehicles. */
 
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
 
extern VehiclePool _vehicle_pool;
 
@@ -282,7 +286,6 @@ public:
 
	 * 0xff == reserved for another custom sprite
 
	 */
 
	byte spritenum;
 
	VehicleSpriteSeq sprite_seq;        ///< Vehicle appearance.
 
	byte x_extent;                      ///< x-extent of vehicle bounding box
 
	byte y_extent;                      ///< y-extent of vehicle bounding box
 
	byte z_extent;                      ///< z-extent of vehicle bounding box
 
@@ -334,7 +337,7 @@ public:
 
	NewGRFCache grf_cache;              ///< Cache of often used calculated NewGRF values
 
	VehicleCache vcache;                ///< Cache of often used vehicle values.
 

	
 
	VehicleSpriteRefreshState rstate;   ///< Values relating to whether sprites should be refreshed, see #VehicleSpriteRefreshState
 
	MutableSpriteCache sprite_cache;    ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache
 

	
 
	Vehicle(VehicleType type = VEH_INVALID);
 

	
 
@@ -1044,7 +1047,7 @@ struct SpecializedVehicle : public Vehic
 
	 */
 
	inline SpecializedVehicle<T, Type>() : Vehicle(Type)
 
	{
 
		this->sprite_seq.count = 1;
 
		this->sprite_cache.sprite_seq.count = 1;
 
	}
 

	
 
	/**
 
@@ -1193,24 +1196,24 @@ struct SpecializedVehicle : public Vehic
 
		 * there won't be enough change in bounding box or offsets to need
 
		 * to resolve a new sprite.
 
		 */
 
		if (this->direction != this->rstate.last_direction || this->rstate.is_viewport_candidate) {
 
		if (this->direction != this->sprite_cache.last_direction || this->sprite_cache.is_viewport_candidate) {
 
			VehicleSpriteSeq seq;
 

	
 
			((T*)this)->T::GetImage(this->direction, EIT_ON_MAP, &seq);
 
			if (this->sprite_seq != seq) {
 
			if (this->sprite_cache.sprite_seq != seq) {
 
				sprite_has_changed = true;
 
				this->sprite_seq = seq;
 
				this->sprite_cache.sprite_seq = seq;
 
			}
 

	
 
			this->rstate.last_direction = this->direction;
 
			this->rstate.is_viewport_candidate = false;
 
			this->rstate.sprite_has_viewport_changes = false;
 
			this->sprite_cache.last_direction = this->direction;
 
			this->sprite_cache.is_viewport_candidate = false;
 
			this->sprite_cache.sprite_has_viewport_changes = false;
 
		} else {
 
			/*
 
			 * Changes could still be relevant when we render the vehicle even if
 
			 * they don't alter the bounding box
 
			 */
 
			this->rstate.sprite_has_viewport_changes = true;
 
			this->sprite_cache.sprite_has_viewport_changes = true;
 
		}
 

	
 
		if (force_update || sprite_has_changed) {
0 comments (0 inline, 0 general)