diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.cpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.cpp index bad82472..4b540fdf 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.cpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.cpp @@ -6,50 +6,58 @@ namespace nostalgia::gfx { -static void rotateLeft(TileSheet::SubSheet &ss, ox::Point const &pt, int const depth = 0) noexcept { +static void rotateLeft( + TileSheet::SubSheet &ss, + ox::Point const &pt, + ox::Point const &pt1, + ox::Point const &pt2, + int const depth = 0) noexcept { if (depth >= 4) { return; } - auto const h = ss.rows * TileHeight; - auto const dstPt = ox::Point{pt.y, h - 1 - pt.x}; - auto const srcIdx = ptToIdx(pt, ss.columns); + auto const dstPt = ox::Point{pt1.x + pt.y, pt2.y - pt.x}; + auto const srcIdx = ptToIdx(pt + pt1, ss.columns); auto const dstIdx = ptToIdx(dstPt, ss.columns); auto const src = ss.pixels[srcIdx]; auto &dst = ss.pixels[dstIdx]; - rotateLeft(ss, dstPt, depth + 1); + rotateLeft(ss, dstPt - pt1, pt1, pt2, depth + 1); dst = src; } -static void rotateLeft(TileSheet::SubSheet &ss) noexcept { - auto const w = ss.columns * TileWidth; - auto const h = ss.rows * TileHeight; - for (int x = 0; x < w / 2; ++x) { - for (int y = 0; y < h / 2; ++y) { - rotateLeft(ss, {w - 1 - y, x}); +static void rotateLeft(TileSheet::SubSheet &ss, ox::Point const &pt1, ox::Point const &pt2) noexcept { + auto const w = pt2.x - pt1.x; + auto const h = pt2.y - pt1.y; + for (int x = 0; x <= w / 2; ++x) { + for (int y = 0; y <= h / 2; ++y) { + rotateLeft(ss, {x, y}, pt1, pt2); } } } -static void rotateRight(TileSheet::SubSheet &ss, ox::Point const &pt, int const depth = 0) noexcept { +static void rotateRight( + TileSheet::SubSheet &ss, + ox::Point const &pt, + ox::Point const &pt1, + ox::Point const &pt2, + int const depth = 0) noexcept { if (depth >= 4) { return; } - auto const w = ss.columns * TileWidth; - auto const dstPt = ox::Point{w - 1 - pt.y, pt.x}; - auto const srcIdx = ptToIdx(pt, ss.columns); + auto const dstPt = ox::Point{pt2.x - pt.y, pt1.y + pt.x}; + auto const srcIdx = ptToIdx(pt + pt1, ss.columns); auto const dstIdx = ptToIdx(dstPt, ss.columns); auto const src = ss.pixels[srcIdx]; auto &dst = ss.pixels[dstIdx]; - rotateRight(ss, dstPt, depth + 1); + rotateRight(ss, dstPt - pt1, pt1, pt2, depth + 1); dst = src; } -static void rotateRight(TileSheet::SubSheet &ss) noexcept { - auto const w = ss.columns * TileWidth; - auto const h = ss.rows * TileHeight; - for (int x = 0; x < w / 2; ++x) { - for (int y = 0; y < h / 2; ++y) { - rotateRight(ss, {w - 1 - y, x}); +static void rotateRight(TileSheet::SubSheet &ss, ox::Point const &pt1, ox::Point const &pt2) noexcept { + auto const w = pt2.x - pt1.x; + auto const h = pt2.y - pt1.y; + for (int x = 0; x <= w / 2; ++x) { + for (int y = 0; y <= h / 2; ++y) { + rotateRight(ss, {x, y}, pt1, pt2); } } } @@ -61,28 +69,47 @@ RotateCommand::RotateCommand( Direction const dir) noexcept: m_img(img), m_idx(std::move(idx)), + m_pt2{[this] { + auto &ss = getSubSheet(m_img, m_idx); + return ox::Point{ss.columns * TileWidth - 1, ss.rows * TileHeight - 1}; + }()}, + m_dir{dir} { +} + +RotateCommand::RotateCommand( + TileSheet &img, + TileSheet::SubSheetIdx idx, + ox::Point const &pt1, + ox::Point const &pt2, + Direction const dir) noexcept: + m_img(img), + m_idx(std::move(idx)), + m_pt1{pt1}, + m_pt2{pt2}, m_dir{dir} { } ox::Error RotateCommand::redo() noexcept { + auto &ss = getSubSheet(m_img, m_idx); switch (m_dir) { case Direction::Left: - rotateLeft(getSubSheet(m_img, m_idx)); - break; + rotateLeft(ss, m_pt1, m_pt2); + break; case Direction::Right: - rotateRight(getSubSheet(m_img, m_idx)); + rotateRight(ss, m_pt1, m_pt2); break; } return {}; } ox::Error RotateCommand::undo() noexcept { + auto &ss = getSubSheet(m_img, m_idx); switch (m_dir) { case Direction::Left: - rotateRight(getSubSheet(m_img, m_idx)); + rotateRight(ss, m_pt1, m_pt2); break; case Direction::Right: - rotateLeft(getSubSheet(m_img, m_idx)); + rotateLeft(ss, m_pt1, m_pt2); break; } return {}; diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.hpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.hpp index e7a89772..2418b1a1 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.hpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/rotatecommand.hpp @@ -18,11 +18,20 @@ class RotateCommand: public TileSheetCommand { private: TileSheet &m_img; TileSheet::SubSheetIdx m_idx; + ox::Point const m_pt1; + ox::Point const m_pt2; Direction const m_dir; public: RotateCommand(TileSheet &img, TileSheet::SubSheetIdx idx, Direction dir) noexcept; + RotateCommand( + TileSheet &img, + TileSheet::SubSheetIdx idx, + ox::Point const &pt1, + ox::Point const &pt2, + Direction dir) noexcept; + ox::Error redo() noexcept final; ox::Error undo() noexcept final; diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp index 82f72b6f..2d0588a3 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp @@ -239,13 +239,25 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int const palIdx) noexcept { } ox::Error TileSheetEditorModel::rotateLeft() noexcept { + auto &ss = activeSubSheet(); + ox::Point pt1, pt2{ss.columns * TileWidth - 1, ss.rows * TileHeight - 1}; + if (m_selection) { + pt1 = m_selection->a; + pt2 = m_selection->b; + } return pushCommand(ox::make( - m_img, m_activeSubsSheetIdx, RotateCommand::Direction::Left)); + m_img, m_activeSubsSheetIdx, pt1, pt2, RotateCommand::Direction::Left)); } ox::Error TileSheetEditorModel::rotateRight() noexcept { + auto &ss = activeSubSheet(); + ox::Point pt1, pt2{ss.columns * TileWidth - 1, ss.rows * TileHeight - 1}; + if (m_selection) { + pt1 = m_selection->a; + pt2 = m_selection->b; + } return pushCommand(ox::make( - m_img, m_activeSubsSheetIdx, RotateCommand::Direction::Right)); + m_img, m_activeSubsSheetIdx, pt1, pt2, RotateCommand::Direction::Right)); } void TileSheetEditorModel::setSelection(studio::Selection const&sel) noexcept {