From 1ff35cb6f9629365f3e54ab51d046e6dc1611bf0 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 1 Aug 2024 21:14:41 +0100 Subject: [PATCH] Codechange: Don't mark animated tiles dirty if frame is not changed. If animation is continued but the animation frame has not changed then there is no need to mark the tile for refresh. Loosely backport from JGRPP. --- src/base_station_base.h | 4 ++-- src/newgrf_animation_base.h | 17 ++++++++++++----- src/newgrf_roadstop.cpp | 2 +- src/station.cpp | 13 ++++++------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/base_station_base.h b/src/base_station_base.h index 0c0ad22770..72a5bb85ce 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -196,11 +196,11 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { } private: - void SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation); + bool SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation); public: inline void SetRoadStopRandomBits(TileIndex tile, uint8_t random_bits) { this->SetRoadStopTileData(tile, random_bits, false); } - inline void SetRoadStopAnimationFrame(TileIndex tile, uint8_t frame) { this->SetRoadStopTileData(tile, frame, true); } + inline bool SetRoadStopAnimationFrame(TileIndex tile, uint8_t frame) { return this->SetRoadStopTileData(tile, frame, true); } void RemoveRoadStopTileData(TileIndex tile); static void PostDestructor(size_t index); diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index af4562ffa2..ab919e2e84 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -20,7 +20,14 @@ template struct TileAnimationFrameAnimationHelper { static uint8_t Get(Tobj *, TileIndex tile) { return GetAnimationFrame(tile); } - static void Set(Tobj *, TileIndex tile, uint8_t frame) { SetAnimationFrame(tile, frame); } + static bool Set(Tobj *, TileIndex tile, uint8_t frame) + { + uint8_t prev_frame = GetAnimationFrame(tile); + if (prev_frame == frame) return false; + + SetAnimationFrame(tile, frame); + return true; + } }; /** @@ -105,8 +112,8 @@ struct AnimationBase { } } - Tframehelper::Set(obj, tile, frame); - MarkTileDirtyByTile(tile); + bool changed = Tframehelper::Set(obj, tile, frame); + if (changed) MarkTileDirtyByTile(tile); } /** @@ -131,8 +138,8 @@ struct AnimationBase { case 0xFE: AddAnimatedTile(tile, false); break; case 0xFF: DeleteAnimatedTile(tile); break; default: - Tframehelper::Set(obj, tile, callback); - AddAnimatedTile(tile); + bool changed = Tframehelper::Set(obj, tile, callback); + AddAnimatedTile(tile, changed); break; } diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 9b1af78519..16d38a0991 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -344,7 +344,7 @@ uint16_t GetAnimRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t struct RoadStopAnimationFrameAnimationHelper { static uint8_t Get(BaseStation *st, TileIndex tile) { return st->GetRoadStopAnimationFrame(tile); } - static void Set(BaseStation *st, TileIndex tile, uint8_t frame) { st->SetRoadStopAnimationFrame(tile, frame); } + static bool Set(BaseStation *st, TileIndex tile, uint8_t frame) { return st->SetRoadStopAnimationFrame(tile, frame); } }; /** Helper class for animation control. */ diff --git a/src/station.cpp b/src/station.cpp index e0dab59067..ab4ec70736 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -168,16 +168,14 @@ void BaseStation::PostDestructor(size_t) InvalidateWindowData(WC_SELECT_STATION, 0, 0); } -void BaseStation::SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation) +bool BaseStation::SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation) { for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) { if (tile_data.tile == tile) { - if (animation) { - tile_data.animation_frame = data; - } else { - tile_data.random_bits = data; - } - return; + uint8_t &v = animation ? tile_data.animation_frame : tile_data.random_bits; + if (v == data) return false; + v = data; + return true; } } RoadStopTileData tile_data; @@ -185,6 +183,7 @@ void BaseStation::SetRoadStopTileData(TileIndex tile, uint8_t data, bool animati tile_data.animation_frame = animation ? data : 0; tile_data.random_bits = animation ? 0 : data; this->custom_roadstop_tile_data.push_back(tile_data); + return data != 0; } void BaseStation::RemoveRoadStopTileData(TileIndex tile)