From 7ab99aabe8509e84b9b5b04aafa1e1ae20b40512 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 16 Oct 2022 21:51:07 +0200 Subject: a --- main/app.cpp | 23 ++++++---- main/app.hpp | 3 +- main/camera.cpp | 19 -------- main/editor.cpp | 16 ++++++- main/editor.hpp | 14 +++--- main/gui.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main/main.cpp | 37 ++++++++------- main/menu.cpp | 139 -------------------------------------------------------- main/update.cpp | 53 +++++++++++++++++++++ src/world.hpp | 19 ++------ 10 files changed, 251 insertions(+), 206 deletions(-) create mode 100644 main/gui.cpp delete mode 100644 main/menu.cpp create mode 100644 main/update.cpp diff --git a/main/app.cpp b/main/app.cpp index 9537bf58..b412c81b 100644 --- a/main/app.cpp +++ b/main/app.cpp @@ -32,6 +32,7 @@ app::app(const Arguments& arguments): SDL_MaximizeWindow(window()); timeline.start(); } + void app::viewportEvent(Platform::Sdl2Application::ViewportEvent& event) { update_window_scale(event.windowSize()); @@ -44,6 +45,20 @@ void app::mousePressEvent(Platform::Sdl2Application::MouseEvent& event) { if (_imgui.handleMousePressEvent(event)) return event.setAccepted(); + { + const auto tile = pixel_to_tile(Vector2(*_cursor_pos)); + int button; + switch (event.button()) + { + case MouseEvent::Button::Left: button = 0; break; + case MouseEvent::Button::Right: button = 1; break; + case MouseEvent::Button::Middle: button = 2; break; + case MouseEvent::Button::X1: button = 5; break; + case MouseEvent::Button::X2: button = 6; break; + default: button = -1; break; + } + do_mouse_click(tile, button); + } } void app::mouseReleaseEvent(Platform::Sdl2Application::MouseEvent& event) @@ -114,12 +129,4 @@ void app::event_mouse_enter() { } -void app::update(float dt) -{ - do_camera(dt); - do_menu(); - if (keys[key::quit]) - Platform::Sdl2Application::exit(0); -} - } // namespace floormat diff --git a/main/app.hpp b/main/app.hpp index 0242365c..e5c0e34b 100644 --- a/main/app.hpp +++ b/main/app.hpp @@ -59,6 +59,7 @@ struct app final : Platform::Application Vector2 pixel_to_tile(Vector2 position) const; void draw_cursor_tile(); + void do_mouse_click(Vector2 pos, int button); std::optional _cursor_pos; @@ -90,7 +91,7 @@ struct app final : Platform::Application Vector2 camera_offset; enum_bitset keys; Magnum::Timeline timeline; - editor_state _editor; + editor _editor; }; constexpr Vector2 app::project(const Vector3 pt) diff --git a/main/camera.cpp b/main/camera.cpp index 2bbadd00..bfbf6aa5 100644 --- a/main/camera.cpp +++ b/main/camera.cpp @@ -32,23 +32,4 @@ void app::update_window_scale(Vector2i sz) _shader.set_scale(Vector2{sz}); } -Vector2 app::pixel_to_tile(Vector2 position) const -{ - const auto px = position - Vector2{windowSize()}*.5f - camera_offset; - return unproject(px) / Vector2{TILE_SIZE[0]*.5f, TILE_SIZE[1]*.5f} + Vector2{.5f, .5f}; -} - -void app::draw_cursor_tile() -{ - if (_cursor_pos) - { - const auto tile = pixel_to_tile(Vector2(*_cursor_pos)); - if (std::min(tile[0], tile[1]) >= 0 && std::max(tile[0], tile[1]) < (int)TILE_MAX_DIM) - { - const auto x = std::uint8_t(tile[0]), y = std::uint8_t(tile[1]); - draw_wireframe_quad({x, y}); - } - } -} - } // namespace floormat diff --git a/main/editor.cpp b/main/editor.cpp index 58b1e14a..e95bc6e3 100644 --- a/main/editor.cpp +++ b/main/editor.cpp @@ -5,6 +5,7 @@ #include "random.hpp" #include "compat/assert.hpp" #include "compat/unreachable.hpp" +#include "src/tile-defs.hpp" #include #include @@ -117,12 +118,23 @@ std::optional, std::uint8_t>> tile_type:: case sel_none: return std::nullopt; case sel_tile: return _selected_tile; case sel_perm: return get_selected_perm(); - default: unreachable(); + default : unreachable(); } } -editor_state::editor_state() +editor::editor() { } +void editor::click_at_tile(Vector2 pos, int mouse_button) +{ + if (mouse_button == 0) + { + if (pos[0] >= 0 && pos[1] >= 0 && pos[0] < TILE_MAX_DIM && pos[1] < TILE_MAX_DIM) + { + + } + } +} + } // namespace floormat diff --git a/main/editor.hpp b/main/editor.hpp index 44149555..db4da59e 100644 --- a/main/editor.hpp +++ b/main/editor.hpp @@ -1,4 +1,5 @@ #pragma once +#include "compat/defs.hpp" #include "tile-atlas.hpp" #include #include @@ -53,7 +54,7 @@ private: std::tuple, std::uint8_t> get_selected_perm(); }; -struct editor_state final +struct editor final { [[nodiscard]] bool dirty() const { return _dirty; } void set_dirty(bool value) { _dirty = value; } @@ -63,13 +64,12 @@ struct editor_state final tile_type& floor() { return _floor; } const tile_type& floor() const { return _floor; } - editor_state(); + void click_at_tile(Vector2 pos, int mouse_button); - 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; + editor(); + editor(editor&&) noexcept = default; + editor& operator=(editor&&) noexcept = default; + DECLARE_DELETED_COPY_ASSIGNMENT(editor); private: tile_type _floor{editor_mode::floor, "floor"}; diff --git a/main/gui.cpp b/main/gui.cpp new file mode 100644 index 00000000..d5a8f149 --- /dev/null +++ b/main/gui.cpp @@ -0,0 +1,134 @@ +#include "app.hpp" +#include "imgui-raii.hpp" +#include +#include + +namespace floormat { + +using namespace floormat::imgui; + +void app::setup_menu() +{ + GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::BlendEquation::Add); + GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::BlendFunction::OneMinusSourceAlpha); +} + +void app::display_menu() +{ + GL::Renderer::enable(GL::Renderer::Feature::Blending); + GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); + GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); + GL::Renderer::disable(GL::Renderer::Feature::DepthTest); + _imgui.drawFrame(); + GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); +} + +void app::do_menu() +{ + _imgui.newFrame(); + float main_menu_height = 0; + if (auto b = begin_main_menu()) + { + if (auto b = begin_menu("File")) + { + ImGui::MenuItem("Open", "Ctrl+O"); + ImGui::MenuItem("Recent"); + ImGui::Separator(); + ImGui::MenuItem("Save", "Ctrl+S"); + ImGui::MenuItem("Save as...", "Ctrl+Shift+S"); + ImGui::Separator(); + ImGui::MenuItem("Close"); + } + if (auto b = begin_menu("Mode")) + { + ImGui::MenuItem("Select", "F1", _editor.mode() == editor_mode::select); + ImGui::MenuItem("Floor", "F2", _editor.mode() == editor_mode::floor); + ImGui::MenuItem("Walls", "F3", _editor.mode() == editor_mode::walls); + } + + main_menu_height = ImGui::GetContentRegionMax().y; + } + draw_menu_(_editor.floor(), main_menu_height); +} + +void app::draw_menu_(tile_type& type, float main_menu_height) +{ + if (ImGui::GetIO().WantTextInput && !isTextInputActive()) + startTextInput(); + else if (!ImGui::GetIO().WantTextInput && isTextInputActive()) + stopTextInput(); + + auto& style = ImGui::GetStyle(); + ImGui::StyleColorsDark(&style); + style.WindowPadding = {8, 8}; + style.WindowBorderSize = {}; + style.FramePadding = {4, 4}; + style.Colors[ImGuiCol_WindowBg] = {0, 0, 0, .5}; + style.Colors[ImGuiCol_FrameBg] = {0, 0, 0, 0}; + + if (main_menu_height > 0) + { + ImGui::SetNextWindowPos({0, main_menu_height+style.WindowPadding.y}); + ImGui::SetNextFrameWantCaptureKeyboard(false); + ImGui::SetNextWindowSize({450, windowSize()[1] - main_menu_height - style.WindowPadding.y}); + if (const auto flags = ImGuiWindowFlags_(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings); + auto b = begin_window({}, flags)) + { + const float window_width = ImGui::GetWindowWidth() - 32; + + char buf[64]; + //ImGui::SetNextWindowBgAlpha(.2f); + + if (auto b = begin_list_box("##tiles", {-FLT_MIN, -1})) + { + for (const auto& [k, v] : type) + { + const auto& k_ = k; + const auto& v_ = v; + const auto click_event = [&] { + if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) + _editor.floor().select_tile_permutation(v_); + }; + const auto add_tile_count = [&] { + snprintf(buf, sizeof(buf), "%zu", (std::size_t)v_->num_tiles().product()); + ImGui::SameLine(window_width - ImGui::CalcTextSize(buf).x - style.FramePadding.x - 4); + ImGui::Text("%s", buf); + }; + const std::size_t N = v->num_tiles().product(); + if (const auto flags = ImGuiTreeNodeFlags_(ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Framed); + auto b = tree_node(k.data(), flags)) + { + click_event(); + add_tile_count(); + auto c = push_style_var(ImGuiStyleVar_FramePadding, {1, 1}); + auto c2 = push_style_var(ImGuiStyleVar_FrameBorderSize, 3); + auto c3 = push_style_color(ImGuiCol_Button, {1, 1, 1, 1}); + 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(); + snprintf(buf, sizeof(buf), "##item_%zu", i); + const auto uv = v->texcoords_for_id(i); + ImGui::ImageButton(buf, (void*)&v->texture(), {TILE_SIZE[0]/2, TILE_SIZE[1]/2}, + { uv[3][0], uv[3][1] }, { uv[0][0], uv[0][1] }); + if (ImGui::IsItemClicked()) + _editor.floor().select_tile(v, (std::uint8_t)i); + else + click_event(); + ImGui::SameLine(); + } + ImGui::NewLine(); + } + else + { + click_event(); + add_tile_count(); + } + } + } + } + } +} + +} // namespace floormat diff --git a/main/main.cpp b/main/main.cpp index e371713b..b032e2a2 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -7,22 +7,6 @@ namespace floormat { -chunk app::make_test_chunk() -{ - constexpr auto N = TILE_MAX_DIM; - chunk c; - for (auto [x, k, pt] : c) { - const auto& atlas = pt.x > N/2 && pt.y >= N/2 ? floor2 : floor1; - x.ground_image = { atlas, (std::uint8_t)(k % atlas->num_tiles().product()) }; - } - constexpr auto K = N/2; - c[{K, K }].wall_north = { wall1, 0 }; - c[{K, K }].wall_west = { wall2, 0 }; - c[{K, K+1}].wall_north = { wall1, 0 }; - c[{K+1, K }].wall_west = { wall2, 0 }; - return c; -} - void app::drawEvent() { #if 0 GL::defaultFramebuffer.clear(GL::FramebufferClear::Color | GL::FramebufferClear::Depth); @@ -52,6 +36,27 @@ void app::drawEvent() { void app::draw_chunk(chunk& c) { + { + int minx = 0, maxx = 0, miny = 0, maxy = 0; + auto fn = [&](int x, int y) { + const auto pos = pixel_to_tile({(float)x, (float)y}) / Vector2{TILE_MAX_DIM, TILE_MAX_DIM}; + minx = std::min(minx, (int)std::floor(pos[0])); + maxx = std::max(maxx, (int)(pos[0])); + miny = std::min(miny, (int)std::floor(pos[1])); + maxy = std::max(maxy, (int)(pos[1])); + }; + const auto sz = windowSize(); + const auto x = sz[0], y = sz[1]; + fn(0, 0); + fn(x, 0); + fn(0, y); + fn(x, y); + + printf("%d %d -> %d %d\n", minx, miny, maxx, maxy); + fflush(stdout); + printf(""); // put breakpoint here + } + _shader.set_tint({1, 1, 1, 1}); _floor_mesh.draw(_shader, c); _wall_mesh.draw(_shader, c); diff --git a/main/menu.cpp b/main/menu.cpp deleted file mode 100644 index 2874ad96..00000000 --- a/main/menu.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "app.hpp" -#include "imgui-raii.hpp" -#include -#include - -namespace floormat { - -using namespace floormat::imgui; - -void app::setup_menu() -{ - GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::BlendEquation::Add); - GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::BlendFunction::OneMinusSourceAlpha); -} - -void app::display_menu() -{ - GL::Renderer::enable(GL::Renderer::Feature::Blending); - GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); - GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); - GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - _imgui.drawFrame(); - GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); -} - -void app::do_menu() -{ - _imgui.newFrame(); - float main_menu_height = 0; - if (auto b = begin_main_menu()) - { - if (auto b = begin_menu("File")) - { - ImGui::MenuItem("Open", "Ctrl+O"); - ImGui::MenuItem("Recent"); - ImGui::Separator(); - ImGui::MenuItem("Save", "Ctrl+S"); - ImGui::MenuItem("Save as...", "Ctrl+Shift+S"); - ImGui::Separator(); - ImGui::MenuItem("Close"); - } - if (auto b = begin_menu("Mode")) - { - ImGui::MenuItem("Select", "F1", _editor.mode() == editor_mode::select); - ImGui::MenuItem("Floor", "F2", _editor.mode() == editor_mode::floor); - ImGui::MenuItem("Walls", "F3", _editor.mode() == editor_mode::walls); - } - - main_menu_height = ImGui::GetContentRegionMax().y; - } - draw_menu_(_editor.floor(), main_menu_height); -} - -void app::draw_menu_(tile_type& type, float main_menu_height) -{ - if (ImGui::GetIO().WantTextInput && !isTextInputActive()) - startTextInput(); - else if (!ImGui::GetIO().WantTextInput && isTextInputActive()) - stopTextInput(); - - auto& style = ImGui::GetStyle(); - ImGui::StyleColorsDark(&style); - style.WindowPadding = {8, 8}; - style.WindowBorderSize = {}; - style.FramePadding = {4, 4}; - style.Colors[ImGuiCol_WindowBg] = {0, 0, 0, .5}; - style.Colors[ImGuiCol_FrameBg] = {0, 0, 0, 0}; - - if (main_menu_height > 0) - { - ImGui::SetNextWindowPos({0, main_menu_height+style.WindowPadding.y}); - ImGui::SetNextFrameWantCaptureKeyboard(false); - ImGui::SetNextWindowSize({450, windowSize()[1] - main_menu_height - style.WindowPadding.y}); - if (const auto flags = ImGuiWindowFlags_(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings); - auto b = begin_window({}, flags)) - { - const float window_width = ImGui::GetWindowWidth() - 32; - - char buf[64]; - //ImGui::SetNextWindowBgAlpha(.2f); - - if (auto b = begin_list_box("##tiles", {-FLT_MIN, -1})) - { - for (const auto& [k, v] : type) - { - const auto& k_ = k; - const auto& v_ = v; - const auto click_event = [&] { - if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) - { - Debug{} << "shuffle" << k_.data(); - } - }; - const auto add_tile_count = [&] { - snprintf(buf, sizeof(buf), "%zu", (std::size_t)v_->num_tiles().product()); - ImGui::SameLine(window_width - ImGui::CalcTextSize(buf).x - style.FramePadding.x - 4); - ImGui::Text("%s", buf); - }; - const std::size_t N = v->num_tiles().product(); - if (const auto flags = ImGuiTreeNodeFlags_(ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Framed); - auto b = tree_node(k.data(), flags)) - { - click_event(); - add_tile_count(); - auto c = push_style_var(ImGuiStyleVar_FramePadding, {1, 1}); - auto c2 = push_style_var(ImGuiStyleVar_FrameBorderSize, 3); - auto c3 = push_style_color(ImGuiCol_Button, {1, 1, 1, 1}); - 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(); - snprintf(buf, sizeof(buf), "##item_%zu", i); - const auto uv = v->texcoords_for_id(i); - ImGui::ImageButton(buf, (void*)&v->texture(), {TILE_SIZE[0]/2, TILE_SIZE[1]/2}, - { uv[3][0], uv[3][1] }, { uv[0][0], uv[0][1] }); - if (ImGui::IsItemClicked()) - { - Debug{} << "tile" << buf+2 << i; - fflush(stdout); - } - else - click_event(); - ImGui::SameLine(); - } - ImGui::NewLine(); - } - else - { - click_event(); - add_tile_count(); - } - } - } - } - } -} - -} // namespace floormat diff --git a/main/update.cpp b/main/update.cpp new file mode 100644 index 00000000..1c7bb500 --- /dev/null +++ b/main/update.cpp @@ -0,0 +1,53 @@ +#include "app.hpp" + +namespace floormat { + +chunk app::make_test_chunk() +{ + constexpr auto N = TILE_MAX_DIM; + chunk c; + for (auto [x, k, pt] : c) { + const auto& atlas = pt.x > N/2 && pt.y >= N/2 ? floor2 : floor1; + x.ground_image = { atlas, (std::uint8_t)(k % atlas->num_tiles().product()) }; + } + constexpr auto K = N/2; + c[{K, K }].wall_north = { wall1, 0 }; + c[{K, K }].wall_west = { wall2, 0 }; + c[{K, K+1}].wall_north = { wall1, 0 }; + c[{K+1, K }].wall_west = { wall2, 0 }; + return c; +} + +void app::do_mouse_click(const Vector2 pos, int button) +{ + _editor.click_at_tile(pos, button); +} + +void app::update(float dt) +{ + do_camera(dt); + do_menu(); + if (keys[key::quit]) + Platform::Sdl2Application::exit(0); +} + +Vector2 app::pixel_to_tile(Vector2 position) const +{ + const auto px = position - Vector2{windowSize()}*.5f - camera_offset; + return unproject(px) / Vector2{TILE_SIZE[0]*.5f, TILE_SIZE[1]*.5f} + Vector2{.5f, .5f}; +} + +void app::draw_cursor_tile() +{ + if (_cursor_pos) + { + const auto tile = pixel_to_tile(Vector2(*_cursor_pos)); + if (std::min(tile[0], tile[1]) >= 0 && std::max(tile[0], tile[1]) < (int)TILE_MAX_DIM) + { + const auto x = std::uint8_t(tile[0]), y = std::uint8_t(tile[1]); + draw_wireframe_quad({x, y}); + } + } +} + +} // namespace floormat diff --git a/src/world.hpp b/src/world.hpp index 0d28429e..b21502e0 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -9,21 +9,12 @@ struct chunk_coords final { }; struct global_coords final { + std::int16_t cx = 0, cy = 0; 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_}; -} + constexpr global_coords(chunk_coords c, local_coords xy) + : cx{c.x}, cy{c.y}, x{xy.x}, y{xy.y} + {} +}; } // namespace floormat -- cgit v1.2.3