mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: create MutableSpriteCache to remove the need to cast Vehicle to a mutable type in render methods
This commit is contained in:
parent
eeb88e87d8
commit
9b28b15e67
|
@ -341,8 +341,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = u->build_year = _cur_year;
|
v->build_year = u->build_year = _cur_year;
|
||||||
|
|
||||||
v->sprite_seq.Set(SPR_IMG_QUERY);
|
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
|
||||||
u->sprite_seq.Set(SPR_IMG_QUERY);
|
u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
|
||||||
|
|
||||||
v->random_bits = VehicleRandomBits();
|
v->random_bits = VehicleRandomBits();
|
||||||
u->random_bits = VehicleRandomBits();
|
u->random_bits = VehicleRandomBits();
|
||||||
|
@ -374,7 +374,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
|
||||||
w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
|
w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
|
||||||
w->spritenum = 0xFF;
|
w->spritenum = 0xFF;
|
||||||
w->subtype = AIR_ROTOR;
|
w->subtype = AIR_ROTOR;
|
||||||
w->sprite_seq.Set(SPR_ROTOR_STOPPED);
|
w->sprite_cache.sprite_seq.Set(SPR_ROTOR_STOPPED);
|
||||||
w->random_bits = VehicleRandomBits();
|
w->random_bits = VehicleRandomBits();
|
||||||
/* Use rotor's air.state to store the rotor animation frame */
|
/* Use rotor's air.state to store the rotor animation frame */
|
||||||
w->state = HRS_ROTOR_STOPPED;
|
w->state = HRS_ROTOR_STOPPED;
|
||||||
|
@ -497,7 +497,7 @@ static void HelicopterTickHandler(Aircraft *v)
|
||||||
if (spd == 0) {
|
if (spd == 0) {
|
||||||
u->state = HRS_ROTOR_STOPPED;
|
u->state = HRS_ROTOR_STOPPED;
|
||||||
GetRotorImage(v, EIT_ON_MAP, &seq);
|
GetRotorImage(v, EIT_ON_MAP, &seq);
|
||||||
if (u->sprite_seq == seq) return;
|
if (u->sprite_cache.sprite_seq == seq) return;
|
||||||
} else if (tick >= spd) {
|
} else if (tick >= spd) {
|
||||||
u->tick_counter = 0;
|
u->tick_counter = 0;
|
||||||
u->state++;
|
u->state++;
|
||||||
|
@ -507,7 +507,7 @@ static void HelicopterTickHandler(Aircraft *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->sprite_seq = seq;
|
u->sprite_cache.sprite_seq = seq;
|
||||||
|
|
||||||
u->UpdatePositionAndViewport();
|
u->UpdatePositionAndViewport();
|
||||||
}
|
}
|
||||||
|
@ -528,7 +528,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
v->UpdateViewport(true, false);
|
v->UpdateViewport(true, false);
|
||||||
if (v->subtype == AIR_HELICOPTER) {
|
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();
|
Aircraft *u = v->Next();
|
||||||
|
@ -540,7 +540,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
|
||||||
|
|
||||||
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
||||||
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
|
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();
|
u->UpdatePositionAndViewport();
|
||||||
|
|
||||||
|
@ -1278,7 +1278,7 @@ void Aircraft::MarkDirty()
|
||||||
this->colourmap = PAL_NONE;
|
this->colourmap = PAL_NONE;
|
||||||
this->UpdateViewport(true, false);
|
this->UpdateViewport(true, false);
|
||||||
if (this->subtype == AIR_HELICOPTER) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -439,7 +439,7 @@ void AddArticulatedParts(Vehicle *first)
|
||||||
v->max_age = 0;
|
v->max_age = 0;
|
||||||
v->engine_type = engine_type;
|
v->engine_type = engine_type;
|
||||||
v->value = 0;
|
v->value = 0;
|
||||||
v->sprite_seq.Set(SPR_IMG_QUERY);
|
v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
|
||||||
v->random_bits = VehicleRandomBits();
|
v->random_bits = VehicleRandomBits();
|
||||||
|
|
||||||
if (flip_image) v->spritenum++;
|
if (flip_image) v->spritenum++;
|
||||||
|
|
|
@ -110,7 +110,7 @@ void DisasterVehicle::UpdateImage()
|
||||||
{
|
{
|
||||||
SpriteID img = this->image_override;
|
SpriteID img = this->image_override;
|
||||||
if (img == 0) img = _disaster_images[this->subtype][this->direction];
|
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_Rotors(DisasterVehicle *v)
|
||||||
v->tick_counter++;
|
v->tick_counter++;
|
||||||
if (HasBit(v->tick_counter, 0)) return true;
|
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;
|
if (++cur_image > SPR_ROTOR_MOVING_3) cur_image = SPR_ROTOR_MOVING_1;
|
||||||
|
|
||||||
v->UpdatePositionAndViewport();
|
v->UpdatePositionAndViewport();
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
*/
|
*/
|
||||||
static bool IncrementSprite(EffectVehicle *v, SpriteID last)
|
static bool IncrementSprite(EffectVehicle *v, SpriteID last)
|
||||||
{
|
{
|
||||||
if (v->sprite_seq.seq[0].sprite != last) {
|
if (v->sprite_cache.sprite_seq.seq[0].sprite != last) {
|
||||||
v->sprite_seq.seq[0].sprite++;
|
v->sprite_cache.sprite_seq.seq[0].sprite++;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -39,7 +39,7 @@ static bool IncrementSprite(EffectVehicle *v, SpriteID last)
|
||||||
static void ChimneySmokeInit(EffectVehicle *v)
|
static void ChimneySmokeInit(EffectVehicle *v)
|
||||||
{
|
{
|
||||||
uint32 r = Random();
|
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);
|
v->progress = GB(r, 16, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) {
|
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->progress = 7;
|
||||||
v->UpdatePositionAndViewport();
|
v->UpdatePositionAndViewport();
|
||||||
|
@ -66,7 +66,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void SteamSmokeInit(EffectVehicle *v)
|
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;
|
v->progress = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ static bool SteamSmokeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void DieselSmokeInit(EffectVehicle *v)
|
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;
|
v->progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ static bool DieselSmokeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void ElectricSparkInit(EffectVehicle *v)
|
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;
|
v->progress = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ static bool ElectricSparkTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void SmokeInit(EffectVehicle *v)
|
static void SmokeInit(EffectVehicle *v)
|
||||||
{
|
{
|
||||||
v->sprite_seq.Set(SPR_SMOKE_0);
|
v->sprite_cache.sprite_seq.Set(SPR_SMOKE_0);
|
||||||
v->progress = 12;
|
v->progress = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ static bool SmokeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void ExplosionLargeInit(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;
|
v->progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ static bool ExplosionLargeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void BreakdownSmokeInit(EffectVehicle *v)
|
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;
|
v->progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
|
||||||
v->progress++;
|
v->progress++;
|
||||||
if ((v->progress & 7) == 0) {
|
if ((v->progress & 7) == 0) {
|
||||||
if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) {
|
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();
|
v->UpdatePositionAndViewport();
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void ExplosionSmallInit(EffectVehicle *v)
|
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;
|
v->progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ static bool ExplosionSmallTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void BulldozerInit(EffectVehicle *v)
|
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->progress = 0;
|
||||||
v->animation_state = 0;
|
v->animation_state = 0;
|
||||||
v->animation_substate = 0;
|
v->animation_substate = 0;
|
||||||
|
@ -289,7 +289,7 @@ static bool BulldozerTick(EffectVehicle *v)
|
||||||
if ((v->progress & 7) == 0) {
|
if ((v->progress & 7) == 0) {
|
||||||
const BulldozerMovement *b = &_bulldozer_movement[v->animation_state];
|
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->x_pos += _inc_by_dir[b->direction].x;
|
||||||
v->y_pos += _inc_by_dir[b->direction].y;
|
v->y_pos += _inc_by_dir[b->direction].y;
|
||||||
|
@ -311,7 +311,7 @@ static bool BulldozerTick(EffectVehicle *v)
|
||||||
|
|
||||||
static void BubbleInit(EffectVehicle *v)
|
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->spritenum = 0;
|
||||||
v->progress = 0;
|
v->progress = 0;
|
||||||
}
|
}
|
||||||
|
@ -474,8 +474,8 @@ static bool BubbleTick(EffectVehicle *v)
|
||||||
if ((v->progress & 3) != 0) return true;
|
if ((v->progress & 3) != 0) return true;
|
||||||
|
|
||||||
if (v->spritenum == 0) {
|
if (v->spritenum == 0) {
|
||||||
v->sprite_seq.seq[0].sprite++;
|
v->sprite_cache.sprite_seq.seq[0].sprite++;
|
||||||
if (v->sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
|
if (v->sprite_cache.sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
|
||||||
v->UpdatePositionAndViewport();
|
v->UpdatePositionAndViewport();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ static bool BubbleTick(EffectVehicle *v)
|
||||||
v->x_pos += b->x;
|
v->x_pos += b->x;
|
||||||
v->y_pos += b->y;
|
v->y_pos += b->y;
|
||||||
v->z_pos += b->z;
|
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();
|
v->UpdatePositionAndViewport();
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = _cur_year;
|
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->random_bits = VehicleRandomBits();
|
||||||
v->SetFrontEngine();
|
v->SetFrontEngine();
|
||||||
|
|
||||||
|
|
|
@ -1153,7 +1153,7 @@ static const OldChunks vehicle_chunk[] = {
|
||||||
|
|
||||||
OCL_SVAR( OC_UINT8, Vehicle, owner ),
|
OCL_SVAR( OC_UINT8, Vehicle, owner ),
|
||||||
OCL_SVAR( OC_TILE, Vehicle, tile ),
|
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
|
OCL_NULL( 8 ), ///< Vehicle sprite box, calculated automatically
|
||||||
|
|
||||||
|
@ -1246,7 +1246,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
|
||||||
if (v == nullptr) continue;
|
if (v == nullptr) continue;
|
||||||
v->refit_cap = v->cargo_cap;
|
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 */
|
/* no need to override other sprites */
|
||||||
if (IsInsideMM(sprite, 1460, 1465)) {
|
if (IsInsideMM(sprite, 1460, 1465)) {
|
||||||
sprite += 580; // aircraft smoke puff
|
sprite += 580; // aircraft smoke puff
|
||||||
|
@ -1257,7 +1257,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
|
||||||
} else if (IsInsideMM(sprite, 2516, 2539)) {
|
} else if (IsInsideMM(sprite, 2516, 2539)) {
|
||||||
sprite += 1385; // rotor or disaster-related vehicles
|
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) {
|
switch (v->type) {
|
||||||
case VEH_TRAIN: {
|
case VEH_TRAIN: {
|
||||||
|
|
|
@ -445,21 +445,21 @@ void AfterLoadVehicles(bool part_of_load)
|
||||||
case VEH_ROAD:
|
case VEH_ROAD:
|
||||||
case VEH_TRAIN:
|
case VEH_TRAIN:
|
||||||
case VEH_SHIP:
|
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;
|
break;
|
||||||
|
|
||||||
case VEH_AIRCRAFT:
|
case VEH_AIRCRAFT:
|
||||||
if (Aircraft::From(v)->IsNormalAircraft()) {
|
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 */
|
/* The plane's shadow will have the same image as the plane, but no colour */
|
||||||
Vehicle *shadow = v->Next();
|
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 */
|
/* In the case of a helicopter we will update the rotor sprites */
|
||||||
if (v->subtype == AIR_HELICOPTER) {
|
if (v->subtype == AIR_HELICOPTER) {
|
||||||
Vehicle *rotor = shadow->Next();
|
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);
|
UpdateAircraftCache(Aircraft::From(v), true);
|
||||||
|
@ -808,7 +808,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
||||||
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164),
|
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_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_CONDNULL(5, SL_MIN_VERSION, SLV_59),
|
||||||
SLE_VAR(Vehicle, progress, SLE_UINT8),
|
SLE_VAR(Vehicle, progress, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
||||||
|
@ -848,7 +848,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
||||||
SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
|
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_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_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||||
SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
|
SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
|
||||||
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
|
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
|
||||||
|
|
|
@ -864,7 +864,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||||
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
|
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = _cur_year;
|
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->random_bits = VehicleRandomBits();
|
||||||
|
|
||||||
v->UpdateCache();
|
v->UpdateCache();
|
||||||
|
|
|
@ -624,7 +624,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const
|
||||||
|
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = _cur_year;
|
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->random_bits = VehicleRandomBits();
|
||||||
|
|
||||||
v->group_id = DEFAULT_GROUP;
|
v->group_id = DEFAULT_GROUP;
|
||||||
|
@ -690,7 +690,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
|
||||||
u->engine_type = v->engine_type;
|
u->engine_type = v->engine_type;
|
||||||
u->date_of_last_service = v->date_of_last_service;
|
u->date_of_last_service = v->date_of_last_service;
|
||||||
u->build_year = v->build_year;
|
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();
|
u->random_bits = VehicleRandomBits();
|
||||||
v->SetMultiheaded();
|
v->SetMultiheaded();
|
||||||
u->SetMultiheaded();
|
u->SetMultiheaded();
|
||||||
|
@ -756,7 +756,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin
|
||||||
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
|
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = _cur_year;
|
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->random_bits = VehicleRandomBits();
|
||||||
|
|
||||||
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
|
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
|
||||||
|
|
|
@ -1094,25 +1094,19 @@ static void DoDrawVehicle(const Vehicle *v)
|
||||||
/*
|
/*
|
||||||
* If the vehicle sprite was not updated despite further viewport changes, we need
|
* If the vehicle sprite was not updated despite further viewport changes, we need
|
||||||
* to update it before drawing.
|
* 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) {
|
if (v->sprite_cache.sprite_has_viewport_changes) {
|
||||||
Vehicle* v_mutable = const_cast<Vehicle*>(v);
|
|
||||||
VehicleSpriteSeq seq;
|
VehicleSpriteSeq seq;
|
||||||
v_mutable->GetImage(v_mutable->direction, EIT_ON_MAP, &seq);
|
v->GetImage(v->direction, EIT_ON_MAP, &seq);
|
||||||
v_mutable->sprite_seq = seq;
|
v->sprite_cache.sprite_seq = seq;
|
||||||
v_mutable->rstate.sprite_has_viewport_changes = false;
|
v->sprite_cache.sprite_has_viewport_changes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
for (uint i = 0; i < v->sprite_seq.count; ++i) {
|
for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
|
||||||
PaletteID pal2 = v->sprite_seq.seq[i].pal;
|
PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
|
||||||
if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = 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);
|
v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
|
||||||
}
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
|
@ -1175,10 +1169,10 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
|
||||||
* are part of a newgrf vehicle set which changes bounding boxes within a
|
* are part of a newgrf vehicle set which changes bounding boxes within a
|
||||||
* single vehicle direction.
|
* 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->sprite_cache.is_viewport_candidate = true;
|
||||||
v_mutable->rstate.is_viewport_candidate = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v = v->hash_viewport_next;
|
v = v->hash_viewport_next;
|
||||||
|
@ -1605,7 +1599,7 @@ void Vehicle::UpdatePosition()
|
||||||
void Vehicle::UpdateViewport(bool dirty)
|
void Vehicle::UpdateViewport(bool dirty)
|
||||||
{
|
{
|
||||||
Rect new_coord;
|
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);
|
Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
|
||||||
new_coord.left += pt.x;
|
new_coord.left += pt.x;
|
||||||
|
|
|
@ -124,13 +124,6 @@ struct VehicleCache {
|
||||||
byte cached_vis_effect; ///< Visual effect to show (see #VisualEffect)
|
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. */
|
/** Sprite sequence for a vehicle part. */
|
||||||
struct VehicleSpriteSeq {
|
struct VehicleSpriteSeq {
|
||||||
PalSpriteID seq[4];
|
PalSpriteID seq[4];
|
||||||
|
@ -188,6 +181,17 @@ struct VehicleSpriteSeq {
|
||||||
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const;
|
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. */
|
/** A vehicle pool for a little over 1 million vehicles. */
|
||||||
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
|
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
|
||||||
extern VehiclePool _vehicle_pool;
|
extern VehiclePool _vehicle_pool;
|
||||||
|
@ -282,7 +286,6 @@ public:
|
||||||
* 0xff == reserved for another custom sprite
|
* 0xff == reserved for another custom sprite
|
||||||
*/
|
*/
|
||||||
byte spritenum;
|
byte spritenum;
|
||||||
VehicleSpriteSeq sprite_seq; ///< Vehicle appearance.
|
|
||||||
byte x_extent; ///< x-extent of vehicle bounding box
|
byte x_extent; ///< x-extent of vehicle bounding box
|
||||||
byte y_extent; ///< y-extent of vehicle bounding box
|
byte y_extent; ///< y-extent of vehicle bounding box
|
||||||
byte z_extent; ///< z-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
|
NewGRFCache grf_cache; ///< Cache of often used calculated NewGRF values
|
||||||
VehicleCache vcache; ///< Cache of often used vehicle 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);
|
Vehicle(VehicleType type = VEH_INVALID);
|
||||||
|
|
||||||
|
@ -1044,7 +1047,7 @@ struct SpecializedVehicle : public Vehicle {
|
||||||
*/
|
*/
|
||||||
inline SpecializedVehicle<T, Type>() : Vehicle(Type)
|
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 Vehicle {
|
||||||
* there won't be enough change in bounding box or offsets to need
|
* there won't be enough change in bounding box or offsets to need
|
||||||
* to resolve a new sprite.
|
* 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;
|
VehicleSpriteSeq seq;
|
||||||
|
|
||||||
((T*)this)->T::GetImage(this->direction, EIT_ON_MAP, &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;
|
sprite_has_changed = true;
|
||||||
this->sprite_seq = seq;
|
this->sprite_cache.sprite_seq = seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->rstate.last_direction = this->direction;
|
this->sprite_cache.last_direction = this->direction;
|
||||||
this->rstate.is_viewport_candidate = false;
|
this->sprite_cache.is_viewport_candidate = false;
|
||||||
this->rstate.sprite_has_viewport_changes = false;
|
this->sprite_cache.sprite_has_viewport_changes = false;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Changes could still be relevant when we render the vehicle even if
|
* Changes could still be relevant when we render the vehicle even if
|
||||||
* they don't alter the bounding box
|
* 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) {
|
if (force_update || sprite_has_changed) {
|
||||||
|
|
Loading…
Reference in New Issue