diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/critter.cpp | 3 | ||||
-rw-r--r-- | src/object.cpp | 31 | ||||
-rw-r--r-- | src/object.hpp | 5 | ||||
-rw-r--r-- | src/scenery.cpp | 2 |
4 files changed, 19 insertions, 22 deletions
diff --git a/src/critter.cpp b/src/critter.cpp index 490aa757..96f7bc2a 100644 --- a/src/critter.cpp +++ b/src/critter.cpp @@ -156,7 +156,8 @@ void critter::update_movement(size_t i, Ns dt, rotation new_r) fm_assert(new_r < rotation_COUNT); fm_assert(is_dynamic()); - auto nframes = allocate_frame_time(dt, speed); + const auto hz = atlas->info().fps; + const auto nframes = allocate_frame_time<uint16_t>(dt, delta, hz, speed); if (nframes == 0) { //static unsigned foo; diff --git a/src/object.cpp b/src/object.cpp index 00df3793..93b80b7d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -7,6 +7,7 @@ #include "src/timer.hpp" #include "compat/debug.hpp" #include "compat/exception.hpp" +#include "compat/limits.hpp" #include <cmath> #include <algorithm> #include <Corrade/Containers/GrowableArray.h> @@ -287,23 +288,22 @@ bool object::move_to(Magnum::Vector2i delta) return move_to(i, delta, r); } -uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed) +template<typename T> requires std::is_unsigned_v<T> +uint32_t object::allocate_frame_time(Ns dt, T& accum, uint32_t hz, float speed) { constexpr auto ns_in_sec = Ns((int)1e9); - constexpr auto u16_max = uint64_t{65535}; + constexpr auto accum_max = uint64_t{limits<T>::max}; + static_assert(Ns{accum_max} * ns_in_sec.stamp != Ns{}); // check for overflow on T - fm_assert(hz > 0); - fm_assert(dt >= Ns{0}); - - const auto from_accum = uint64_t{accum} * ns_in_sec / u16_max; + const auto from_accum = uint64_t{accum} * ns_in_sec / accum_max; const auto from_dt = Ns(uint64_t(double(dt.stamp) * double(speed))); fm_assert(from_dt <= Ns{uint64_t{1} << 53}); const auto ticks = from_dt + from_accum; const auto frame_duration = ns_in_sec / hz; - const auto frames = (uint32_t)(ticks / frame_duration); + const auto nframes = (uint32_t)(ticks / frame_duration); const auto rem = ticks % frame_duration; - const auto new_accum_ = rem * u16_max / uint64_t{ns_in_sec}; - const auto new_accum = (uint16_t)Math::clamp(new_accum_, uint64_t{0}, u16_max); + const auto new_accum_ = rem * accum_max / uint64_t{ns_in_sec}; + const auto new_accum = (T)Math::clamp(new_accum_, uint64_t{0}, accum_max); [[maybe_unused]] const auto old_accum = accum; accum = new_accum; @@ -315,17 +315,12 @@ uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float << ", acc:" << new_accum_ << ", rem:" << rem; #endif - fm_assert(frames < 1 << 22); - return frames; + fm_assert(nframes < 1 << 12); + return nframes; } -uint32_t object::allocate_frame_time(Ns dt, float speed) -{ - fm_assert(atlas); - auto hz = atlas->info().fps; - fm_assert(hz > 0); - return allocate_frame_time(dt, delta, hz, speed); -} +template uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed); +template uint32_t object::allocate_frame_time(Ns dt, uint32_t& accum, uint32_t hz, float speed); void object::set_bbox_(Vector2b offset_, Vector2b bb_offset_, Vector2ub bb_size_, pass_mode pass_) { diff --git a/src/object.hpp b/src/object.hpp index 3976088e..97070e75 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -88,8 +88,9 @@ struct object void teleport_to(size_t& i, global_coords coord, Vector2b offset, rotation new_r); void teleport_to(size_t& i, point pt, rotation new_r); - static uint32_t allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed); - uint32_t allocate_frame_time(Ns dt, float speed); + template<typename T> + requires std::is_unsigned_v<T> + static uint32_t allocate_frame_time(Ns dt, T& accum, uint32_t hz, float speed); protected: object(object_id id, class chunk& c, const object_proto& proto); diff --git a/src/scenery.cpp b/src/scenery.cpp index 2666f912..277a76b5 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -89,7 +89,7 @@ void door_scenery::update(scenery& s, size_t, Ns dt) fm_assert(s.atlas); auto& anim = *s.atlas; const auto nframes = (int)anim.info().nframes; - const auto n = (int)s.allocate_frame_time(dt, 1); + const auto n = (int)s.allocate_frame_time<uint16_t>(dt, s.delta, s.atlas->info().fps, 1); if (n == 0) return; const int8_t dir = closing ? 1 : -1; |