diff options
-rw-r--r-- | compat/assert.hpp | 51 | ||||
-rw-r--r-- | compat/defs.hpp | 4 | ||||
-rw-r--r-- | src/chunk.hpp | 17 | ||||
-rw-r--r-- | src/tile.cpp | 6 | ||||
-rw-r--r-- | src/tile.hpp | 13 | ||||
-rw-r--r-- | src/wall-mesh.hpp | 2 | ||||
-rw-r--r-- | src/world.cpp | 5 | ||||
-rw-r--r-- | src/world.hpp | 29 |
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 |