diff --git a/src/display.cpp b/src/display.cpp index 11045650ead..c5449fe9370 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -42,6 +42,7 @@ #include "play_controller.hpp" //note: this can probably be refactored out #include "reports.hpp" #include "resources.hpp" +#include "serialization/chrono.hpp" #include "synced_context.hpp" #include "team.hpp" #include "terrain/builder.hpp" @@ -1929,7 +1930,7 @@ void display::scroll_to_xy(const point& screen_coordinates, SCROLL_TYPE scroll_t events::pump(); auto time = std::chrono::steady_clock::now(); - auto dt = std::chrono::duration_cast(time - prev_time); + auto dt = fractional_seconds{time - prev_time}; // Do not skip too many frames on slow PCs dt = std::min(dt, 200ms); @@ -2208,8 +2209,7 @@ void display::fade_tod_mask( auto duration = 300ms / turbo_speed(); auto start = std::chrono::steady_clock::now(); for(auto now = start; now < start + duration; now = std::chrono::steady_clock::now()) { - float prop_f = float((now - start).count()) / float(duration.count()); - uint8_t p = float_to_color(prop_f); + uint8_t p = float_to_color(chrono::normalize_progress(now - start, duration)); tod_hex_alpha2 = p; tod_hex_alpha1 = ~p; draw_manager::invalidate_region(map_outside_area()); @@ -2242,8 +2242,7 @@ void display::fade_to(const color_t& c, const std::chrono::milliseconds& duratio // Smoothly blend and display for(auto now = start; now < start + duration; now = std::chrono::steady_clock::now()) { - float prop_f = float((now - start).count()) / float(duration.count()); - uint8_t p = float_to_color(prop_f); + uint8_t p = float_to_color(chrono::normalize_progress(now - start, duration)); fade_color_ = fade_start.smooth_blend(fade_end, p); draw_manager::invalidate_region(map_outside_area()); events::pump_and_draw(); diff --git a/src/gui/dialogs/outro.cpp b/src/gui/dialogs/outro.cpp index 8bac44dd1a8..bae05b4c0c8 100644 --- a/src/gui/dialogs/outro.cpp +++ b/src/gui/dialogs/outro.cpp @@ -22,6 +22,7 @@ #include "game_classification.hpp" #include "gettext.hpp" #include "gui/widgets/window.hpp" +#include "serialization/chrono.hpp" #include "serialization/markup.hpp" #include @@ -130,7 +131,7 @@ void outro::update() switch(stage_) { case stage::fading_in: if(now <= stage_start_ + fade_duration) { - window_canvas.set_variable("fade_alpha", wfl::variant(255.0 * get_fade_progress(now))); + window_canvas.set_variable("fade_alpha", wfl::variant(float_to_color(get_fade_progress(now)))); } else { goto_stage(stage::waiting); } @@ -146,7 +147,7 @@ void outro::update() case stage::fading_out: if(now <= stage_start_ + fade_duration) { - window_canvas.set_variable("fade_alpha", wfl::variant(255.0 * (1.0 - get_fade_progress(now)))); + window_canvas.set_variable("fade_alpha", wfl::variant(float_to_color(1.0 - get_fade_progress(now)))); } else if(++text_index_ < text_.size()) { window_canvas.set_variable("outro_text", wfl::variant(text_[text_index_])); goto_stage(stage::fading_in); @@ -165,9 +166,7 @@ void outro::update() double outro::get_fade_progress(const std::chrono::steady_clock::time_point& now) const { - using fractional_milliseconds = std::chrono::duration; - const auto time = fractional_milliseconds{now - stage_start_} / fade_duration; - return std::clamp(time, 0.0, 1.0); + return chrono::normalize_progress(now - stage_start_, fade_duration); } } // namespace dialogs diff --git a/src/serialization/chrono.hpp b/src/serialization/chrono.hpp index 4311523642e..24415a3fc33 100644 --- a/src/serialization/chrono.hpp +++ b/src/serialization/chrono.hpp @@ -16,6 +16,7 @@ #include "config_attribute_value.hpp" +#include #include #include #include @@ -72,6 +73,14 @@ inline auto parse_duration(const config_attribute_value& val, const Duration& de return Duration{val.to_long_long(def.count())}; } +template +constexpr double normalize_progress( + const std::chrono::duration& elapsed, + const std::chrono::duration& duration) +{ + return std::clamp(std::chrono::duration{elapsed} / duration, 0.0, 1.0); +} + template constexpr auto deconstruct_duration(const std::tuple&, const std::chrono::duration& span) {