summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rotation.cpp29
-rw-r--r--src/rotation.hpp14
-rw-r--r--src/rotation.inl54
-rw-r--r--src/scenery.cpp87
-rw-r--r--src/scenery.hpp12
5 files changed, 105 insertions, 91 deletions
diff --git a/src/rotation.cpp b/src/rotation.cpp
new file mode 100644
index 00000000..7c0ea021
--- /dev/null
+++ b/src/rotation.cpp
@@ -0,0 +1,29 @@
+#include "rotation.inl"
+
+namespace floormat {
+
+/* N 0 -32 32 16
+ * E 32 0 16 32
+ * S 0 32 32 16
+ * W -32 0 16 32
+ */
+
+/* N 16 -32 32 16
+ * E 32 16 16 32
+ * S -16 32 32 16
+ * W -32 -16 16 32
+ */
+
+using bbox = Pair<Vector2b, Vector2ub>;
+
+static_assert(rotate_bbox({ 16, -32 }, { 32, 16 }, rotation::N, rotation::E) == bbox{{ 32, 16}, {16, 32}});
+static_assert(rotate_bbox({ 16, -32 }, { 32, 16 }, rotation::N, rotation::S) == bbox{{-16, 32}, {32, 16}});
+static_assert(rotate_bbox({ 16, -32 }, { 32, 16 }, rotation::N, rotation::W) == bbox{{-32, -16}, {16, 32}});
+static_assert(rotate_bbox({ 32, 16 }, { 16, 32 }, rotation::E, rotation::S) == bbox{{-16, 32}, {32, 16}});
+static_assert(rotate_bbox({ 32, 16 }, { 16, 32 }, rotation::E, rotation::N) == bbox{{ 16, -32}, {32, 16}});
+static_assert(rotate_bbox({ -32, -16 }, { 16, 32 }, rotation::W, rotation::S) == bbox{{-16, 32}, {32, 16}});
+
+static_assert(rotate_bbox({ 1, 2 }, { 3, 4 }, rotation::E, rotation::E) == bbox{{1, 2}, {3, 4}});
+static_assert(rotate_bbox({ 1, 2 }, { 3, 4 }, rotation::N, rotation::N) == bbox{{1, 2}, {3, 4}});
+
+} // namespace floormat
diff --git a/src/rotation.hpp b/src/rotation.hpp
new file mode 100644
index 00000000..39694336
--- /dev/null
+++ b/src/rotation.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include <cstddef>
+
+namespace floormat {
+
+enum class rotation : unsigned char {
+ N, NE, E, SE, S, SW, W, NW,
+};
+
+constexpr inline std::size_t rotation_BITS = 3;
+constexpr inline std::size_t rotation_MASK = (1 << rotation_BITS)-1;
+constexpr inline rotation rotation_COUNT = rotation{1 << rotation_BITS};
+
+} // namespace floormat
diff --git a/src/rotation.inl b/src/rotation.inl
new file mode 100644
index 00000000..8f9e6012
--- /dev/null
+++ b/src/rotation.inl
@@ -0,0 +1,54 @@
+#pragma once
+#include "compat/assert.hpp"
+#include "rotation.hpp"
+#include <Corrade/Containers/PairStl.h>
+#include <Corrade/Containers/TripleStl.h>
+#include <Magnum/Magnum.h>
+#include <Magnum/Math/Vector2.h>
+
+namespace floormat {
+
+constexpr Triple<Vector2b, Vector2ub, Vector2ub> rotation_symmetry(rotation r)
+{
+ constexpr Pair<rotation, Triple<Vector2b, Vector2ub, Vector2ub>> rotation_symmetries[] = {
+ { rotation::N, { { 1, 1}, {0, 1}, {0, 1} } },
+ { rotation::E, { {-1, 1}, {1, 0}, {1, 0} } },
+ { rotation::S, { {-1, -1}, {0, 1}, {0, 1} } },
+ { rotation::W, { { 1, -1}, {1, 0}, {1, 0} } },
+ };
+
+ fm_assert(r < rotation_COUNT);
+ auto idx = (std::size_t)r / 2;
+ const auto& [r1, sym] = rotation_symmetries[idx];
+ return sym;
+}
+
+constexpr Vector2b rotate_point(Vector2b rect, rotation r_old, rotation r_new)
+{
+ fm_assert(r_old < rotation_COUNT && r_new < rotation_COUNT);
+ auto [m_offset0, i_offset0, i_size0] = rotation_symmetry(r_old);
+ auto offset0_ = rect * m_offset0;
+ auto offset_n = Vector2b(offset0_[i_offset0[0]], offset0_[i_offset0[1]]);
+ auto [m_offset1, i_offset1, i_size1] = rotation_symmetry(r_new);
+ return Vector2b{offset_n[i_offset1[0]], offset_n[i_offset1[1]]}*m_offset1;
+}
+
+constexpr Vector2ub rotate_size(Vector2ub size0, rotation r_old, rotation r_new)
+{
+ fm_assert(r_old < rotation_COUNT && r_new < rotation_COUNT);
+ auto [m_offset0, i_offset0, i_size0] = rotation_symmetry(r_old);
+ auto size_n = Vector2ub(size0[i_size0[0]], size0[i_size0[1]]);
+ //fm_debug_assert(r_old != rotation::N || offset_n == offset0 && size_n == size0);
+ auto [m_offset1, i_offset1, i_size1] = rotation_symmetry(r_new);
+ return Vector2ub{size_n[i_size1[0]], size_n[i_size1[1]]};
+}
+
+constexpr Pair<Vector2b, Vector2ub> rotate_bbox(Vector2b offset0, Vector2ub size0, rotation r_old, rotation r_new)
+{
+ return {
+ rotate_point(offset0, r_old, r_new),
+ rotate_size(size0, r_old, r_new),
+ };
+}
+
+} // namespace floormat
diff --git a/src/scenery.cpp b/src/scenery.cpp
index eddada7b..90c33032 100644
--- a/src/scenery.cpp
+++ b/src/scenery.cpp
@@ -1,81 +1,11 @@
#include "scenery.hpp"
#include "anim-atlas.hpp"
#include "compat/assert.hpp"
+#include "rotation.inl"
#include <algorithm>
-#include <Corrade/Containers/PairStl.h>
-#include <Corrade/Containers/TripleStl.h>
namespace floormat {
-namespace {
-
-constexpr Pair<rotation, Triple<Vector2b, Vector2ub, Vector2ub>> rotation_symmetries[] = {
- { rotation::N, { { 1, 1}, {0, 1}, {0, 1} } },
- { rotation::E, { {-1, 1}, {1, 0}, {1, 0} } },
- { rotation::S, { {-1, -1}, {0, 1}, {0, 1} } },
- { rotation::W, { { 1, -1}, {1, 0}, {1, 0} } },
-};
-
-constexpr Triple<Vector2b, Vector2ub, Vector2ub> symmetry_for_rot(rotation r)
-{
- fm_assert(r < rotation_COUNT);
- auto idx = (std::size_t)r / 2;
- const auto& [r1, sym] = rotation_symmetries[idx];
- return sym;
-}
-
-constexpr Vector2b rotate_bbox_offset(Vector2b offset0, rotation r_old, rotation r_new)
-{
- fm_assert(r_old < rotation_COUNT && r_new < rotation_COUNT);
- auto [m_offset0, i_offset0, i_size0] = symmetry_for_rot(r_old);
- auto offset0_ = offset0 * m_offset0;
- auto offset_n = Vector2b(offset0_[i_offset0[0]], offset0_[i_offset0[1]]);
- auto [m_offset1, i_offset1, i_size1] = symmetry_for_rot(r_new);
- return Vector2b{offset_n[i_offset1[0]], offset_n[i_offset1[1]]}*m_offset1;
-}
-
-constexpr Vector2ub rotate_bbox_size(Vector2ub size0, rotation r_old, rotation r_new)
-{
- fm_assert(r_old < rotation_COUNT && r_new < rotation_COUNT);
- auto [m_offset0, i_offset0, i_size0] = symmetry_for_rot(r_old);
- auto size_n = Vector2ub(size0[i_size0[0]], size0[i_size0[1]]);
- //fm_debug_assert(r_old != rotation::N || offset_n == offset0 && size_n == size0);
- auto [m_offset1, i_offset1, i_size1] = symmetry_for_rot(r_new);
- return Vector2ub{size_n[i_size1[0]], size_n[i_size1[1]]};
-}
-
-constexpr Pair<Vector2b, Vector2ub> rotate_bbox_to(Vector2b offset0, Vector2ub size0, rotation r_old, rotation r_new)
-{
- return {
- rotate_bbox_offset(offset0, r_old, r_new),
- rotate_bbox_size(size0, r_old, r_new),
- };
-}
-
-/* N 0 -32 32 16
- * E 32 0 16 32
- * S 0 32 32 16
- * W -32 0 16 32
- */
-
-/* N 16 -32 32 16
- * E 32 16 16 32
- * S -16 32 32 16
- * W -32 -16 16 32
- */
-static_assert(rotate_bbox_to({ 16, -32}, {32, 16}, rotation::N, rotation::E) == Pair<Vector2b, Vector2ub>{{ 32, 16}, {16, 32}});
-static_assert(rotate_bbox_to({ 16, -32}, {32, 16}, rotation::N, rotation::S) == Pair<Vector2b, Vector2ub>{{-16, 32}, {32, 16}});
-static_assert(rotate_bbox_to({ 16, -32}, {32, 16}, rotation::N, rotation::W) == Pair<Vector2b, Vector2ub>{{-32, -16}, {16, 32}});
-
-static_assert(rotate_bbox_to({ 32, 16}, {16, 32}, rotation::E, rotation::S) == Pair<Vector2b, Vector2ub>{{-16, 32}, {32, 16}});
-static_assert(rotate_bbox_to({ 32, 16}, {16, 32}, rotation::E, rotation::N) == Pair<Vector2b, Vector2ub>{{ 16, -32}, {32, 16}});
-static_assert(rotate_bbox_to({-32, -16}, {16, 32}, rotation::W, rotation::S) == Pair<Vector2b, Vector2ub>{{-16, 32}, {32, 16}});
-
-static_assert(rotate_bbox_to({1, 2}, {3, 4}, rotation::E, rotation::E) == Pair<Vector2b, Vector2ub>{{1, 2}, {3, 4}});
-static_assert(rotate_bbox_to({1, 2}, {3, 4}, rotation::N, rotation::N) == Pair<Vector2b, Vector2ub>{{1, 2}, {3, 4}});
-
-} // namespace
-
scenery_proto::scenery_proto() noexcept = default;
scenery_proto::scenery_proto(const std::shared_ptr<anim_atlas>& atlas, const scenery& frame) noexcept :
atlas{atlas}, frame{frame}
@@ -104,8 +34,8 @@ scenery::scenery(generic_tag_t, const anim_atlas& atlas, rotation r, frame_t fra
Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) :
frame{frame},
offset{offset},
- bbox_offset{rotate_bbox_offset(bbox_offset, atlas.first_rotation(), r)},
- bbox_size{rotate_bbox_size(bbox_size, atlas.first_rotation(), r)},
+ bbox_offset{rotate_point(bbox_offset, atlas.first_rotation(), r)},
+ bbox_size{rotate_size(bbox_size, atlas.first_rotation(), r)},
r{r}, type{scenery_type::generic},
passability{passability},
active{active}, interactive{interactive}
@@ -118,8 +48,8 @@ scenery::scenery(door_tag_t, const anim_atlas& atlas, rotation r, bool is_open,
Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) :
frame{frame_t(is_open ? 0 : atlas.group(r).frames.size()-1)},
offset{offset},
- bbox_offset{rotate_bbox_offset(bbox_offset, atlas.first_rotation(), r)},
- bbox_size{rotate_bbox_size(bbox_size, atlas.first_rotation(), r)},
+ bbox_offset{rotate_point(bbox_offset, atlas.first_rotation(), r)},
+ bbox_size{rotate_size(bbox_size, atlas.first_rotation(), r)},
r{r}, type{scenery_type::door},
passability{is_open ? pass_mode::pass : pass_mode::blocked},
interactive{true}
@@ -128,13 +58,10 @@ scenery::scenery(door_tag_t, const anim_atlas& atlas, rotation r, bool is_open,
fm_assert(atlas.group(r).frames.size() >= 2);
}
-Vector2b scenery::rotate_bbox_offset(Vector2b offset, rotation old_r, rotation r) { return floormat::rotate_bbox_offset(offset, old_r, r); }
-Vector2ub scenery::rotate_bbox_size(Vector2ub size, rotation old_r, rotation r) { return floormat::rotate_bbox_size(size, old_r, r); }
-
void scenery::rotate(rotation new_r)
{
- bbox_offset = scenery::rotate_bbox_offset(bbox_offset, r, new_r);
- bbox_size = scenery::rotate_bbox_size(bbox_size, r, new_r);
+ bbox_offset = rotate_point(bbox_offset, r, new_r);
+ bbox_size = rotate_size(bbox_size, r, new_r);
r = new_r;
}
diff --git a/src/scenery.hpp b/src/scenery.hpp
index 3e950e90..9e58f612 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "pass-mode.hpp"
#include "tile-defs.hpp"
+#include "rotation.hpp"
#include <cstdint>
#include <memory>
#include <type_traits>
@@ -11,14 +12,6 @@ namespace floormat {
struct anim_atlas;
-enum class rotation : std::uint8_t {
- N, NE, E, SE, S, SW, W, NW,
-};
-
-constexpr inline std::size_t rotation_BITS = 3;
-constexpr inline std::size_t rotation_MASK = (1 << rotation_BITS)-1;
-constexpr inline rotation rotation_COUNT = rotation{1 << rotation_BITS};
-
enum class scenery_type : std::uint8_t {
none, generic, door,
};
@@ -60,9 +53,6 @@ struct scenery final
bool activate(const anim_atlas& atlas);
void update(float dt, const anim_atlas& anim);
void rotate(rotation r);
-
- static Vector2b rotate_bbox_offset(Vector2b offset, rotation old_r, rotation r);
- static Vector2ub rotate_bbox_size(Vector2ub size, rotation old_r, rotation r);
};
constexpr scenery::scenery() noexcept : scenery{scenery::none_tag_t{}} {}