diff options
-rw-r--r-- | editor/app.hpp | 4 | ||||
-rw-r--r-- | editor/draw.cpp | 16 | ||||
-rw-r--r-- | editor/editor.hpp | 2 | ||||
-rw-r--r-- | editor/imgui.cpp | 1 | ||||
-rw-r--r-- | editor/tile-editor.cpp | 9 | ||||
-rw-r--r-- | editor/update.cpp | 33 | ||||
-rw-r--r-- | floormat/main.hpp | 3 | ||||
-rw-r--r-- | loader/atlas.cpp | 1 | ||||
-rw-r--r-- | main/draw.cpp | 2 | ||||
-rw-r--r-- | main/main-impl.hpp | 4 | ||||
-rw-r--r-- | src/scenery.cpp | 53 | ||||
-rw-r--r-- | src/scenery.hpp | 3 |
12 files changed, 77 insertions, 54 deletions
diff --git a/editor/app.hpp b/editor/app.hpp index badca9a9..7a1bf89d 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -28,6 +28,7 @@ struct anim_atlas; struct cursor_state final { Optional<Vector2i> pixel; Optional<global_coords> tile; + bool in_imgui = false; }; @@ -60,6 +61,7 @@ private: int exec(); void update(float dt) override; + void update_world(float dt); void update_cursor_tile(const Optional<Vector2i>& pixel); void maybe_initialize_chunk(const chunk_coords& pos, chunk& c) override; void maybe_initialize_chunk_(const chunk_coords& pos, chunk& c); @@ -85,7 +87,7 @@ private: void do_camera(float dt, const key_set& cmds, int mods); void reset_camera_offset(); - clickable_scenery* find_clickable_scenery(); + clickable_scenery* find_clickable_scenery(Vector2i pixel); void do_quicksave(); void do_quickload(); diff --git a/editor/draw.cpp b/editor/draw.cpp index 9915a93e..17be7aeb 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -35,21 +35,21 @@ void app::draw_cursor() void app::draw() { - draw_cursor(); + if (_editor.current_tile_editor()) + draw_cursor(); draw_ui(); render_menu(); } -clickable_scenery* app::find_clickable_scenery() +clickable_scenery* app::find_clickable_scenery(Vector2i pixel_) { + clickable_scenery* item = nullptr; if (cursor.tile) { - float depth = -2; - clickable_scenery* item = nullptr; + float depth = -1; auto array = M->clickable_scenery(); - const auto pixel = Vector2ui(*cursor.pixel); + const auto pixel = Vector2ui(pixel_); for (clickable_scenery& c : array) - { if (c.depth > depth && c.dest.contains(pixel)) { const auto pos = pixel - c.dest.min() + c.src.min(); @@ -62,10 +62,8 @@ clickable_scenery* app::find_clickable_scenery() item = &c; } } - } - return item; } - return nullptr; + return item; } } // namespace floormat diff --git a/editor/editor.hpp b/editor/editor.hpp index bcbc26d1..e0c4f848 100644 --- a/editor/editor.hpp +++ b/editor/editor.hpp @@ -58,7 +58,7 @@ private: button btn; }; Optional<drag_pos> _last_pos; - editor_mode _mode = editor_mode::floor; + editor_mode _mode = editor_mode::none; bool _dirty = false; }; diff --git a/editor/imgui.cpp b/editor/imgui.cpp index 7b64c133..afa55485 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -86,7 +86,6 @@ void app::draw_ui() const float main_menu_height = draw_main_menu(); if (auto* ed = _editor.current_tile_editor(); ed != nullptr) draw_editor_pane(*ed, main_menu_height); - draw_cursor(); [[maybe_unused]] auto font = font_saver{ctx.FontSize*dpi}; draw_fps(); draw_tile_under_cursor(); diff --git a/editor/tile-editor.cpp b/editor/tile-editor.cpp index 9f9b6571..4ae54d86 100644 --- a/editor/tile-editor.cpp +++ b/editor/tile-editor.cpp @@ -172,7 +172,9 @@ void tile_editor::place_tile(world& world, global_coords pos, const tile_image_p void tile_editor::toggle_rotation() { - if (_rotation == editor_wall_rotation::W) + if (_mode != editor_mode::walls) + _rotation = editor_wall_rotation::N; + else if (_rotation == editor_wall_rotation::W) _rotation = editor_wall_rotation::N; else _rotation = editor_wall_rotation::W; @@ -187,7 +189,10 @@ void tile_editor::set_rotation(editor_wall_rotation r) return; case editor_wall_rotation::W: case editor_wall_rotation::N: - _rotation = r; + if (_mode == editor_mode::walls) + _rotation = r; + else + _rotation = editor_wall_rotation::N; break; } } diff --git a/editor/update.cpp b/editor/update.cpp index c68c7517..a253c3c4 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -1,6 +1,7 @@ #include "app.hpp" -#include "src/chunk.hpp" +#include "src/world.hpp" #include "src/tile-atlas.hpp" +#include "main/clickable.hpp" #include "floormat/events.hpp" #include "floormat/main.hpp" @@ -46,7 +47,14 @@ void app::do_mouse_move(int mods) void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods) { - if (cursor.tile && !cursor.in_imgui && is_down) + update_cursor_tile(cursor.pixel); + if (!_editor.current_tile_editor()) + { + if (cursor.tile) + if (auto* s = find_clickable_scenery(*cursor.pixel)) + s->item.activate(s->atlas); + } + else if (cursor.tile && !cursor.in_imgui && is_down) { auto& w = M->world(); auto pos = *cursor.tile; @@ -60,7 +68,6 @@ void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods) } } _editor.on_release(); - update_cursor_tile(cursor.pixel); } void app::do_key(key k, int mods) @@ -98,19 +105,29 @@ void app::apply_commands(const key_set& keys) do_key(k, key_modifiers[i]); } -using clickable_scenery = clickable<anim_atlas, scenery>; - - +void app::update_world(float dt) +{ + auto& world = M->world(); + auto [minx, maxx, miny, maxy] = M->get_draw_bounds(); + minx--; miny--; maxx++; maxy++; + for (std::int16_t y = miny; y <= maxy; y++) + for (std::int16_t x = minx; x <= maxx; x++) + for (chunk_coords c{x, y}; auto [x, k, pt] : world[c]) + if (auto [atlas, scenery] = x.scenery(); atlas != nullptr) + scenery.update(dt, *atlas); +} void app::update(float dt) { + update_world(dt); apply_commands(keys); do_camera(dt, keys, get_key_modifiers()); - if (auto* s = find_clickable_scenery()) + clear_non_repeated_keys(); + + if (!_editor.current_tile_editor() && cursor.tile && find_clickable_scenery(*cursor.pixel)) M->set_cursor(std::uint32_t(Cursor::Hand)); else M->set_cursor(std::uint32_t(Cursor::Arrow)); - clear_non_repeated_keys(); } } // namespace floormat diff --git a/floormat/main.hpp b/floormat/main.hpp index b4e4d536..a470f12e 100644 --- a/floormat/main.hpp +++ b/floormat/main.hpp @@ -19,6 +19,8 @@ template<typename Atlas, typename T> struct clickable; struct floormat_main { + struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; }; + floormat_main() noexcept; virtual ~floormat_main() noexcept; @@ -45,6 +47,7 @@ struct floormat_main virtual std::uint32_t cursor() const noexcept = 0; virtual global_coords pixel_to_tile(Vector2d position) const noexcept = 0; + virtual draw_bounds get_draw_bounds() const noexcept = 0; virtual struct world& world() noexcept = 0; virtual SDL_Window* window() noexcept = 0; diff --git a/loader/atlas.cpp b/loader/atlas.cpp index fdafc39e..ab289647 100644 --- a/loader/atlas.cpp +++ b/loader/atlas.cpp @@ -43,7 +43,6 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name) fm_assert(anim_info.nframes == 1 || anim_info.fps > 0); const auto size = tex.pixels().size(); const auto width = size[1], height = size[0]; - using Vector2uz = Math::Vector2<std::size_t>; fm_assert(Vector2uz{anim_info.pixel_size} == Vector2uz(width, height)); auto atlas = std::make_shared<struct anim_atlas>(path, tex, std::move(anim_info)); diff --git a/main/draw.cpp b/main/draw.cpp index ba15b365..54f33622 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -118,7 +118,7 @@ void main_impl::draw_anim() noexcept const auto& f = atlas->frame(s.r, s.frame); constexpr Vector2 pixel88 = tile_shader::project(TILE_MAX_DIM*TILE_SIZE20*.5f); const auto world_pos = TILE_SIZE20 * Vector3(xy.x, xy.y, 0) + Vector3(g.offset); - const Vector2ui offset((Vector2(_shader.camera_offset()) + Vector2(sz) - pixel88)*.5f + const Vector2ui offset((Vector2(_shader.camera_offset()) + Vector2(sz)*.5f) + _shader.project(world_pos) - Vector2(f.ground)); clickable<anim_atlas, scenery> item = { *atlas, s, diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 7adaeaec..dd745bef 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -88,13 +88,11 @@ private: bool do_sleep = false; } dt_expected; - struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; }; - void recalc_viewport(Vector2i size) noexcept; void draw_world() noexcept; void draw_anim() noexcept; - draw_bounds get_draw_bounds() const noexcept; + draw_bounds get_draw_bounds() const noexcept override; [[nodiscard]] static bool check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept; char maybe_register_debug_callback(fm_gpu_debug flag); diff --git a/src/scenery.cpp b/src/scenery.cpp index cf2c6e98..86561a13 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -56,6 +56,9 @@ scenery::scenery(float dt, frame_t frame, rotation r, bool passable, scenery_typ void scenery::update(float dt, const anim_atlas& anim) { + if (!active) + return; + switch (type) { default: @@ -63,31 +66,31 @@ void scenery::update(float dt, const anim_atlas& anim) case scenery_type::generic: break; case scenery_type::door: - if (active) - { - const auto hz = std::uint8_t(anim.info().fps); - const auto nframes = (int)anim.info().nframes; - fm_debug_assert(anim.info().fps > 0 && anim.info().fps <= 0xff); - - delta += dt; - const float frame_time = 1000.f/hz; - const auto n = int(delta / frame_time); - delta -= frame_time * n; - fm_debug_assert(delta >= 0); - const std::int8_t dir = passable ? 1 : -1; - const int fr = frame + dir*n; - active = fr > 0 && fr < nframes-1; - passable = fr <= 0; - frame = (frame_t)std::clamp(fr, 0, nframes-1); - if (!active) - delta = 0; - } + const auto hz = std::uint8_t(anim.info().fps); + const auto nframes = (int)anim.info().nframes; + fm_debug_assert(anim.info().fps > 0 && anim.info().fps <= 0xff); + + delta += dt; + const float frame_time = 1.f/hz; + const auto n = int(delta / frame_time); + delta -= frame_time * n; + fm_debug_assert(delta >= 0); + const std::int8_t dir = closing ? 1 : -1; + const int fr = frame + dir*n; + active = fr > 0 && fr < nframes-1; + passable = fr <= 0; + frame = (frame_t)std::clamp(fr, 0, nframes-1); + if (!active) + delta = 0; break; } } bool scenery::activate(const anim_atlas& atlas) { + if (active) + return false; + switch (type) { default: @@ -95,13 +98,11 @@ bool scenery::activate(const anim_atlas& atlas) case scenery_type::generic: break; case scenery_type::door: - if (!active) - { - fm_assert(frame == 0 || frame == atlas.info().nframes-1); - active = true; - return true; - } - break; + fm_assert(frame == 0 || frame == atlas.info().nframes-1); + closing = frame == 0; + frame += closing ? 1 : -1; + active = true; + return true; } return false; } diff --git a/src/scenery.hpp b/src/scenery.hpp index fadf4da8..68bb084a 100644 --- a/src/scenery.hpp +++ b/src/scenery.hpp @@ -34,7 +34,8 @@ struct scenery final rotation r : 3 = rotation::N; std::uint8_t passable : 1 = false; std::uint8_t active : 1 = false; - scenery_type type : 3 = scenery_type::none; + std::uint8_t closing : 1 = true; + scenery_type type : 2 = scenery_type::none; scenery() noexcept; scenery(none_tag_t) noexcept; |