summaryrefslogtreecommitdiffhomepage
path: root/editor/editor.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-06 18:14:02 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-06 18:14:02 +0100
commitedc3ad8c86cb1a042134f82c738029004b116d86 (patch)
tree1535f1450a859a4489f0e62dcc36e56015abe78c /editor/editor.cpp
parentacf6f498818572528003ffc62f02fdcd4bf71a9a (diff)
editor stuff
Diffstat (limited to 'editor/editor.cpp')
-rw-r--r--editor/editor.cpp282
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