diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-06 18:14:02 +0100 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-06 18:14:02 +0100 |
| commit | edc3ad8c86cb1a042134f82c738029004b116d86 (patch) | |
| tree | 1535f1450a859a4489f0e62dcc36e56015abe78c /editor/editor.cpp | |
| parent | acf6f498818572528003ffc62f02fdcd4bf71a9a (diff) | |
editor stuff
Diffstat (limited to 'editor/editor.cpp')
| -rw-r--r-- | editor/editor.cpp | 282 |
1 files changed, 30 insertions, 252 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp index 499dd441..99948aca 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -1,11 +1,6 @@ #include "editor.hpp" -#include "serialize/json-helper.hpp" -#include "serialize/tile-atlas.hpp" #include "src/loader.hpp" -#include "random.hpp" -#include "compat/assert.hpp" -#include "compat/unreachable.hpp" -#include "src/tile-defs.hpp" +#include "tile-atlas.hpp" #include "src/world.hpp" #include "keys.hpp" @@ -17,249 +12,9 @@ namespace floormat { -tile_editor::tile_editor(editor_mode mode, StringView name) : _name{ name}, _mode{ mode} +tile_editor* editor::current_tile_editor() noexcept { - load_atlases(); -} - -void tile_editor::load_atlases() -{ - static const std::filesystem::path image_path{IMAGE_PATH, std::filesystem::path::generic_format}; - using atlas_array = std::vector<std::shared_ptr<tile_atlas>>; - const String filename = _name + ".json"; - const auto filename_view = std::string_view{filename.cbegin(), filename.cend()}; - for (auto& atlas : json_helper::from_json<atlas_array>(image_path/filename_view)) - { - StringView name = atlas->name(); - if (auto x = name.findLast('.'); x) - name = name.prefix(x.data()); - auto& [_, vec] = _permutation; - vec.reserve((std::size_t)atlas->num_tiles()); - _atlases[name] = std::move(atlas); - } -} - -std::shared_ptr<tile_atlas> tile_editor::maybe_atlas(StringView str) -{ - auto it = std::find_if(_atlases.begin(), _atlases.end(), [&](const auto& tuple) -> bool { - const auto& [x, _] = tuple; - return StringView{x} == str; - }); - if (it == _atlases.end()) - return nullptr; - else - return it->second; -} - -std::shared_ptr<tile_atlas> tile_editor::atlas(StringView str) -{ - if (auto ptr = maybe_atlas(str); ptr) - return ptr; - else - fm_abort("no such atlas: %s", str.cbegin()); -} - -void tile_editor::clear_selection() -{ - _selected_tile = {}; - _permutation = {}; - _selection_mode = sel_none; -} - -void tile_editor::select_tile(const std::shared_ptr<tile_atlas>& atlas, std::size_t variant) -{ - fm_assert(atlas); - clear_selection(); - _selection_mode = sel_tile; - _selected_tile = { atlas, variant_t(variant % atlas->num_tiles()) }; -} - -void tile_editor::select_tile_permutation(const std::shared_ptr<tile_atlas>& atlas) -{ - fm_assert(atlas); - clear_selection(); - _selection_mode = sel_perm; - _permutation = { atlas, {} }; -} - -bool tile_editor::is_tile_selected(const std::shared_ptr<const tile_atlas>& atlas, std::size_t variant) const -{ - return atlas && _selection_mode == sel_tile && _selected_tile && - atlas == _selected_tile.atlas && variant == _selected_tile.variant; -} - -bool tile_editor::is_permutation_selected(const std::shared_ptr<const tile_atlas>& atlas) const -{ - const auto& [perm, _] = _permutation; - return atlas && _selection_mode == sel_perm && perm == atlas; -} - -bool tile_editor::is_atlas_selected(const std::shared_ptr<const tile_atlas>& atlas) const -{ - switch (_selection_mode) - { - default: - case sel_none: - return false; - case sel_perm: - return is_permutation_selected(atlas); - case sel_tile: - return atlas && _selected_tile && atlas == _selected_tile.atlas; - } -} - -template<std::random_access_iterator T> -void fisher_yates(T begin, T end) -{ - const auto N = std::distance(begin, end); - for (auto i = N-1; i >= 1; i--) - { - const auto j = random(i+1); - using std::swap; - swap(begin[i], begin[j]); - } -} - -tile_image_proto tile_editor::get_selected_perm() -{ - auto& [atlas, vec] = _permutation; - const auto N = (variant_t)atlas->num_tiles(); - if (N == 0) - return {}; - if (vec.empty()) - { - for (variant_t i = 0; i < N; i++) - vec.push_back(i); - fisher_yates(vec.begin(), vec.end()); - } - const auto idx = vec.back(); - vec.pop_back(); - return {atlas, idx}; -} - -tile_image_proto tile_editor::get_selected() -{ - switch (_selection_mode) - { - case sel_none: - return {}; - case sel_tile: - return _selected_tile; - case sel_perm: - return get_selected_perm(); - default: - fm_warn_once("invalid editor mode '%u'", (unsigned)_selection_mode); - break; - } -} - -void tile_editor::place_tile(world& world, global_coords pos, const tile_image_proto& img) -{ - auto [c, t] = world[pos]; - switch (_mode) - { - case editor_mode::none: - break; - case editor_mode::floor: - t.ground() = img; - break; - case editor_mode::walls: - switch (_rotation) - { - case editor_wall_rotation::N: - t.wall_north() = img; - break; - case editor_wall_rotation::W: - t.wall_west() = img; - break; - } - break; - } -} - -void tile_editor::toggle_rotation() -{ - if (_rotation == editor::rotation_W) - _rotation = editor::rotation_N; - else - _rotation = editor::rotation_W; -} - -void tile_editor::set_rotation(editor_wall_rotation r) -{ - switch (r) - { - default: - fm_warn_once("invalid rotation '0x%hhx", r); - return; - case editor::rotation_W: - case editor::rotation_N: - _rotation = r; - break; - } -} - -auto tile_editor::check_snap(int mods) const -> snap_mode -{ - const bool ctrl = mods & kmod_ctrl, shift = mods & kmod_shift; - - if (!(ctrl | shift)) - return snap_mode::none; - - switch (_mode) - { - default: - case editor_mode::none: - return snap_mode::none; - case editor_mode::walls: - switch (_rotation) - { - case editor_wall_rotation::N: - return snap_mode::horizontal; - case editor_wall_rotation::W: - return snap_mode::vertical; - default: return snap_mode::none; - } - case editor_mode::floor: - if (shift) - return snap_mode::horizontal; - if (ctrl) - return snap_mode::vertical; - return snap_mode::none; - } -} - -bool tile_editor::can_rotate() const -{ - return _mode == editor_mode::walls; -} - -editor::editor() -{ -} - -void editor::set_mode(editor_mode mode) -{ - _mode = mode; - on_release(); -} - -const tile_editor* editor::current() const noexcept -{ - switch (_mode) - { - case editor_mode::floor: - return &_floor; - case editor_mode::walls: - return &_wall; // todo - default: - return nullptr; - } -} - -tile_editor* editor::current() noexcept -{ - return const_cast<tile_editor*>(static_cast<const editor&>(*this).current()); + return const_cast<tile_editor*>(static_cast<const editor&>(*this).current_tile_editor()); } void editor::on_release() @@ -270,7 +25,7 @@ void editor::on_release() auto editor::get_snap_value(snap_mode snap, int mods) const -> snap_mode { - if (const auto* mode = current(); mode != nullptr) + if (const auto* mode = current_tile_editor(); mode != nullptr) return mode->check_snap(mods); else if (snap != snap_mode::none) return snap; @@ -296,7 +51,7 @@ global_coords editor::apply_snap(global_coords pos, global_coords last, snap_mod void editor::on_mouse_move(world& world, global_coords& pos, int mods) { - if (auto* mode = current(); mode && _last_pos && _last_pos->btn != button::none) + if (auto* mode = current_tile_editor(); mode && _last_pos && _last_pos->btn != button::none) { auto& last = *_last_pos; const Vector2i offset = pos - last.coord; @@ -326,7 +81,7 @@ void editor::on_mouse_move(world& world, global_coords& pos, int mods) void editor::on_click_(world& world, global_coords pos, button b) { - if (auto* mode = current(); mode != nullptr) + if (auto* mode = current_tile_editor(); mode != nullptr) if (auto opt = mode->get_selected(); opt) { switch (b) @@ -341,11 +96,34 @@ void editor::on_click_(world& world, global_coords pos, button b) void editor::on_click(world& world, global_coords pos, int mods, button b) { - if (auto* mode = current(); mode != nullptr) + if (auto* mode = current_tile_editor(); mode != nullptr) { _last_pos = { pos, pos, mode->check_snap(mods), b }; on_click_(world, pos, b); } } +editor::editor() +{ +} + +void editor::set_mode(editor_mode mode) +{ + _mode = mode; + on_release(); +} + +const tile_editor* editor::current_tile_editor() const noexcept +{ + switch (_mode) + { + case editor_mode::floor: + return &_floor; + case editor_mode::walls: + return &_wall; // todo + default: + return nullptr; + } +} + } // namespace floormat |
