From 76f68c48f566eacb4582f7055303e52df080c9a4 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 2 Feb 2020 22:59:18 +0000 Subject: [PATCH] Cache whether vehicle is currently drawn: Vehicle::IsDrawn() --- src/aircraft_cmd.cpp | 5 +++++ src/disaster_vehicle.cpp | 1 + src/effectvehicle.cpp | 2 ++ src/rail_cmd.cpp | 2 ++ src/road_cmd.cpp | 1 + src/roadveh_cmd.cpp | 1 + src/saveload/afterload.cpp | 2 ++ src/ship_cmd.cpp | 1 + src/train_cmd.cpp | 3 +++ src/transparency.h | 3 +++ src/tunnelbridge_cmd.cpp | 4 ++++ src/vehicle.cpp | 15 ++++++++++++--- src/vehicle_base.h | 11 +++++++++-- 13 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index a8d60b586a..bfed28b455 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -577,9 +577,11 @@ void HandleAircraftEnterHangar(Aircraft *v) Aircraft *u = v->Next(); u->vehstatus |= VS_HIDDEN; + u->UpdateIsDrawn(); u = u->Next(); if (u != nullptr) { u->vehstatus |= VS_HIDDEN; + u->UpdateIsDrawn(); u->cur_speed = 0; } @@ -1493,14 +1495,17 @@ void AircraftLeaveHangar(Aircraft *v, Direction exit_dir) v->progress = 0; v->direction = exit_dir; v->vehstatus &= ~VS_HIDDEN; + v->UpdateIsDrawn(); { Vehicle *u = v->Next(); u->vehstatus &= ~VS_HIDDEN; + u->UpdateIsDrawn(); /* Rotor blades */ u = u->Next(); if (u != nullptr) { u->vehstatus &= ~VS_HIDDEN; + u->UpdateIsDrawn(); u->cur_speed = 80; } } diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 47b81c659d..1ed32e80da 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -180,6 +180,7 @@ DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubT this->owner = OWNER_NONE; this->image_override = 0; this->current_order.Free(); + this->UpdateIsDrawn(); this->UpdateImage(); this->UpdatePositionAndViewport(); diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp index 6b6d739735..6e606db454 100644 --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.cpp @@ -632,6 +632,8 @@ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) _effect_init_procs[type](v); + v->UpdateIsDrawn(); + v->UpdatePositionAndViewport(); v->AddEffectVehicleToTickCache(); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 7294e3060e..329018bcb9 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -3671,6 +3671,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int v->track = TRACK_BIT_DEPOT, v->vehstatus |= VS_HIDDEN; // hide it + v->UpdateIsDrawn(); v->direction = ReverseDir(v->direction); if (v->Next() == nullptr) VehicleEnterDepot(v->First()); v->tile = tile; @@ -3684,6 +3685,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int if ((v = v->Next()) != nullptr) { v->vehstatus &= ~VS_HIDDEN; v->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); + v->UpdateIsDrawn(); } } } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 83b2ca68c8..235a571961 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -2362,6 +2362,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int rv->direction = ReverseDir(rv->direction); if (rv->Next() == nullptr) VehicleEnterDepot(rv->First()); rv->tile = tile; + rv->UpdateIsDrawn(); InvalidateWindowData(WC_VEHICLE_DEPOT, rv->tile); return VETSB_ENTERED_WORMHOLE; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index e3e6e3592d..253a973f97 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1119,6 +1119,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) v->cur_image_valid_dir = INVALID_DIR; v->state = tdir; v->frame = RVC_DEPOT_START_FRAME; + v->UpdateIsDrawn(); v->x_pos = x; v->y_pos = y; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 01b6d1c345..3d007071f5 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3795,6 +3795,8 @@ bool AfterLoadGame() InvalidateVehicleTickCaches(); ClearVehicleTickCaches(); + UpdateAllVehiclesIsDrawn(); + extern void YapfCheckRailSignalPenalties(); YapfCheckRailSignalPenalties(); diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index af4448eca8..b2e3fce6c6 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -405,6 +405,7 @@ static bool CheckShipLeaveDepot(Ship *v) v->state = AxisToTrackBits(axis); v->vehstatus &= ~VS_HIDDEN; + v->UpdateIsDrawn(); v->cur_speed = 0; v->UpdateViewport(true, true); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 7916fca456..5652da6e45 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1835,6 +1835,8 @@ static void UpdateStatusAfterSwap(Train *v) /* Reverse the direction. */ if (v->track != TRACK_BIT_DEPOT) v->direction = ReverseDir(v->direction); + v->UpdateIsDrawn(); + /* Call the proper EnterTile function unless we are in a wormhole. */ if (!(v->track & TRACK_BIT_WORMHOLE)) { VehicleEnterTile(v, v->tile, v->x_pos, v->y_pos); @@ -2642,6 +2644,7 @@ static bool CheckTrainStayInDepot(Train *v) if (v->direction & 2) v->track = TRACK_BIT_Y; v->vehstatus &= ~VS_HIDDEN; + v->UpdateIsDrawn(); v->cur_speed = 0; v->UpdateViewport(true, true); diff --git a/src/transparency.h b/src/transparency.h index 08b13ca9b9..af64ee92a2 100644 --- a/src/transparency.h +++ b/src/transparency.h @@ -70,6 +70,9 @@ static inline bool IsInvisibilitySet(TransparencyOption to) static inline void ToggleTransparency(TransparencyOption to) { ToggleBit(_transparency_opt, to); + + extern void UpdateAllVehiclesIsDrawn(); + if (to == TO_TUNNELS) UpdateAllVehiclesIsDrawn(); } /** diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 0a57d12201..02208b866d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -2566,6 +2566,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti t->track = TRACK_BIT_WORMHOLE; if (Tunnel::GetByTile(tile)->is_chunnel) SetBit(t->gv_flags, GVF_CHUNNEL_BIT); t->vehstatus |= VS_HIDDEN; + t->UpdateIsDrawn(); return VETSB_ENTERED_WORMHOLE; } } @@ -2577,6 +2578,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti t->track = DiagDirToDiagTrackBits(vdir); assert(t->track); t->vehstatus &= ~VS_HIDDEN; + t->UpdateIsDrawn(); return VETSB_ENTERED_WORMHOLE; } } else if (v->type == VEH_ROAD) { @@ -2593,6 +2595,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti rv->state = RVSB_WORMHOLE; if (Tunnel::GetByTile(tile)->is_chunnel) SetBit(rv->gv_flags, GVF_CHUNNEL_BIT); rv->vehstatus |= VS_HIDDEN; + rv->UpdateIsDrawn(); return VETSB_ENTERED_WORMHOLE; } else { return VETSB_CONTINUE; @@ -2607,6 +2610,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti rv->state = DiagDirToDiagTrackdir(vdir); rv->frame = TILE_SIZE - (frame + 1); rv->vehstatus &= ~VS_HIDDEN; + rv->UpdateIsDrawn(); return VETSB_ENTERED_WORMHOLE; } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 452682e223..cd8a0e99aa 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -358,15 +358,22 @@ uint Vehicle::Crash(bool flooded) } /** - * Get whether a the vehicle should be drawn (i.e. if it isn't hidden, or it is in a tunnel but being shown transparently) + * Update cache of whether the vehicle should be drawn (i.e. if it isn't hidden, or it is in a tunnel but being shown transparently) * @return whether to show vehicle */ -bool Vehicle::IsDrawn() const +void Vehicle::UpdateIsDrawn() { - return !(HasBit(this->subtype, GVSF_VIRTUAL)) && (!(this->vehstatus & VS_HIDDEN) || + bool drawn = !(HasBit(this->subtype, GVSF_VIRTUAL)) && (!(this->vehstatus & VS_HIDDEN) || (IsTransparencySet(TO_TUNNELS) && ((this->type == VEH_TRAIN && Train::From(this)->track == TRACK_BIT_WORMHOLE) || (this->type == VEH_ROAD && RoadVehicle::From(this)->state == RVSB_WORMHOLE)))); + + SB(this->vcache.cached_veh_flags, VCF_IS_DRAWN, 1, drawn ? 1 : 0); +} + +void UpdateAllVehiclesIsDrawn() +{ + for (Vehicle *v : Vehicle::Iterate()) { v->UpdateIsDrawn(); } } /** @@ -2240,6 +2247,7 @@ void VehicleEnterDepot(Vehicle *v) SetWindowDirty(WC_VEHICLE_DEPOT, v->tile); v->vehstatus |= VS_HIDDEN; + v->UpdateIsDrawn(); v->cur_speed = 0; VehicleServiceInDepot(v); @@ -3847,6 +3855,7 @@ char *Vehicle::DumpVehicleFlags(char *b, const char *last) const b += seprintf(b, last, ", vcf:"); dump('l', HasBit(this->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT)); dump('z', HasBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST)); + dump('d', HasBit(this->vcache.cached_veh_flags, VCF_IS_DRAWN)); if (this->IsGroundVehicle()) { uint16 gv_flags = this->GetGroundVehicleFlags(); b += seprintf(b, last, ", gvf:"); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 159cd6197b..365e4e38cd 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -134,7 +134,8 @@ enum GroundVehicleSubtypeFlags { */ enum VehicleCacheFlags { VCF_LAST_VISUAL_EFFECT = 0, ///< Last vehicle in the consist with a visual effect. - VCF_GV_ZERO_SLOPE_RESIST = 1, ///< GrounVehicle: Consist has zero slope resistance (valid only for the first engine), may be false negative. + VCF_GV_ZERO_SLOPE_RESIST = 1, ///< GroundVehicle: Consist has zero slope resistance (valid only for the first engine), may be false negative. + VCF_IS_DRAWN = 2, ///< Vehicle is currently drawn }; /** Cached often queried values common to all vehicles. */ @@ -1093,7 +1094,12 @@ public: return v; } - bool IsDrawn() const; + bool IsDrawn() const + { + return HasBit(this->vcache.cached_veh_flags, VCF_IS_DRAWN); + } + + void UpdateIsDrawn(); inline void UpdateSpriteSeqBound() { @@ -1311,5 +1317,6 @@ inline void InvalidateVehicleTickCaches() void ClearVehicleTickCaches(); void RemoveFromOtherVehicleTickCache(const Vehicle *v); +void UpdateAllVehiclesIsDrawn(); #endif /* VEHICLE_BASE_H */