diff options
-rw-r--r-- | src/object.cpp | 2 | ||||
-rw-r--r-- | src/point.hpp | 3 | ||||
-rw-r--r-- | src/timer-ns.cpp | 71 | ||||
-rw-r--r-- | src/timer-test.cpp | 7 | ||||
-rw-r--r-- | src/timer.cpp | 17 | ||||
-rw-r--r-- | src/timer.hpp | 96 | ||||
-rw-r--r-- | test/critter.cpp | 23 |
7 files changed, 122 insertions, 97 deletions
diff --git a/src/object.cpp b/src/object.cpp index 521fa7b1..82c79d7d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -303,7 +303,7 @@ uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float 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 rem = (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); [[maybe_unused]] const auto old_accum = accum; diff --git a/src/point.hpp b/src/point.hpp index bd9c66ca..3b164ac3 100644 --- a/src/point.hpp +++ b/src/point.hpp @@ -34,6 +34,9 @@ struct point size_t hash() const; friend Debug& operator<<(Debug& dbg, const point& pt); + static constexpr uint32_t distance(point a, point b); + static constexpr uint32_t distance_l2(point a, point b); + private: int16_t cx = 0, cy = 0; int8_t cz = 0; diff --git a/src/timer-ns.cpp b/src/timer-ns.cpp index a705365e..5bc302ff 100644 --- a/src/timer-ns.cpp +++ b/src/timer-ns.cpp @@ -26,73 +26,6 @@ static_assert(MAX - HALF <= HALF+1); } // namespace -Ns operator+(const Ns& lhs, const Ns& rhs) -{ - constexpr auto max = (uint64_t)-1; - auto a = lhs.stamp, b = rhs.stamp; - fm_assert(max - a >= b); - return Ns{a + b}; -} - -Ns operator-(const Ns& lhs, const Ns& rhs) -{ - auto a = lhs.stamp, b = rhs.stamp; - fm_assert(a >= b); - return Ns{a - b}; -} - -uint64_t operator/(const Ns& lhs, const Ns& rhs) -{ - auto a = lhs.stamp, b = rhs.stamp; - fm_assert(b != 0); - return a / b; -} - -Ns operator/(const Ns& lhs, uint64_t b) -{ - auto a = lhs.stamp; - fm_assert(b != 0); - return Ns{a / b}; -} - -uint64_t operator%(const Ns& lhs, const Ns& rhs) -{ - auto a = lhs.stamp, b = rhs.stamp; - fm_assert(b != 0); - return a % b; -} - -Ns operator%(const Ns& lhs, uint64_t b) -{ - auto a = lhs.stamp; - fm_assert(b != 0); - return Ns{a % b}; -} - -bool operator==(const Ns& lhs, const Ns& rhs) -{ - auto a = lhs.stamp, b = rhs.stamp; - return a == b; -} - -std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs) -{ - auto a = lhs.stamp, b = rhs.stamp; - return a <=> b; -} - -Ns Ns::from_millis(uint64_t a) -{ - constexpr auto b = uint64_t(1e6); - const auto x = a * b; - fm_assert(a == 0 || x / a == b); - return Ns{x}; -}; - -Ns::operator uint64_t() const { return stamp; } -Ns::operator float() const { return float(stamp); } -uint64_t Ns::operator*() const { return stamp; } - Debug& operator<<(Debug& dbg, const Ns& box) { const auto value = (float)((double)box.stamp * 1e-6); @@ -109,10 +42,10 @@ Debug& operator<<(Debug& dbg, const Ns& box) auto flags = dbg.flags(); dbg << ""; dbg.setFlags(flags | Debug::Flag::NoSpace); - dbg << "{"; + //dbg << "{"; dbg << fraction(value, precision); dbg << " ms"; - dbg << "}"; + //dbg << "}"; dbg.setFlags(flags); return dbg; } diff --git a/src/timer-test.cpp b/src/timer-test.cpp new file mode 100644 index 00000000..e23443b7 --- /dev/null +++ b/src/timer-test.cpp @@ -0,0 +1,7 @@ +#include "timer.hpp" + +namespace floormat { + + + +} // namespace floormat diff --git a/src/timer.cpp b/src/timer.cpp index 8e9ed917..f67d7324 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -46,8 +46,21 @@ uint64_t Time::init() noexcept { return get_time(); } bool Time::operator==(const Time&) const noexcept = default; std::strong_ordering Time::operator<=>(const Time&) const noexcept = default; -float Time::to_seconds(const Ns& ts) noexcept { return float{ts} * 1e-9f; } -float Time::to_milliseconds(const Ns& ts) noexcept { return float{ts} * 1e-6f; } +double Time::to_seconds(const Ns& ts) noexcept +{ + auto x1 = double{ts}; + auto x2 = x1 * 1e-9; + fm_assert(x2 < double{1 << 24}); + return (float)x2; +} + +double Time::to_milliseconds(const Ns& ts) noexcept +{ + auto x1 = double{ts}; + auto x2 = x1 * 1e-6; + fm_assert(x2 < double{1 << 24}); + return (float)x2; +} const char* format_datetime_to_string(char (&buf)[fm_DATETIME_BUF_SIZE]) { diff --git a/src/timer.hpp b/src/timer.hpp index 45c41459..1350899b 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -8,20 +8,40 @@ struct Ns { explicit constexpr Ns(): stamp{0} {} explicit constexpr Ns(uint64_t x) : stamp{x} {} - static Ns from_millis(uint64_t x); + explicit constexpr operator uint64_t() const { return stamp; } + explicit constexpr operator double() const { return stamp; } + explicit constexpr operator float() const = delete; - explicit operator uint64_t() const; - explicit operator float() const; - uint64_t operator*() const; + static constexpr Ns from_millis(uint64_t a) + { + constexpr auto b = uint64_t(1e6); + const auto x = a * b; + fm_assert(a == 0 || x / a == b); + return Ns{x}; + } + + // ----- - friend Ns operator+(const Ns& lhs, const Ns& rhs); - friend Ns operator-(const Ns& lhs, const Ns& rhs); + friend constexpr Ns operator+(const Ns& lhs, const Ns& rhs) + { + constexpr auto max = (uint64_t)-1; + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(max - a >= b); + return Ns{a + b}; + } + + friend constexpr Ns operator-(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(a >= b); + return Ns{a - b}; + } friend Ns operator*(const Ns&, const Ns&) = delete; template<typename T> requires (std::is_integral_v<T> && std::is_unsigned_v<T>) - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { auto a = lhs.stamp, b = uint64_t{rhs}; auto x = a * b; @@ -31,18 +51,18 @@ struct Ns template<typename T> requires (std::is_integral_v<T> && std::is_signed_v<T> && sizeof(T) < sizeof(uint64_t)) - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { fm_assert(rhs >= T{0}); return lhs * uint64_t(rhs); } template<typename T> - friend Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + friend constexpr Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } template<typename T> requires std::is_same_v<float, T> - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { auto a = lhs.stamp; auto x = float(a) * float{rhs}; @@ -52,15 +72,53 @@ struct Ns template<typename T> requires std::is_same_v<float, T> - friend Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + friend constexpr Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + + friend constexpr uint64_t operator/(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(b != 0); + return a / b; + } - friend uint64_t operator/(const Ns& lhs, const Ns& rhs); - friend Ns operator/(const Ns& lhs, uint64_t rhs); - friend uint64_t operator%(const Ns& lhs, const Ns& rhs); - friend Ns operator%(const Ns& lhs, uint64_t rhs); + friend constexpr Ns operator/(const Ns& lhs, uint64_t b) + { + auto a = lhs.stamp; + fm_assert(b != 0); + return Ns{a / b}; + } + + friend constexpr uint64_t operator%(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(b != 0); + return a % b; + } + + friend constexpr Ns operator%(const Ns& lhs, uint64_t b) + { + auto a = lhs.stamp; + fm_assert(b != 0); + return Ns{a % b}; + } + + friend constexpr Ns& operator+=(Ns& lhs, const Ns& rhs) + { + constexpr auto max = (uint64_t)-1; + auto b = rhs.stamp; + fm_assert(max - lhs.stamp >= b); + lhs.stamp += b; + return lhs; + } + + friend constexpr bool operator==(const Ns& lhs, const Ns& rhs) = default; + + friend constexpr std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + return a <=> b; + } - friend bool operator==(const Ns& lhs, const Ns& rhs); - friend std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs); friend Debug& operator<<(Debug& dbg, const Ns& box); uint64_t stamp; @@ -76,8 +134,8 @@ struct Time final friend Ns operator-(const Time& lhs, const Time& rhs) noexcept; [[nodiscard]] Ns update(const Time& ts = now()) & noexcept; - static float to_seconds(const Ns& ts) noexcept; - static float to_milliseconds(const Ns& ts) noexcept; + static double to_seconds(const Ns& ts) noexcept; + static double to_milliseconds(const Ns& ts) noexcept; uint64_t stamp = init(); diff --git a/test/critter.cpp b/test/critter.cpp index cd041651..0a715657 100644 --- a/test/critter.cpp +++ b/test/critter.cpp @@ -31,8 +31,7 @@ void run(StringView name, const F& make_dt, critter& npc, const Ns max_time, Ns time{0}; uint32_t steps; - Debug{} << "=>" << name; - Debug{} << ">>" << npc.position(); + Debug{} << ">>" << name << npc.position(); auto last_pos = npc.position(); uint32_t i; @@ -50,15 +49,18 @@ void run(StringView name, const F& make_dt, critter& npc, const Ns max_time, break; } last_pos = pos; - Debug{} << "" << Vector2i(pos.local()) << pos.offset(); + Debug{} << Vector2i(pos.local()) << pos.offset(); fm_assert(i != max_steps); } if (stopped) - Debug{} << " break!"; + { + Debug{} << "===>" << i << "iters" << colon(',') << time; + // todo! calc distance + } else - Debug{} << " loop ends..."; + Debug{} << "!!! error: position doesn't converge after" << i << "iterations!"; } /* ***** TEST 1 ***** @@ -66,10 +68,15 @@ void run(StringView name, const F& make_dt, critter& npc, const Ns max_time, * wall n 0x0 - 8:9 * wall n 0x1 - 8:0 * - * npc speed=5 bbox-offset=0 bbox-size=32x32 + * bbox-offset=0 bbox-size=32x32 + * + * npc speed=1 ==> 6800 ms + * npc speed=5 ==> 1350 ms * * before chunk=0x0 tile=8:15 offset=-8:8 * after chunk=0x0 tile=8:9 offset=-8:-16 + * + * time=6800ms */ critter_proto make_proto(int accel) @@ -107,6 +114,10 @@ template<typename F> void test1(const F& make_dt, int accel) run("test1"_s, make_dt, *player, Second*20, init, N, end, Second*7, 16, Millisecond*350); } +/* ***** TEST 2 ***** + * + */ + template<typename F> void test2(F&& make_dt, int accel) { // TODO diagonal! |