summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-02-21 14:29:22 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-02-21 14:29:22 +0100
commit5eb4ae08d5cd81f7315998394054aa50e52b6870 (patch)
tree1174490ccb5cbcb4167d715a30d385e796beb25d
parentb8aa39d289c605b13bb550b786cba3f646fa5b48 (diff)
buffer flush
-rw-r--r--atlas.cpp4
-rw-r--r--atlas.hpp2
-rw-r--r--defs.hpp43
-rw-r--r--hash.hpp24
-rw-r--r--loader-impl.cpp1
-rw-r--r--main.cpp3
-rw-r--r--tile.cpp16
-rw-r--r--tile.hpp117
8 files changed, 201 insertions, 9 deletions
diff --git a/atlas.cpp b/atlas.cpp
index 4e384540..1463c26a 100644
--- a/atlas.cpp
+++ b/atlas.cpp
@@ -1,4 +1,5 @@
#include "atlas.hpp"
+#include "defs.hpp"
#include <Magnum/ImageView.h>
#include <Magnum/GL/TextureFormat.h>
@@ -12,10 +13,11 @@ atlas_texture::atlas_texture(const Trade::ImageData2D& image, Vector2i dims) :
CORRADE_INTERNAL_ASSERT(dims_[0] > 0 && dims_[1] > 0);
CORRADE_INTERNAL_ASSERT(tile_size_ * dims_ == size_);
CORRADE_INTERNAL_ASSERT(size_ % dims_ == Vector2i{});
+ CORRADE_INTERNAL_ASSERT(dims.product() < 256);
tex_.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setMinificationFilter(GL::SamplerFilter::Linear)
- .setStorage(1, GL::textureFormat(image.format()), image.size())
+ .setStorage(MIPMAP_LEVEL, GL::textureFormat(image.format()), image.size())
.setSubImage(0, {}, image);
}
diff --git a/atlas.hpp b/atlas.hpp
index 1b2a4e15..5e45a1fc 100644
--- a/atlas.hpp
+++ b/atlas.hpp
@@ -21,6 +21,8 @@ struct atlas_texture final
private:
GL::Texture2D tex_;
Vector2i size_, dims_, tile_size_;
+
+ static constexpr int MIPMAP_LEVEL = 1;
};
} // namespace Magnum::Examples
diff --git a/defs.hpp b/defs.hpp
index a2f5d240..f680c4b9 100644
--- a/defs.hpp
+++ b/defs.hpp
@@ -1,24 +1,59 @@
#pragma once
+#include <cstddef>
#include <cstdio>
-#include <exception>
+#include <limits>
+#include <type_traits>
+
+#ifdef _MSC_VER
+# define FUNCTION_NAME __FUNCSIG__
+#else
+# define FUNCTION_NAME __PRETTY_FUNCTION__
+#endif
namespace Magnum::Examples {
-struct assertion_failure final : std::exception
-{
+using size_t = std::size_t;
+using ssize_t = std::make_signed_t<std::size_t>;
+
+struct exception {
const char* file = nullptr;
+ const char* function = nullptr;
int line = -1;
+};
+
+struct assertion_failure final : exception
+{
char msg[128 - sizeof(int) - sizeof(char*)];
+};
+
+struct out_of_range final : exception {
+ ssize_t value = 0;
+ ssize_t min = std::numeric_limits<ssize_t>::min();
+ ssize_t max = std::numeric_limits<ssize_t>::max();
+};
- const char* what() const noexcept override { return msg; }
+struct key_error final : exception {
+ ssize_t value = 0;
};
} // namespace Magnum::Examples
+#define KEY_ERROR(value) \
+ ::Magnum::Examples::key_error{{__FILE__, FUNCTION_NAME, __LINE__}, (value)}
+
+#define OUT_OF_RANGE(value, min, max) \
+ ::Magnum::Examples::out_of_range{ \
+ {__FILE__, FUNCTION_NAME, __LINE__}, \
+ ::Magnum::Examples::ssize_t((value)), \
+ ::Magnum::Examples::ssize_t((min)), \
+ ::Magnum::Examples::ssize_t((max)) \
+ }
+
#define ABORT_WITH(exc_type, ...) ([&]() { \
exc_type _e; \
_e.line = __LINE__; \
_e.file = __FILE__; \
+ _e.function = FUNCTION_NAME; \
std::snprintf(_e.msg, sizeof(_e.msg), __VA_ARGS__); \
throw _e; \
}())
diff --git a/hash.hpp b/hash.hpp
new file mode 100644
index 00000000..c6d74444
--- /dev/null
+++ b/hash.hpp
@@ -0,0 +1,24 @@
+#pragma once
+#include <cstdint>
+
+namespace Magnum::Examples {
+
+template<unsigned N = sizeof(std::size_t)*8> struct hash;
+
+template<>
+struct hash<32> final {
+ [[maybe_unused]]
+ constexpr std::uint32_t operator()(std::uint32_t x) const noexcept {
+ return (std::uint32_t)x*0x9e3779b1u;
+ }
+};
+
+template<>
+struct hash<64> final {
+ [[maybe_unused]]
+ constexpr std::uint64_t operator()(std::uint64_t x) const noexcept {
+ return x*0x9e3779b97f4a7c15ull;
+ }
+};
+
+} // namespace Magnum::Examples
diff --git a/loader-impl.cpp b/loader-impl.cpp
index 96f5930b..63b16a10 100644
--- a/loader-impl.cpp
+++ b/loader-impl.cpp
@@ -9,7 +9,6 @@
#include <string>
#include <unordered_map>
#include <utility>
-#include <optional>
namespace Magnum::Examples {
diff --git a/main.cpp b/main.cpp
index e134134a..6af9dd7f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -2,10 +2,8 @@
#include "loader.hpp"
#include "tile-shader.hpp"
-#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/PluginManager/Manager.h>
-#include <Corrade/Utility/Resource.h>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Vector.h>
#include <Magnum/ImageView.h>
@@ -16,7 +14,6 @@
#include <Magnum/GL/TextureFormat.h>
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/Trade/AbstractImporter.h>
-#include <Magnum/Trade/ImageData.h>
#include <Magnum/GlmIntegration/Integration.h>
#include <glm/glm.hpp>
diff --git a/tile.cpp b/tile.cpp
new file mode 100644
index 00000000..3fe28959
--- /dev/null
+++ b/tile.cpp
@@ -0,0 +1,16 @@
+#include "tile.hpp"
+#include <limits>
+
+namespace Magnum::Examples {
+
+chunk::tile_index_type chunk::make_tile_indices() noexcept
+{
+ tile_index_type array;
+ for (unsigned i = 0; i < N*N; i++)
+ array[i] = (UnsignedByte)i;
+ return array;
+}
+
+world::world() = default;
+
+} // namespace Magnum::Examples
diff --git a/tile.hpp b/tile.hpp
new file mode 100644
index 00000000..f47f9077
--- /dev/null
+++ b/tile.hpp
@@ -0,0 +1,117 @@
+#pragma once
+#include "loader.hpp"
+#include "atlas.hpp"
+#include "hash.hpp"
+#include "defs.hpp"
+
+#include <cstddef>
+#include <tuple>
+#include <array>
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
+namespace Magnum::Examples {
+
+struct tile_image final : std::tuple<atlas_ptr, UnsignedByte>
+{
+ constexpr int variant() const noexcept { return std::get<1>(*this); }
+ atlas_ptr atlas() const noexcept { return std::get<0>(*this); }
+};
+
+struct tile final
+{
+ enum class pass_mode : std::uint8_t { pass_blocked, pass_yes, pass_shoot_through, pass_obscured };
+ using enum pass_mode;
+
+ tile_image ground_image_;
+ pass_mode passability_ = pass_obscured;
+
+ explicit operator bool() const noexcept { return !!std::get<0>(ground_image_); }
+};
+
+struct local_coords final : std::pair<UnsignedByte, UnsignedByte> {
+ constexpr std::size_t to_index() const noexcept;
+};
+
+struct chunk_coords final : std::pair<Short, Short> {
+ constexpr std::size_t to_index() const noexcept;
+};
+
+struct global_coords final : std::pair<chunk_coords, local_coords> {};
+
+struct chunk final
+{
+ static constexpr std::size_t N = 16;
+ static constexpr std::size_t TILE_COUNT = N*N;
+ using tile_index_type = std::array<UnsignedByte, TILE_COUNT>;
+ static tile_index_type make_tile_indices() noexcept;
+
+ tile_index_type indices = make_tile_indices();
+
+ constexpr struct tile& tile(local_coords xy);
+ constexpr struct tile& tile(local_coords xy) const { return const_cast<chunk&>(*this).tile(xy); }
+ constexpr struct tile& operator[](std::size_t i);
+
+ template<typename F> constexpr inline void foreach_tile(F&& fun) { foreach_tile_<F, chunk&>(fun); }
+ template<typename F> constexpr inline void foreach_tile(F&& fun) const { foreach_tile_<F, const chunk&>(fun); }
+
+private:
+ template<typename F, typename Self> constexpr void foreach_tile_(F&& fun);
+ std::array<struct tile, TILE_COUNT> tiles = {};
+};
+
+constexpr std::size_t local_coords::to_index() const noexcept {
+ return second*chunk::N + first;
+}
+
+constexpr struct tile& chunk::operator[](std::size_t i) {
+ if (i >= TILE_COUNT)
+ throw OUT_OF_RANGE(i, 0, TILE_COUNT);
+ return tiles[i];
+}
+
+constexpr tile& chunk::tile(local_coords xy)
+{
+ auto idx = xy.to_index();
+ if (idx >= TILE_COUNT)
+ throw OUT_OF_RANGE(idx, 0, TILE_COUNT);
+ return tiles[idx];
+}
+
+template<typename F, typename Self>
+constexpr void chunk::foreach_tile_(F&& fun)
+{
+ for (unsigned j = 0; j < N; j++)
+ for (unsigned i = 0; i < N; i++)
+ {
+ unsigned idx = j*N + i;
+ if (tiles[idx])
+ fun(*static_cast<Self>(*this).tiles[idx]);
+ }
+}
+
+constexpr std::size_t chunk_coords::to_index() const noexcept
+{
+ using unsigned_type = std::make_unsigned_t<decltype(second)>;
+ using limits = std::numeric_limits<unsigned_type>;
+ constexpr auto N = limits::max() + std::size_t{1};
+ static_assert(sizeof(unsigned_type) <= sizeof(std::size_t)/2);
+ return (std::size_t)(unsigned_type)second * N + (std::size_t)(unsigned_type)first;
+}
+
+struct hash_chunk final {
+ constexpr std::size_t operator()(chunk_coords xy) const noexcept {
+ return hash<sizeof(std::size_t)*8>{}(xy.to_index());
+ }
+};
+
+struct world final
+{
+ explicit world();
+
+private:
+ std::unordered_map<chunk_coords, std::shared_ptr<chunk>, hash_chunk> chunks;
+};
+
+} //namespace Magnum::Examples