summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-05-26 18:11:06 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-05-26 18:11:06 +0200
commite679da407d43b581afaf0539acea1143c022b245 (patch)
treea3798c7021559cc5fc66caa0350ec74edee4a015 /src
parent3e1349ce28eae928c8ecfd2ec9bfdde5147ad6a8 (diff)
w
Diffstat (limited to 'src')
-rw-r--r--src/hole-cut.cpp189
-rw-r--r--src/hole.cpp196
-rw-r--r--src/hole.hpp34
3 files changed, 248 insertions, 171 deletions
diff --git a/src/hole-cut.cpp b/src/hole-cut.cpp
new file mode 100644
index 00000000..f87a6c2f
--- /dev/null
+++ b/src/hole-cut.cpp
@@ -0,0 +1,189 @@
+#include "hole.hpp"
+#include "compat/array-size.hpp"
+#include "compat/iota.hpp"
+#include "compat/map.hpp"
+//#include <mg/Functions.h>
+
+#ifdef __GNUG__
+#pragma GCC diagnostic ignored "-Wswitch-default"
+//#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+namespace floormat {
+namespace {
+
+using bbox = cut_rectangle_result::bbox;
+using rect = cut_rectangle_result::rect;
+
+enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, };
+enum class location : uint8_t { R0, R1, H0, H1, };
+
+struct coords
+{
+ location x0 : 2;
+ location x1 : 2;
+ location y0 : 2;
+ location y1 : 2;
+};
+
+struct element
+{
+ uint8_t size;
+ std::array<coords, 8> array;
+};
+
+constexpr element make_element(uint8_t s)
+{
+ // ReSharper disable CppIdenticalOperandsInBinaryExpression
+ // NOLINTBEGIN(*-simplify)
+ switch (s)
+ {
+ using enum location;
+ case x0|x1|y0|y1: return element{1, {{ // 9.1
+ {R0, R1, R0, R1},
+ }}};
+ case __|__|__|__: return element{8, {{ // 14.1
+ {R0, H0, R0, H0},
+ {H0, H1, R0, H0},
+ {H1, R1, R0, H0},
+ {R0, H0, H0, H1},
+ {H1, R1, H0, H1},
+ {R0, H0, H1, R1},
+ {H0, H1, H0, R1},
+ {H1, R1, H1, R1},
+ }}};
+
+ case x0|x1|__|__: return element{2, {{ // 13.1
+ {R0, R1, R0, H0},
+ {R0, R1, H1, R1},
+ }}};
+ case __|__|y0|y1: return element{2, {{ // 13.2
+ {R0, H0, H1, R1},
+ {H1, R1, R0, R1},
+ }}};
+
+ case x0|x1|y0|__: return element{1, {{ // 12.1
+ {R0, R1, H1, R1},
+ }}};
+ case x0|x1|__|y1: return element{1, {{ // 12.2
+ {R0, R1, R0, H0},
+ }}};
+ case x0|__|y0|y1: return element{1, {{ // 12.3
+ {H1, R1, R0, R1},
+ }}};
+ case __|x1|y0|y1: return element{1, {{ // 12.4
+ {R0, H0, R0, R1},
+ }}};
+
+ case x0|__|__|__: return element{3, {{ // 10.1
+ {R0, R1, R0, H0},
+ {H1, R1, H0, H1},
+ {R0, R1, H1, R1},
+ }}};
+ case __|x1|__|__: return element{3, {{ // 10.2
+ {R0, R1, R0, H0},
+ {R0, H0, H0, H1},
+ {R0, R1, H1, R1},
+ }}};
+ case __|__|y0|__: return element{3, {{ // 10.3
+ {R0, H0, R0, R1},
+ {H0, H1, H0, R1},
+ {H1, R1, R0, R1},
+ }}};
+ case __|__|__|y1: return element{3, {{ // 10.4
+ {R0, H0, R0, R1},
+ {H0, H1, R0, H0},
+ {H1, R1, R0, R1},
+ }}};
+
+ case x0|__|y0|__: return element{2, {{ // 11.1
+ {H1, R1, R0, H1},
+ {R0, R1, H1, R1},
+ }}};
+ case __|x1|y0|__: return element{2, {{ // 11.2
+ {R0, H0, R0, H1},
+ {R0, R1, H1, R1},
+ }}};
+ case x0|__|__|y1: return element{2, {{ // 11.3
+ {R0, R1, R0, H0},
+ {H1, R1, H0, R1},
+ }}};
+ case __|x1|__|y1: return element{2, {{ // 11.4
+ {R0, R1, R0, H0},
+ {R0, H0, H0, H1},
+ }}};
+ }
+ // NOLINTEND(*-simplify)
+ // ReSharper restore CppIdenticalOperandsInBinaryExpression
+ std::unreachable();
+}
+
+constexpr auto elements = map(make_element, iota_array<uint8_t, 16>);
+
+constexpr auto get_value_from_coord(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, coords c)
+{
+ const auto xs = std::array{ r0.x(), r1.x(), h0.x(), h1.x(), };
+ const auto ys = std::array{ r0.y(), r1.y(), h0.y(), h1.y(), };
+ const auto x0 = xs[(uint8_t)c.x0];
+ const auto x1 = xs[(uint8_t)c.x1];
+ const auto y0 = ys[(uint8_t)c.y0];
+ const auto y1 = ys[(uint8_t)c.y1];
+ return rect{ Vector2i{x0, y0}, Vector2i{x1, y1} };
+}
+
+[[nodiscard]]
+constexpr bool
+check_empty(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, Vector2ub input_bb, Vector2ub hole_bb)
+{
+ bool iempty = Vector2ui{input_bb}.product() == 0;
+ bool hempty = Vector2ui{hole_bb}.product() == 0;
+ bool empty_before_x = h1.x() <= r0.x();
+ bool empty_after_x = h0.x() >= r1.x();
+ bool empty_before_y = h1.y() <= r0.y();
+ bool empty_after_y = h0.y() >= r1.y();
+
+ return iempty | hempty | empty_before_x | empty_after_x | empty_before_y | empty_after_y;
+}
+
+constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole)
+{
+ auto ihalf = Vector2i{input.bbox_size/2};
+ auto r0 = input.position - ihalf;
+ auto r1 = input.position + Vector2i{input.bbox_size} - ihalf;
+
+ auto hhalf = Vector2i{hole.bbox_size/2};
+ auto h0 = hole.position - hhalf;
+ auto h1 = hole.position + Vector2i{hole.bbox_size} - hhalf;
+
+ if (check_empty(r0, r1, h0, h1, input.bbox_size, hole.bbox_size))
+ return {0, {}};
+
+ const bool sx = h0.x() <= r0.x();
+ const bool ex = h1.x() >= r1.x();
+ const bool sy = h0.y() <= r0.y();
+ const bool ey = h1.y() >= r1.y();
+
+ auto val = uint8_t(sx << 0 | ex << 1 | sy << 2 | ey << 3);
+ CORRADE_ASSUME(val < 16);
+ const auto elt = elements[val];
+ cut_rectangle_result res = {
+ .size = elt.size,
+ .array = {},
+ };
+
+ const auto sz = elt.size;
+ CORRADE_ASSUME(sz <= 8);
+
+ for (auto i = 0u; i < sz; i++)
+ res.array[i] = get_value_from_coord(r0, r1, h0, h1, elt.array[i]);
+
+ return res;
+}
+
+} // namespace
+
+cut_rectangle_result cut_rectangle(bbox input, bbox hole)
+{
+ return cut_rectangleʹ(input, hole);
+}
+} // namespace floormat
diff --git a/src/hole.cpp b/src/hole.cpp
index 396d6d44..783fa5ee 100644
--- a/src/hole.cpp
+++ b/src/hole.cpp
@@ -1,190 +1,54 @@
#include "hole.hpp"
-#include "compat/array-size.hpp"
-#include "compat/iota.hpp"
-#include "compat/map.hpp"
-//#include <mg/Functions.h>
-
-#ifdef __GNUG__
-#pragma GCC diagnostic ignored "-Wswitch-default"
-//#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
+#include "chunk.hpp"
+#include "tile-constants.hpp"
+#include "shaders/shader.hpp"
namespace floormat {
namespace {
-using bbox = cut_rectangle_result::bbox;
-using rect = cut_rectangle_result::rect;
-
-enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, };
-enum class location : uint8_t { R0, R1, H0, H1, };
-
-struct coords
-{
- location x0 : 2;
- location x1 : 2;
- location y0 : 2;
- location y1 : 2;
-};
+} // namespace
-struct element
+hole::hole(object_id id, floormat::chunk& c, const hole_proto& proto):
+ object{id, c, proto}
{
- uint8_t size;
- std::array<coords, 8> array;
-};
+}
-constexpr element make_element(uint8_t s)
+hole::~hole() noexcept
{
- // ReSharper disable CppIdenticalOperandsInBinaryExpression
- // NOLINTBEGIN(*-simplify)
- switch (s)
- {
- using enum location;
- case x0|x1|y0|y1: return element{1, {{ // 9.1
- {R0, R1, R0, R1},
- }}};
- case __|__|__|__: return element{8, {{ // 14.1
- {R0, H0, R0, H0},
- {H0, H1, R0, H0},
- {H1, R1, R0, H0},
- {R0, H0, H0, H1},
- {H1, R1, H0, H1},
- {R0, H0, H1, R1},
- {H0, H1, H0, R1},
- {H1, R1, H1, R1},
- }}};
-
- case x0|x1|__|__: return element{2, {{ // 13.1
- {R0, R1, R0, H0},
- {R0, R1, H1, R1},
- }}};
- case __|__|y0|y1: return element{2, {{ // 13.2
- {R0, H0, H1, R1},
- {H1, R1, R0, R1},
- }}};
-
- case x0|x1|y0|__: return element{1, {{ // 12.1
- {R0, R1, H1, R1},
- }}};
- case x0|x1|__|y1: return element{1, {{ // 12.2
- {R0, R1, R0, H0},
- }}};
- case x0|__|y0|y1: return element{1, {{ // 12.3
- {H1, R1, R0, R1},
- }}};
- case __|x1|y0|y1: return element{1, {{ // 12.4
- {R0, H0, R0, R1},
- }}};
-
- case x0|__|__|__: return element{3, {{ // 10.1
- {R0, R1, R0, H0},
- {H1, R1, H0, H1},
- {R0, R1, H1, R1},
- }}};
- case __|x1|__|__: return element{3, {{ // 10.2
- {R0, R1, R0, H0},
- {R0, H0, H0, H1},
- {R0, R1, H1, R1},
- }}};
- case __|__|y0|__: return element{3, {{ // 10.3
- {R0, H0, R0, R1},
- {H0, H1, H0, R1},
- {H1, R1, R0, R1},
- }}};
- case __|__|__|y1: return element{3, {{ // 10.4
- {R0, H0, R0, R1},
- {H0, H1, R0, H0},
- {H1, R1, R0, R1},
- }}};
-
- case x0|__|y0|__: return element{2, {{ // 11.1
- {H1, R1, R0, H1},
- {R0, R1, H1, R1},
- }}};
- case __|x1|y0|__: return element{2, {{ // 11.2
- {R0, H0, R0, H1},
- {R0, R1, H1, R1},
- }}};
- case x0|__|__|y1: return element{2, {{ // 11.3
- {R0, R1, R0, H0},
- {H1, R1, H0, R1},
- }}};
- case __|x1|__|y1: return element{2, {{ // 11.4
- {R0, R1, R0, H0},
- {R0, H0, H0, H1},
- }}};
- }
- // NOLINTEND(*-simplify)
- // ReSharper restore CppIdenticalOperandsInBinaryExpression
- std::unreachable();
+ c->mark_ground_modified();
+ c->mark_walls_modified();
+ c->mark_passability_modified();
}
-constexpr auto elements = map(make_element, iota_array<uint8_t, 16>);
-
-constexpr auto get_value_from_coord(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, coords c)
+void hole::update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt)
{
- const auto xs = std::array{ r0.x(), r1.x(), h0.x(), h1.x(), };
- const auto ys = std::array{ r0.y(), r1.y(), h0.y(), h1.y(), };
- const auto x0 = xs[(uint8_t)c.x0];
- const auto x1 = xs[(uint8_t)c.x1];
- const auto y0 = ys[(uint8_t)c.y0];
- const auto y1 = ys[(uint8_t)c.y1];
- return rect{ Vector2i{x0, y0}, Vector2i{x1, y1} };
}
-[[nodiscard]]
-constexpr bool
-check_empty(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, Vector2ub input_bb, Vector2ub hole_bb)
+hole::operator hole_proto() const
{
- bool iempty = Vector2ui{input_bb}.product() == 0;
- bool hempty = Vector2ui{hole_bb}.product() == 0;
- bool empty_before_x = h1.x() <= r0.x();
- bool empty_after_x = h0.x() >= r1.x();
- bool empty_before_y = h1.y() <= r0.y();
- bool empty_after_y = h0.y() >= r1.y();
-
- return iempty | hempty | empty_before_x | empty_after_x | empty_before_y | empty_after_y;
+ hole_proto ret;
+ static_cast<object_proto&>(ret) = object_proto(*this);
+ ret.max_distance = max_distance;
+ ret.color = color;
+ ret.falloff = falloff;
+ ret.enabled = enabled;
+ return ret;
}
-constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole)
+float hole::depth_offset() const
{
- auto ihalf = Vector2i{input.bbox_size/2};
- auto r0 = input.position - ihalf;
- auto r1 = input.position + Vector2i{input.bbox_size} - ihalf;
-
- auto hhalf = Vector2i{hole.bbox_size/2};
- auto h0 = hole.position - hhalf;
- auto h1 = hole.position + Vector2i{hole.bbox_size} - hhalf;
-
- if (check_empty(r0, r1, h0, h1, input.bbox_size, hole.bbox_size))
- return {0, {}};
-
- const bool sx = h0.x() <= r0.x();
- const bool ex = h1.x() >= r1.x();
- const bool sy = h0.y() <= r0.y();
- const bool ey = h1.y() >= r1.y();
-
- auto val = uint8_t(sx << 0 | ex << 1 | sy << 2 | ey << 3);
- CORRADE_ASSUME(val < 16);
- const auto elt = elements[val];
- cut_rectangle_result res = {
- .size = elt.size,
- .array = {},
- };
-
- const auto sz = elt.size;
- CORRADE_ASSUME(sz <= 8);
-
- for (auto i = 0u; i < sz; i++)
- res.array[i] = get_value_from_coord(r0, r1, h0, h1, elt.array[i]);
-
- return res;
+ constexpr auto ret = 4 / tile_shader::depth_tile_size;
+ return ret;
}
-} // namespace
-
-cut_rectangle_result cut_rectangle(bbox input, bbox hole)
+Vector2 hole::ordinal_offset(Vector2b) const
{
- return cut_rectangleʹ(input, hole);
+ constexpr auto ret = Vector2(TILE_COUNT, TILE_COUNT) * TILE_SIZE2;
+ return ret;
}
+object_type hole::type() const noexcept { return object_type::hole; }
+bool hole::is_virtual() const { return true; }
+bool hole::is_dynamic() const { return false; }
+
} // namespace floormat
diff --git a/src/hole.hpp b/src/hole.hpp
index b7499ced..64e53149 100644
--- a/src/hole.hpp
+++ b/src/hole.hpp
@@ -6,16 +6,40 @@ namespace floormat {
struct hole_proto final : object_proto
{
- bool affects_render : 1 = true;
- bool affects_physics : 1 = false;
+ ~hole_proto() noexcept override;
+ hole_proto();
+ hole_proto(const hole_proto&);
+ hole_proto& operator=(const hole_proto&);
+ hole_proto(hole_proto&&) noexcept;
+ hole_proto& operator=(hole_proto&&) noexcept;
+ bool operator==(const hole_proto&) const;
+
+ uint8_t height = 0;
+ bool on_render : 1 = true;
+ bool on_physics : 1 = true;
+ bool is_wall : 1 = false;
};
-struct hole : object
+struct hole final : object
{
- bool affects_render : 1 = true;
- bool affects_physics : 1 = false;
+ uint8_t _height = 0;
+ const bool on_render : 1 = true;
+ const bool on_physics : 1 = true;
+ const bool is_wall : 1 = false;
hole(object_id id, class chunk& c, const hole_proto& proto);
+ ~hole() noexcept override;
+
+ Vector2 ordinal_offset(Vector2b offset) const override;
+ float depth_offset() const override;
+ object_type type() const noexcept override;
+ void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override;
+ bool is_dynamic() const override;
+ bool is_virtual() const override;
+
+ explicit operator hole_proto() const;
+
+ friend class world;
};
struct cut_rectangle_result