summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/critter.cpp3
-rw-r--r--src/object.cpp31
-rw-r--r--src/object.hpp5
-rw-r--r--src/scenery.cpp2
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;