summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compat/enum-bitset.hpp20
-rw-r--r--editor/app.hpp21
-rw-r--r--editor/camera.cpp56
-rw-r--r--editor/editor.cpp5
-rw-r--r--editor/editor.hpp10
-rw-r--r--editor/events.cpp38
-rw-r--r--editor/imgui.cpp13
-rw-r--r--editor/update.cpp63
8 files changed, 97 insertions, 129 deletions
diff --git a/compat/enum-bitset.hpp b/compat/enum-bitset.hpp
index 1365b3fb..0a1f91e4 100644
--- a/compat/enum-bitset.hpp
+++ b/compat/enum-bitset.hpp
@@ -4,16 +4,16 @@
namespace floormat {
template<typename Enum>
-requires std::is_enum_v<Enum>
-struct enum_bitset : std::bitset<(std::size_t)Enum::MAX> {
- using type = Enum;
- static_assert(std::is_same_v<std::size_t, std::common_type_t<std::size_t, std::underlying_type_t<Enum>>>);
- static_assert(std::is_same_v<Enum, std::decay_t<Enum>>);
- using std::bitset<(std::size_t)Enum::MAX>::bitset;
- constexpr bool operator[](Enum x) const { return operator[]((std::size_t)x); }
- constexpr decltype(auto) operator[](Enum x) {
- return std::bitset<(std::size_t)Enum::MAX>::operator[]((std::size_t)x);
- }
+requires (std::is_enum_v<Enum> && std::is_same_v<std::size_t, std::common_type_t<std::size_t, std::underlying_type_t<Enum>>>)
+struct enum_bitset : std::bitset<std::size_t(Enum::COUNT)> {
+ using enum_type = Enum;
+ using value_type = std::underlying_type_t<enum_type>;
+
+ static constexpr auto COUNT = std::size_t{value_type(Enum::COUNT)};
+
+ using std::bitset<COUNT>::bitset;
+ constexpr bool operator[](Enum x) const { return std::bitset<COUNT>::operator[](std::size_t{value_type(x)}); }
+ constexpr decltype(auto) operator[](Enum x) { return std::bitset<COUNT>::operator[](std::size_t{value_type(x)}); }
};
} // namespace floormat
diff --git a/editor/app.hpp b/editor/app.hpp
index 3d25fb4e..ccc4d8bf 100644
--- a/editor/app.hpp
+++ b/editor/app.hpp
@@ -41,12 +41,14 @@ private:
fm_DECLARE_DELETED_COPY_ASSIGNMENT(app);
fm_DECLARE_DEPRECATED_MOVE_ASSIGNMENT(app);
- enum class key : int {
+ enum class key : unsigned {
+ noop,
camera_up, camera_left, camera_right, camera_down, camera_reset,
- rotate_tile, quicksave, quickload,
- mode_select, mode_floor, mode_walls,
+ rotate_tile,
+ mode_none, mode_floor, mode_walls,
quit,
- MAX = quit, COUNT, NO_REPEAT = rotate_tile,
+ quicksave, quickload,
+ COUNT, MIN = noop, NO_REPEAT = rotate_tile, GLOBAL = quicksave,
};
void update(float dt) override;
@@ -69,17 +71,12 @@ private:
int exec();
- static int run_from_argv(int argv, const char* const* argc);
-
void maybe_initialize_chunk_(const chunk_coords& pos, chunk& c);
void do_mouse_move();
void do_mouse_up_down(std::uint8_t button, bool is_down);
- void do_camera(float dt);
-
- void do_keys();
- enum_bitset<key> get_nonrepeat_keys();
+ void do_camera(float dt, const enum_bitset<key>& cmds);
void do_quicksave();
void do_quickload();
@@ -94,6 +91,8 @@ private:
void draw_fps();
void draw_cursor_tile_text();
void render_menu();
+ void apply_commands(const enum_bitset<key>& k);
+ void clear_non_global_keys();
void draw_editor_pane(tile_editor& type, float main_menu_height);
@@ -105,7 +104,7 @@ private:
wireframe_mesh<wireframe::quad_wall_w> _wireframe_wall_w;
wireframe_mesh<wireframe::box> _wireframe_box;
editor _editor;
- enum_bitset<key> keys, keys_repeat;
+ enum_bitset<key> keys;
cursor_state cursor;
};
diff --git a/editor/camera.cpp b/editor/camera.cpp
index 8929c97e..c03808d7 100644
--- a/editor/camera.cpp
+++ b/editor/camera.cpp
@@ -5,45 +5,45 @@
namespace floormat {
-void app::do_camera(float dt)
+void app::do_camera(float dt, const enum_bitset<key>& cmds)
{
- if (keys[key::camera_reset])
+ if (cmds[key::camera_reset])
{
reset_camera_offset();
+ update_cursor_tile(cursor.pixel);
do_mouse_move();
+ return;
}
- else
- {
- Vector2d dir{};
- if (keys[key::camera_up])
- dir += Vector2d{0, -1};
- else if (keys[key::camera_down])
- dir += Vector2d{0, 1};
- if (keys[key::camera_left])
- dir += Vector2d{-1, 0};
- else if (keys[key::camera_right])
- dir += Vector2d{1, 0};
+ Vector2d dir{};
- if (dir != Vector2d{})
- {
- auto& shader = M->shader();
- const auto sz = M->window_size();
- constexpr double screens_per_second = 0.75;
+ if (cmds[key::camera_up])
+ dir += Vector2d{0, -1};
+ else if (cmds[key::camera_down])
+ dir += Vector2d{0, 1};
+ if (cmds[key::camera_left])
+ dir += Vector2d{-1, 0};
+ else if (cmds[key::camera_right])
+ dir += Vector2d{1, 0};
- const double pixels_per_second = sz.length() / screens_per_second;
- auto camera_offset = shader.camera_offset();
- const auto max_camera_offset = Vector2d(sz * 10);
+ if (dir != Vector2d{})
+ {
+ auto& shader = M->shader();
+ const auto sz = M->window_size();
+ constexpr double screens_per_second = 0.75;
- camera_offset -= dir.normalized() * (double)dt * pixels_per_second;
- camera_offset[0] = std::clamp(camera_offset[0], -max_camera_offset[0], max_camera_offset[0]);
- camera_offset[1] = std::clamp(camera_offset[1], -max_camera_offset[1], max_camera_offset[1]);
+ const double pixels_per_second = sz.length() / screens_per_second;
+ auto camera_offset = shader.camera_offset();
+ const auto max_camera_offset = Vector2d(sz * 10);
- shader.set_camera_offset(camera_offset);
+ camera_offset -= dir.normalized() * (double)dt * pixels_per_second;
+ camera_offset[0] = std::clamp(camera_offset[0], -max_camera_offset[0], max_camera_offset[0]);
+ camera_offset[1] = std::clamp(camera_offset[1], -max_camera_offset[1], max_camera_offset[1]);
- update_cursor_tile(cursor.pixel);
- do_mouse_move();
- }
+ shader.set_camera_offset(camera_offset);
+
+ update_cursor_tile(cursor.pixel);
+ do_mouse_move();
}
}
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 2bfd481f..58b20e68 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -158,7 +158,7 @@ void tile_editor::place_tile(world& world, global_coords pos, tile_image& img)
default:
fm_warn_once("invalid editor mode '%u'", (unsigned)_mode);
break;
- case editor_mode::select:
+ case editor_mode::none:
break;
case editor_mode::floor:
t.ground = { atlas, variant };
@@ -197,7 +197,6 @@ void tile_editor::set_rotation(editor_wall_rotation r)
editor::editor()
{
- set_mode(editor_mode::floor); // TODO
}
void editor::set_mode(editor_mode mode)
@@ -210,7 +209,7 @@ const tile_editor* editor::current() const noexcept
{
switch (_mode)
{
- case editor_mode::select:
+ case editor_mode::none:
return nullptr;
case editor_mode::floor:
return &_floor;
diff --git a/editor/editor.hpp b/editor/editor.hpp
index dfd2207d..113cb915 100644
--- a/editor/editor.hpp
+++ b/editor/editor.hpp
@@ -16,7 +16,7 @@
namespace floormat {
enum class editor_mode : unsigned char {
- select, floor, walls,
+ none, floor, walls,
};
enum class editor_wall_rotation : std::uint8_t {
@@ -86,15 +86,15 @@ struct editor final
editor& operator=(editor&&) noexcept = default;
fm_DECLARE_DELETED_COPY_ASSIGNMENT(editor);
- using rotation = editor_wall_rotation;
static constexpr inline auto rotation_N = editor_wall_rotation::N;
static constexpr inline auto rotation_W = editor_wall_rotation::W;
private:
- tile_editor _floor{ editor_mode::floor, "floor"};
- tile_editor _wall{ editor_mode::walls, "wall"};
+ tile_editor _floor{ editor_mode::floor, "floor" };
+ tile_editor _wall { editor_mode::walls, "wall" };
+
std::optional<global_coords> _last_pos;
- editor_mode _mode = editor_mode::select;
+ editor_mode _mode = editor_mode::none;
bool _dirty = false;
};
diff --git a/editor/events.cpp b/editor/events.cpp
index 42420686..8a665c64 100644
--- a/editor/events.cpp
+++ b/editor/events.cpp
@@ -18,6 +18,13 @@ void app::on_any_event(const any_event&) noexcept {}
#define accessor(type, name) \
type m_##name = {}; auto name() const noexcept { return m_##name; }
+void app::clear_non_global_keys()
+{
+ using key_type = decltype(keys)::value_type;
+ for (key i = key::MIN; i < key::GLOBAL; i = key{key_type(i) + 1})
+ keys[i] = false;
+}
+
void app::on_mouse_move(const mouse_move_event& event) noexcept
{
struct {
@@ -42,15 +49,10 @@ void app::on_mouse_up_down(const mouse_button_event& event, bool is_down) noexce
accessor(Button, button)
} e = {event.position, Button(event.button)};
- if (cursor.in_imgui = is_down
- ? _imgui.handleMousePressEvent(e)
- : _imgui.handleMouseReleaseEvent(e);
- !cursor.in_imgui)
- {
- update_cursor_tile(event.position);
- if (cursor.tile)
- do_mouse_up_down(event.button, is_down);
- }
+ if (!(cursor.in_imgui = is_down ? _imgui.handleMousePressEvent(e) : _imgui.handleMouseReleaseEvent(e)))
+ do_mouse_up_down(event.button, is_down);
+ else
+ clear_non_global_keys();
}
void app::on_mouse_scroll(const mouse_scroll_event& event) noexcept
@@ -84,24 +86,18 @@ void app::on_key_up_down(const key_event& event, bool is_down) noexcept
case SDLK_d: return key::camera_right;
case SDLK_HOME: return key::camera_reset;
case SDLK_r: return key::rotate_tile;
- case SDLK_1: return key::mode_select;
+ case SDLK_1: return key::mode_none;
case SDLK_2: return key::mode_floor;
case SDLK_3: return key::mode_walls;
case SDLK_F5: return key::quicksave;
case SDLK_F9: return key::quickload;
case SDLK_ESCAPE: return key::quit;
});
- if (x != key::COUNT)
- {
+ if (x != key::COUNT && (!event.is_repeated || (key)x < key::NO_REPEAT))
keys[x] = is_down;
- keys_repeat[x] = is_down ? event.is_repeated : false;
- }
}
else
- {
- keys = {};
- keys_repeat = {};
- }
+ clear_non_global_keys();
}
void app::on_text_input_event(const text_input_event& event) noexcept
@@ -110,10 +106,7 @@ void app::on_text_input_event(const text_input_event& event) noexcept
accessor(Containers::StringView, text)
} e = {event.text};
if (_imgui.handleTextInputEvent(e))
- {
- keys = {};
- keys_repeat = {};
- }
+ clear_non_global_keys();
}
void app::on_viewport_event(const Math::Vector2<int>& size) noexcept
@@ -125,7 +118,6 @@ void app::on_focus_out() noexcept
{
update_cursor_tile(std::nullopt);
keys = {};
- keys_repeat = {};
}
void app::on_mouse_leave() noexcept
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index 83824967..588f4031 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -45,9 +45,16 @@ float app::draw_main_menu()
}
if (auto b = begin_menu("Mode"))
{
- ImGui::MenuItem("Select", "1", _editor.mode() == editor_mode::select);
- ImGui::MenuItem("Floor", "2", _editor.mode() == editor_mode::floor);
- ImGui::MenuItem("Walls", "3", _editor.mode() == editor_mode::walls);
+ bool b_none = false, b_floor = false, b_walls = false;
+ ImGui::MenuItem("Select", "1", &b_none);
+ ImGui::MenuItem("Floor", "2", &b_floor);
+ ImGui::MenuItem("Walls", "3", &b_walls);
+ if (b_none)
+ keys[key::mode_none] = true;
+ if (b_floor)
+ keys[key::mode_floor] = true;
+ if (b_walls)
+ keys[key::mode_walls] = true;
}
main_menu_height = ImGui::GetContentRegionMax().y;
diff --git a/editor/update.cpp b/editor/update.cpp
index 8ff4246b..b26c783b 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -43,70 +43,41 @@ void app::do_mouse_move()
void app::do_mouse_up_down(std::uint8_t button, bool is_down)
{
- if (!cursor.in_imgui && button == mouse_button_left && is_down)
+ if (cursor.tile && !cursor.in_imgui && button == mouse_button_left && is_down)
_editor.on_click(M->world(), *cursor.tile);
else
_editor.on_release();
}
-auto app::get_nonrepeat_keys() -> enum_bitset<key>
+void app::apply_commands(const enum_bitset<key>& k)
{
- enum_bitset<key> ret;
- using type = std::underlying_type_t<key>;
- for (auto i = (type)key::NO_REPEAT; i < (type)key::COUNT; i++)
- {
- auto idx = key{i};
- if (keys_repeat[idx])
- keys[idx] = false;
- else
- ret[idx] = keys[idx];
- keys[idx] = false;
- keys_repeat[idx] = false;
- }
- return ret;
-}
-
-void app::do_keys()
-{
- auto k = get_nonrepeat_keys();
- using type = std::underlying_type_t<key>;
-
- for (auto i = (type)key::NO_REPEAT; i < (type)key::COUNT; i++)
+ if (keys[key::quit])
{
- auto idx = key{i};
- if (keys_repeat[idx])
- k[idx] = false;
- keys[idx] = false;
- keys_repeat[idx] = false;
+ M->quit(0);
+ return;
}
- if (k[key::quicksave])
- do_quicksave();
- if (k[key::quickload])
- do_quickload();
- if (k[key::mode_select])
- _editor.set_mode(editor_mode::select);
+ if (k[key::mode_none])
+ _editor.set_mode(editor_mode::none);
if (k[key::mode_floor])
_editor.set_mode(editor_mode::floor);
if (k[key::mode_walls])
_editor.set_mode(editor_mode::walls);
-
- if (auto* ed = _editor.current(); ed)
- {
- if (k[key::rotate_tile])
+ if (k[key::rotate_tile])
+ if (auto* ed = _editor.current(); ed)
ed->toggle_rotation();
- }
+
+ if (k[key::quicksave])
+ do_quicksave();
+ if (k[key::quickload])
+ do_quickload();
}
void app::update(float dt)
{
- if (keys[key::quit])
- M->quit(0);
- else {
- do_camera(dt);
- draw_ui();
- do_keys();
- }
+ draw_ui();
+ apply_commands(keys);
+ do_camera(dt, keys);
}
} // namespace floormat