summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compat/assert.hpp51
-rw-r--r--compat/defs.hpp4
-rw-r--r--src/chunk.hpp17
-rw-r--r--src/tile.cpp6
-rw-r--r--src/tile.hpp13
-rw-r--r--src/wall-mesh.hpp2
-rw-r--r--src/world.cpp5
-rw-r--r--src/world.hpp29
8 files changed, 73 insertions, 54 deletions
diff --git a/compat/assert.hpp b/compat/assert.hpp
index 8383d333..e8335843 100644
--- a/compat/assert.hpp
+++ b/compat/assert.hpp
@@ -6,31 +6,34 @@
namespace Magnum::Examples::detail {
+template<std::size_t N, std::size_t M, typename... Xs>
+constexpr void emit_debug(const char(&pfx)[M], const char(&fmt)[N], Xs... xs)
+{
+ if (std::is_constant_evaluated())
+ return;
+ else {
+ if constexpr (M > 1)
+ std::fputs(pfx, stderr);
+ std::fprintf(stderr, fmt, xs...);
+ std::fputc('\n', stderr);
+ std::fflush(stderr);
+ }
+}
+
template<std::size_t N, typename...Xs>
constexpr inline void abort(const char (&fmt)[N], Xs... xs)
{
if (std::is_constant_evaluated())
throw "aborting";
else {
- std::fputs("fatal: ", stderr);
- std::fprintf(stderr, fmt, xs...);
- std::putc('\n', stderr);
- std::fflush(stderr);
+ emit_debug("fatal: ", fmt, xs...);
std::abort();
}
}
} // namespace Magnum::Examples::detail
-namespace Magnum::Examples {
-
-#define ABORT(...) \
- do { \
- if (std::is_constant_evaluated()) \
- throw "aborting"; \
- else \
- ::Magnum::Examples::detail:: abort(__VA_ARGS__); \
- } while (false)
+#define ABORT(...) ::Magnum::Examples::detail::abort(__VA_ARGS__)
#define ASSERT(expr) \
do { \
@@ -42,23 +45,13 @@ namespace Magnum::Examples {
} while(false)
#define ASSERT_EXPR(var, expr, cond) \
- [&] { \
+ ([&] { \
decltype(auto) var = (expr); \
ASSERT(cond); \
return (var); \
- }()
-
-#define GAME_DEBUG_OUT(pfx, ...) ([&]() { \
- if constexpr (sizeof((pfx)) > 1) \
- std::fputs((pfx), stderr); \
- std::fprintf(stderr, __VA_ARGS__); \
- std::fputs("\n", stderr); \
- std::fflush(stderr); \
-}())
-
-#define WARN(...) GAME_DEBUG_OUT("warning: ", __VA_ARGS__)
-#define ERR(...) GAME_DEBUG_OUT("error: ", __VA_ARGS__)
-#define MESSAGE(...) GAME_DEBUG_OUT("", __VA_ARGS__)
-#define DEBUG(...) GAME_DEBUG_OUT("", __VA_ARGS__)
+ })()
-} // namespace Magnum::Examples
+#define WARN(...) ::Magnum::Examples::detail::emit_debug("warning: ", __VA_ARGS__)
+#define ERR(...) ::Magnum::Examples::detail::emit_debug("error: ", __VA_ARGS__)
+#define MESSAGE(...) ::Magnum::Examples::detail::emit_debug("", __VA_ARGS__)
+#define DEBUG(...) ::Magnum::Examples::detail::emit_debug("", __VA_ARGS__)
diff --git a/compat/defs.hpp b/compat/defs.hpp
index cd2e13cb..3ba5ebaf 100644
--- a/compat/defs.hpp
+++ b/compat/defs.hpp
@@ -7,3 +7,7 @@
#endif
#define progn(...) [&]{__VA_ARGS__;}()
+
+#define DECLARE_DEPRECATED_COPY_OPERATOR(type) \
+ [[deprecated]] type(const type&) = default; \
+ [[deprecated]] type& operator=(const type&) = default
diff --git a/src/chunk.hpp b/src/chunk.hpp
index e4ba217f..6c3706b8 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -5,6 +5,11 @@
namespace Magnum::Examples {
+template<typename F, typename Tile>
+concept tile_iterator = requires(F fn, Tile& tile) {
+ { fn.operator()(tile, std::size_t{}, local_coords{}) } -> std::same_as<void>;
+};
+
struct chunk final
{
constexpr tile& operator[](local_coords xy) { return _tiles[xy.to_index()]; }
@@ -14,11 +19,15 @@ struct chunk final
const auto& tiles() const { return _tiles; }
auto& tiles() { return _tiles; }
- template<std::invocable<tile&, std::size_t, local_coords> F>
- constexpr inline void foreach_tile(F&& fun) { foreach_tile_<F, chunk&>(std::forward<F>(fun)); }
+ template<tile_iterator<tile&> F>
+ constexpr inline void foreach_tile(F&& fun) {
+ foreach_tile_<F, chunk&>(std::forward<F>(fun));
+ }
- template<std::invocable<tile&, std::size_t, local_coords> F>
- constexpr inline void foreach_tile(F&& fun) const { foreach_tile_<F, const chunk&>(std::forward<F>(fun)); }
+ template<tile_iterator<const tile&> F>
+ constexpr inline void foreach_const_tile(F&& fun) const {
+ const_cast<chunk*>(this)->foreach_tile_<F, const chunk&>(std::forward<F>(fun));
+ }
private:
template<typename F, typename Self>
diff --git a/src/tile.cpp b/src/tile.cpp
index 41d11067..fe0e2da3 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -1,11 +1,7 @@
#include "tile.hpp"
-#include "tile-atlas.hpp"
namespace Magnum::Examples {
-local_coords::local_coords(std::size_t x, std::size_t y) : x{(std::uint8_t)x}, y{(std::uint8_t)y}
-{
- CORRADE_INTERNAL_ASSERT(x <= 0xff && y <= 0xff);
-}
+
} // namespace Magnum::Examples
diff --git a/src/tile.hpp b/src/tile.hpp
index eadfa745..169c941b 100644
--- a/src/tile.hpp
+++ b/src/tile.hpp
@@ -1,4 +1,6 @@
#pragma once
+#include "compat/defs.hpp"
+#include "compat/assert.hpp"
#include <Magnum/Magnum.h>
#include <Magnum/Math/Vector3.h>
#include <cstddef>
@@ -27,14 +29,23 @@ struct tile final
tile_image ground_image, wall_north, wall_west;
pass_mode passability = pass_shoot_through;
+
+ constexpr tile() = default;
+ DECLARE_DEPRECATED_COPY_OPERATOR(tile);
};
struct local_coords final {
std::uint8_t x = 0, y = 0;
constexpr local_coords() = default;
- local_coords(std::size_t x, std::size_t y);
+ constexpr local_coords(std::size_t x, std::size_t y);
constexpr local_coords(std::uint8_t x, std::uint8_t y) : x{x}, y{y} {}
constexpr std::size_t to_index() const { return y*TILE_MAX_DIM + x; }
};
+constexpr local_coords::local_coords(std::size_t x, std::size_t y)
+ : x{(std::uint8_t)x}, y{(std::uint8_t)y}
+{
+ ASSERT(x <= 0xff && y <= 0xff);
+}
+
} //namespace Magnum::Examples
diff --git a/src/wall-mesh.hpp b/src/wall-mesh.hpp
index e9678e3e..e23799f4 100644
--- a/src/wall-mesh.hpp
+++ b/src/wall-mesh.hpp
@@ -19,7 +19,7 @@ struct wall_mesh final
void draw(tile_shader& shader, chunk& c);
private:
- static constexpr auto COUNT1 = TILE_MAX_DIM*2, COUNT = COUNT1 * COUNT1;
+ static constexpr auto COUNT = TILE_MAX_DIM*2 * TILE_MAX_DIM*2;
struct vertex final {
std::array<Vector2, 4> texcoords;
diff --git a/src/world.cpp b/src/world.cpp
index a8ca7085..2d19c7d2 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -2,7 +2,12 @@
namespace Magnum::Examples {
+static_assert(sizeof(decltype(local_coords::x))*8 == 8);
+static_assert(sizeof(decltype(chunk_coords::x))*8 == 16);
+static_assert(std::is_same_v<decltype(local_coords::x), decltype(local_coords::y)>);
+static_assert(std::is_same_v<decltype(chunk_coords::x), decltype(chunk_coords::y)>);
+static_assert(std::is_same_v<decltype(chunk_coords::x), decltype(chunk_coords::y)>);
} // namespace Magnum::Examples
diff --git a/src/world.hpp b/src/world.hpp
index 21b2c764..99b984c2 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -6,23 +6,24 @@ namespace Magnum::Examples {
struct chunk_coords final {
std::int16_t x = 0, y = 0;
-#if 0
- static_assert(std::is_same_v<decltype(x), decltype(x)>);
- static constexpr std::size_t max_bits = sizeof(chunk_coords::x)*8 * 3 / 4;
- static_assert(max_bits*4/3/8 == sizeof(decltype(chunk_coords::x)));
- constexpr chunk_coords(std::int16_t x, std::int16_t y);
-#endif
};
-#if 0
-constexpr chunk_coords::chunk_coords(std::int16_t x, std::int16_t y) : x{x}, y{y} {
- using s = std::make_signed_t<std::size_t>;
-}
-#endif
-
struct global_coords final {
- chunk_coords chunk;
- local_coords tile;
+ std::int32_t x = 0, y = 0;
+ constexpr chunk_coords chunk() const noexcept;
+ constexpr chunk_coords local() const noexcept;
};
+constexpr chunk_coords global_coords::chunk() const noexcept {
+ constexpr std::uint32_t mask = 0xffff0000u;
+ const auto x_ = (std::int16_t)(std::uint16_t)((std::uint32_t)x & mask >> 24),
+ y_ = (std::int16_t)(std::uint16_t)((std::uint32_t)y & mask >> 24);
+ return {x_, y_};
+}
+
+constexpr chunk_coords global_coords::local() const noexcept {
+ const auto x_ = (std::uint8_t)x, y_ = (std::uint8_t)y;
+ return {x_, y_};
+}
+
} // namespace Magnum::Examples