diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-15 21:51:33 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-15 21:51:33 +0200 |
commit | 1e8d16fe10917664f9520008f224f19692c3a668 (patch) | |
tree | c966c22e3bb719754a01715778f0820aa0853dfa | |
parent | d8874ad6c42ec016fa931fe3e57fcd9797d06094 (diff) |
a
-rw-r--r-- | anim-crop-tool/main.cpp | 8 | ||||
-rw-r--r-- | compat/alloca.hpp | 7 | ||||
m--------- | corrade | 0 | ||||
-rw-r--r-- | images/tiles.tga | bin | 960018 -> 492059 bytes | |||
m--------- | magnum | 0 | ||||
-rw-r--r-- | main/app.cpp | 3 | ||||
-rw-r--r-- | main/app.hpp | 8 | ||||
-rw-r--r-- | main/editor.cpp | 33 | ||||
-rw-r--r-- | main/editor.hpp | 45 | ||||
-rw-r--r-- | main/loader-impl.cpp | 12 | ||||
-rw-r--r-- | main/menu.cpp | 39 | ||||
-rw-r--r-- | serialize/json-helper.hpp | 28 | ||||
-rw-r--r-- | src/loader.hpp | 2 | ||||
-rw-r--r-- | test/json.cpp | 13 |
14 files changed, 144 insertions, 54 deletions
diff --git a/anim-crop-tool/main.cpp b/anim-crop-tool/main.cpp index 5caa9fe4..5eab52e5 100644 --- a/anim-crop-tool/main.cpp +++ b/anim-crop-tool/main.cpp @@ -245,10 +245,7 @@ int main(int argc, char** argv) if (!opts_ok) return usage(args); - auto [anim_info, anim_ok] = json_helper::from_json<anim>(opts.input_file); - - if (!anim_ok) - return EX_DATAERR; + auto anim_info = json_helper::from_json<anim>(opts.input_file); if (!check_atlas_name(anim_info.object_name)) { @@ -294,8 +291,7 @@ int main(int argc, char** argv) << std::strerror(errno); // NOLINT(concurrency-mt-unsafe) return EX_CANTCREAT; } - if (!json_helper::to_json<anim>(anim_info, opts.output_dir/(base_name + ".json"))) - return EX_CANTCREAT; + json_helper::to_json<anim>(anim_info, opts.output_dir/(base_name + ".json")); return 0; } diff --git a/compat/alloca.hpp b/compat/alloca.hpp new file mode 100644 index 00000000..1ce269e5 --- /dev/null +++ b/compat/alloca.hpp @@ -0,0 +1,7 @@ +#pragma once + +#ifdef _WIN32 +# include <malloc.h> +#else +# include <alloca.h> +#endif diff --git a/corrade b/corrade -Subproject 3f33f27ab203dfea755e97f7effadffe56dfc8a +Subproject 7220cb9c0cf39565bbbd1e1864310cae9e8f120 diff --git a/images/tiles.tga b/images/tiles.tga Binary files differindex 2e520f2a..41b85822 100644 --- a/images/tiles.tga +++ b/images/tiles.tga diff --git a/magnum b/magnum -Subproject 35c4cdb86558ab0073abe577b3b5314d1f93fd4 +Subproject 69cc083bce5012a4d4a21a9f0c44fcc0b3e687d diff --git a/main/app.cpp b/main/app.cpp index 33b89231..e2d51455 100644 --- a/main/app.cpp +++ b/main/app.cpp @@ -19,12 +19,15 @@ app::app(const Arguments& arguments): .setFlags(GLConfiguration::Flag::GpuValidation) } { + if (!setSwapInterval(-1)) + (void)setSwapInterval(1); set_fp_mask(); reset_camera_offset(); update_window_scale(windowSize()); setMinimalLoopPeriod(5); _imgui = ImGuiIntegration::Context(Vector2{windowSize()}, windowSize(), framebufferSize()); setup_menu(); + SDL_MaximizeWindow(window()); timeline.start(); } void app::viewportEvent(Platform::Sdl2Application::ViewportEvent& event) diff --git a/main/app.hpp b/main/app.hpp index 876ad8fe..211e7bdc 100644 --- a/main/app.hpp +++ b/main/app.hpp @@ -58,10 +58,10 @@ struct app final : Platform::Application const void* _dummy = register_debug_callback(); tile_shader _shader; - tile_atlas_ floor1 = loader.tile_atlas("share/game/images/metal1.tga", {2, 2}); - tile_atlas_ floor2 = loader.tile_atlas("share/game/images/floor1.tga", {4, 4}); - tile_atlas_ wall1 = loader.tile_atlas("share/game/images/wood2.tga", {2, 2}); - tile_atlas_ wall2 = loader.tile_atlas("share/game/images/wood1.tga", {2, 2}); + tile_atlas_ floor1 = loader.tile_atlas("metal1.tga", {2, 2}); + tile_atlas_ floor2 = loader.tile_atlas("floor1.tga", {4, 4}); + tile_atlas_ wall1 = loader.tile_atlas("wood2.tga", {2, 2}); + tile_atlas_ wall2 = loader.tile_atlas("wood1.tga", {2, 2}); chunk _chunk = make_test_chunk(); floor_mesh _floor_mesh; diff --git a/main/editor.cpp b/main/editor.cpp new file mode 100644 index 00000000..4b291ea6 --- /dev/null +++ b/main/editor.cpp @@ -0,0 +1,33 @@ +#include "editor.hpp" +#include "serialize/json-helper.hpp" +#include "serialize/tile-atlas.hpp" +#include "src/loader.hpp" +#include <filesystem> +#include <vector> + +namespace floormat { + +static const std::filesystem::path image_path{IMAGE_PATH, std::filesystem::path::generic_format}; + +tile_type::tile_type(Containers::StringView name) : _name{name} +{ + load_atlases(); +} + +void tile_type::load_atlases() +{ + using atlas_array = std::vector<std::shared_ptr<tile_atlas>>; + for (auto& atlas : json_helper::from_json<atlas_array>(image_path/(_name + ".json"))) + { + Containers::StringView name = atlas->name(); + if (auto x = name.findLast('.'); x) + name = name.prefix(x.data()); + _atlases[name] = std::move(atlas); + } +} + +editor_state::editor_state() +{ +} + +} // namespace floormat diff --git a/main/editor.hpp b/main/editor.hpp index af3934eb..993d057a 100644 --- a/main/editor.hpp +++ b/main/editor.hpp @@ -1,4 +1,9 @@ #pragma once +#include "tile-atlas.hpp" +#include <map> +#include <memory> +#include <tuple> +#include <Corrade/Containers/StringView.h> namespace floormat { @@ -6,10 +11,46 @@ enum class editor_mode : unsigned char { select, floors, walls, }; +struct tile_type final +{ + tile_type(Containers::StringView name); + std::shared_ptr<struct tile_atlas> atlas(Containers::StringView str); + auto begin() & { return _atlases.begin(); } + auto end() & { return _atlases.end(); } + auto begin() const&& { return _atlases.cbegin(); } + auto end() const&& { return _atlases.cend(); } + auto cbegin() const { return _atlases.cbegin(); } + auto cend() const { return _atlases.cend(); } + Containers::StringView name() const { return _name; } + +private: + std::string _name; + std::map<std::string, std::shared_ptr<struct tile_atlas>> _atlases; + void load_atlases(); +}; + struct editor_state final { - editor_mode mode = {}; - bool dirty = false; + [[nodiscard]] bool dirty() const { return _dirty; } + void set_dirty(bool value) { _dirty = value; } + [[nodiscard]] editor_mode mode() const { return _mode; } + void set_mode(editor_mode mode) { _mode = mode; } + + tile_type& floors() { return _floors; } + const tile_type& floors() const { return _floors; } + + editor_state(); + + editor_state(const editor_state&) = delete; + editor_state& operator=(const editor_state&) = delete; + + editor_state(editor_state&&) noexcept = default; + editor_state& operator=(editor_state&&) noexcept = default; + +private: + tile_type _floors{"floor"}; + editor_mode _mode = {}; + bool _dirty = false; }; } // namespace floormat diff --git a/main/loader-impl.cpp b/main/loader-impl.cpp index 4d40250a..3adf792d 100644 --- a/main/loader-impl.cpp +++ b/main/loader-impl.cpp @@ -1,6 +1,7 @@ #include "loader.hpp" #include "tile-atlas.hpp" #include "compat/assert.hpp" +#include "compat/alloca.hpp" #include <filesystem> #include <unordered_map> #include <utility> @@ -62,16 +63,21 @@ std::shared_ptr<tile_atlas> loader_impl::tile_atlas(Containers::StringView name, return atlas; } -Trade::ImageData2D loader_impl::tile_texture(Containers::StringView filename) +Trade::ImageData2D loader_impl::tile_texture(Containers::StringView filename_) { + static_assert(IMAGE_PATH[sizeof(IMAGE_PATH)-2] == '/'); + + char* const filename = (char*)alloca(filename_.size() + sizeof(IMAGE_PATH)); + std::memcpy(filename, IMAGE_PATH, sizeof(IMAGE_PATH)-1); + std::strcpy(filename + sizeof(IMAGE_PATH)-1, filename_.cbegin()); if (!tga_importer || !tga_importer->openFile(filename)) { const auto path = Utility::Path::currentDirectory(); MESSAGE("note: current working directory: '%s'", path->data()); - ABORT("can't open tile image '%s'", filename.cbegin()); + ABORT("can't open tile image '%s'", filename); } auto img = tga_importer->image2D(0); if (!img) - ABORT("can't allocate tile image for '%s'", filename.cbegin()); + ABORT("can't allocate tile image for '%s'", filename); auto ret = std::move(*img); return ret; } diff --git a/main/menu.cpp b/main/menu.cpp index bd107611..f1d9f8db 100644 --- a/main/menu.cpp +++ b/main/menu.cpp @@ -75,6 +75,13 @@ void app::draw_menu() else if (!ImGui::GetIO().WantTextInput && isTextInputActive()) stopTextInput(); + auto& style = ImGui::GetStyle(); + ImGui::StyleColorsDark(&style); + style.WindowPadding = {8, 8}; + style.WindowBorderSize = {}; + style.Colors[ImGuiCol_WindowBg] = {0, 0, 0, .5}; + style.Colors[ImGuiCol_FrameBg] = {0, 0, 0, 0}; + ImVec2 main_menu_pos; if (auto b = begin_main_menu()) @@ -91,21 +98,15 @@ void app::draw_menu() } if (auto b = begin_menu("Mode")) { - ImGui::MenuItem("Select", "F1", _editor.mode == editor_mode::select); - ImGui::MenuItem("Floors", "F2", _editor.mode == editor_mode::floors); - ImGui::MenuItem("Walls", "F3", _editor.mode == editor_mode::walls); + ImGui::MenuItem("Select", "F1", _editor.mode() == editor_mode::select); + ImGui::MenuItem("Floors", "F2", _editor.mode() == editor_mode::floors); + ImGui::MenuItem("Walls", "F3", _editor.mode() == editor_mode::walls); } main_menu_pos = ImGui::GetContentRegionMax(); } if (main_menu_pos.y > 0) { - auto& style = ImGui::GetStyle(); - ImGui::StyleColorsDark(&style); - style.WindowPadding = {8, 8}; - style.WindowBorderSize = {}; - style.Colors[ImGuiCol_WindowBg] = {0, 0, 0, .5}; - style.Colors[ImGuiCol_FrameBg] = {0, 0, 0, 0}; - + return; ImGui::SetNextWindowPos({0, main_menu_pos.y+style.WindowPadding.y}); ImGui::SetNextFrameWantCaptureKeyboard(false); if (auto b = begin_window(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings)) @@ -113,11 +114,23 @@ void app::draw_menu() ImGui::Text("Items:"); //ImGui::SetNextWindowBgAlpha(.2f); - if (auto b = begin_list_box("##tiles", {-FLT_MIN, 100})) + if (auto b = begin_list_box("##tiles", {200, 200})) { - for (const auto& label : {"foo", "bar", "baz"}) + for (const auto& [k, v] : _editor.floors()) { - ImGui::Selectable(label); + const std::size_t N = v->num_tiles().product(); + ImGui::CollapsingHeader(k.data()); + constexpr std::size_t per_row = 8; + for (std::size_t i = 0; i < N; i++) + { + if (i > 0 && i % per_row == 0) + ImGui::NewLine(); + const auto uv = v->texcoords_for_id(i); + ImGui::Image((void*)0, + {TILE_SIZE[0], TILE_SIZE[1]}, + { uv[3][0], uv[3][1] }, { uv[0][0], uv[0][1] }, + {1, 1, 1, 1}, {1, 1, 1, 1}); + } } } } diff --git a/serialize/json-helper.hpp b/serialize/json-helper.hpp index b8e290b7..b1502295 100644 --- a/serialize/json-helper.hpp +++ b/serialize/json-helper.hpp @@ -9,46 +9,36 @@ struct json_helper final { template<typename t> [[nodiscard]] - static std::tuple<t, bool> from_json(const std::filesystem::path& pathname); + static t from_json(const std::filesystem::path& pathname); template<typename t> - [[nodiscard]] - static bool to_json(const t& self, const std::filesystem::path& pathname); + static void to_json(const t& self, const std::filesystem::path& pathname); }; template<typename t> -std::tuple<t, bool> json_helper::from_json(const std::filesystem::path& pathname) { +t json_helper::from_json(const std::filesystem::path& pathname) +{ using Corrade::Utility::Error; std::ifstream s; s.exceptions(s.exceptions() | std::ios::failbit | std::ios::badbit); - try { - s.open(pathname, std::ios_base::in); - } catch (const std::ios::failure& e) { - Error{} << "failed to open" << pathname << "for reading:" << e.what(); - return {}; - } + s.open(pathname, std::ios_base::in); t ret; nlohmann::json j; s >> j; ret = j; - return { std::move(ret), true }; + return ret; } template<typename t> -bool json_helper::to_json(const t& self, const std::filesystem::path& pathname) { +void json_helper::to_json(const t& self, const std::filesystem::path& pathname) +{ using Corrade::Utility::Error; nlohmann::json j = self; std::ofstream s; s.exceptions(s.exceptions() | std::ios::failbit | std::ios::badbit); - try { - s.open(pathname, std::ios_base::out | std::ios_base::trunc); - } catch (const std::ios::failure& e) { - Error{} << "failed to open" << pathname << "for writing:" << e.what(); - return false; - } + s.open(pathname, std::ios_base::out | std::ios_base::trunc); s << j.dump(4); s << '\n'; s.flush(); - return true; } diff --git a/src/loader.hpp b/src/loader.hpp index 6657439a..6d6d49e0 100644 --- a/src/loader.hpp +++ b/src/loader.hpp @@ -7,6 +7,8 @@ #include <optional> #include <memory> +#define IMAGE_PATH "share/game/images/" + namespace floormat { struct tile_atlas; diff --git a/test/json.cpp b/test/json.cpp index 97bece30..0ecd9f54 100644 --- a/test/json.cpp +++ b/test/json.cpp @@ -32,29 +32,28 @@ static chunk make_test_chunk() bool app::test_json() // NOLINT(readability-convert-member-functions-to-static) { - bool ret = true; const std::filesystem::path output_dir = "../test/."; { auto atlas = loader.tile_atlas("share/game/images/metal1.tga", {2, 2}); - ret &= json_helper::to_json(atlas, output_dir/"atlas.json"); + json_helper::to_json(atlas, output_dir/"atlas.json"); } { Magnum::Math::Vector<2, int> v2i_1{1, 2}; Vector2i v2i_2{2, 3}; - ret &= json_helper::to_json(v2i_1, output_dir/"vec2i_1.json"); - ret &= json_helper::to_json(v2i_2, output_dir/"vec2i_2.json"); + json_helper::to_json(v2i_1, output_dir/"vec2i_1.json"); + json_helper::to_json(v2i_2, output_dir/"vec2i_2.json"); } { volatile float zero = 0; Magnum::Math::Vector3 vec{0.f/zero, -1.f/zero, 123.f}; - ret &= json_helper::to_json(vec, output_dir/"vec3_inf.json"); + json_helper::to_json(vec, output_dir/"vec3_inf.json"); } { const auto chunk = make_test_chunk(); - ret &= json_helper::to_json(chunk, output_dir/"zzz_chunk-1.json"); + json_helper::to_json(chunk, output_dir/"zzz_chunk-1.json"); } - return ret; + return true; } } // namespace floormat |