summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-15 21:51:33 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-15 21:51:33 +0200
commit1e8d16fe10917664f9520008f224f19692c3a668 (patch)
treec966c22e3bb719754a01715778f0820aa0853dfa
parentd8874ad6c42ec016fa931fe3e57fcd9797d06094 (diff)
a
-rw-r--r--anim-crop-tool/main.cpp8
-rw-r--r--compat/alloca.hpp7
m---------corrade0
-rw-r--r--images/tiles.tgabin960018 -> 492059 bytes
m---------magnum0
-rw-r--r--main/app.cpp3
-rw-r--r--main/app.hpp8
-rw-r--r--main/editor.cpp33
-rw-r--r--main/editor.hpp45
-rw-r--r--main/loader-impl.cpp12
-rw-r--r--main/menu.cpp39
-rw-r--r--serialize/json-helper.hpp28
-rw-r--r--src/loader.hpp2
-rw-r--r--test/json.cpp13
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
index 2e520f2a..41b85822 100644
--- a/images/tiles.tga
+++ b/images/tiles.tga
Binary files differ
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