diff --git a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp index 3ea035e2..e556423b 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp @@ -74,12 +74,19 @@ struct TileSheetV3 { ox::Vector subsheets; ox::Vector pixels; constexpr SubSheet() noexcept = default; - SubSheet( + inline SubSheet( SubSheetId pId, ox::CRStringView pName, int pColumns, int pRows, - int bpp) noexcept; + int bpp) noexcept: + id(pId), + name(pName), + columns(pColumns), + rows(pRows), + pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { + } + }; static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet"; @@ -105,117 +112,36 @@ struct TileSheet { ox::Vector pixels; constexpr SubSheet() noexcept = default; - constexpr SubSheet(SubSheet const&other) noexcept = default; - SubSheet(SubSheet &&other) noexcept; - SubSheet( + inline SubSheet( SubSheetId pId, ox::CRStringView pName, int pColumns, int pRows, - int bpp) noexcept; - SubSheet( + int bpp) noexcept: + id(pId), + name(pName), + columns(pColumns), + rows(pRows), + pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { + } + inline SubSheet( SubSheetId pId, ox::CRStringView pName, int pColumns, int pRows, - ox::Vector pPixels) noexcept; - - constexpr SubSheet &operator=(const SubSheet &other) noexcept = default; - - SubSheet &operator=(SubSheet &&other) noexcept; - - [[nodiscard]] - std::size_t idx(ox::Point const&pt) const noexcept; - - /** - * Reads all pixels of this sheet or its children into the given pixel list - * @param pixels - */ - void readPixelsTo(ox::Vector &pPixels, int8_t pBpp) const noexcept; - - /** - * Reads all pixels of this sheet or its children into the given pixel list - * @param pixels - */ - void readPixelsTo(ox::Vector &pPixels) const noexcept; + ox::Vector pPixels) noexcept: + id(pId), + name(pName), + columns(pColumns), + rows(pRows), + pixels(std::move(pPixels)) { + } [[nodiscard]] constexpr std::size_t size() const noexcept { return static_cast(columns) * static_cast(rows); } - [[nodiscard]] - std::size_t unusedPixels() const noexcept; - - [[nodiscard]] - uint8_t getPixel4Bpp(std::size_t idx) const noexcept; - - [[nodiscard]] - uint8_t getPixel8Bpp(std::size_t idx) const noexcept; - - [[nodiscard]] - uint8_t getPixel(int8_t pBpp, std::size_t idx) const noexcept; - - [[nodiscard]] - uint8_t getPixel4Bpp(const ox::Point &pt) const noexcept; - - [[nodiscard]] - uint8_t getPixel8Bpp(const ox::Point &pt) const noexcept; - - [[nodiscard]] - uint8_t getPixel(int8_t pBpp, const ox::Point &pt) const noexcept; - - constexpr auto walkPixels(int8_t pBpp, auto callback) const noexcept { - if (pBpp == 4) { - const auto pixelCnt = ox::min(static_cast(columns * rows * PixelsPerTile) / 2, - pixels.size()); - //oxAssert(pixels.size() == pixelCnt, "Pixel count does not match rows and columns"); - for (std::size_t i = 0; i < pixelCnt; ++i) { - const auto colorIdx1 = static_cast(pixels[i] & 0xF); - const auto colorIdx2 = static_cast(pixels[i] >> 4); - callback(i * 2 + 0, colorIdx1); - callback(i * 2 + 1, colorIdx2); - } - } else { - const auto pixelCnt = ox::min( - static_cast(columns * rows * PixelsPerTile), - pixels.size()); - for (std::size_t i = 0; i < pixelCnt; ++i) { - const auto p = pixels[i]; - callback(i, p); - } - } - } - - void setPixel(int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept; - - void setPixel(int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept; - - ox::Error setPixelCount(int8_t pBpp, std::size_t cnt) noexcept; - - /** - * Gets a count of the pixels in this sheet, and not that of its children. - * @param pBpp bits per pixel, need for knowing how to count the pixels - * @return a count of the pixels in this sheet - */ - [[nodiscard]] - unsigned pixelCnt(int8_t pBpp) const noexcept; - - /** - * Gets the offset in tiles of the desired subsheet. - */ - ox::Result getTileOffset( - ox::SpanView const&pNamePath, - int8_t pBpp, - std::size_t pIt = 0, - unsigned pCurrentTotal = 0) const noexcept; - - ox::Result getIdFor( - ox::SpanView const&pNamePath, - std::size_t pIt = 0) const noexcept; - - ox::Result getNameFor(SubSheetId pId) const noexcept; - }; static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet"; @@ -226,84 +152,128 @@ struct TileSheet { SubSheet subsheet{0, "Root", 1, 1, bpp}; constexpr TileSheet() noexcept = default; - TileSheet(TileSheet const&other) noexcept = default; - inline TileSheet(TileSheet &&other) noexcept: - bpp(other.bpp), - idIt(other.idIt), - defaultPalette(std::move(other.defaultPalette)), - subsheet(std::move(other.subsheet)) { - } - - TileSheet &operator=(TileSheet const&other) noexcept; - - TileSheet &operator=(TileSheet &&other) noexcept; - - [[nodiscard]] - SubSheetIdx validateSubSheetIdx( - SubSheetIdx const&pIdx, - std::size_t pIdxIt, - SubSheet const&pSubsheet) noexcept; - - /** - * validateSubSheetIdx takes a SubSheetIdx and moves the index to the - * preceding or parent sheet if the current corresponding sheet does - * not exist. - * @param idx SubSheetIdx to validate and correct - * @return a valid version of idx - */ - [[nodiscard]] - SubSheetIdx validateSubSheetIdx(SubSheetIdx const&idx) noexcept; - - [[nodiscard]] - static SubSheet const&getSubSheet( - SubSheetIdx const&idx, - std::size_t idxIt, - SubSheet const&pSubsheet) noexcept; - - [[nodiscard]] - static SubSheet &getSubSheet( - SubSheetIdx const&idx, - std::size_t idxIt, - SubSheet &pSubsheet) noexcept; - - [[nodiscard]] - const SubSheet &getSubSheet(SubSheetIdx const&idx) const noexcept; - - [[nodiscard]] - SubSheet &getSubSheet(SubSheetIdx const&idx) noexcept; - - ox::Error addSubSheet(SubSheetIdx const&idx) noexcept; - - [[nodiscard]] - static ox::Error rmSubSheet( - SubSheetIdx const&idx, - std::size_t idxIt, - SubSheet &pSubsheet) noexcept; - - [[nodiscard]] - ox::Error rmSubSheet(SubSheetIdx const&idx) noexcept; - - [[nodiscard]] - uint8_t getPixel4Bpp( - ox::Point const&pt, - SubSheetIdx const&subsheetIdx) const noexcept; - - [[nodiscard]] - uint8_t getPixel8Bpp( - ox::Point const&pt, - SubSheetIdx const&subsheetIdx) const noexcept; - - ox::Result getIdFor(ox::CRStringView path) const noexcept; - - ox::Result getTileOffset(ox::CRStringView pNamePath) const noexcept; - - ox::Result getNameFor(SubSheetId pId) const noexcept; - - [[nodiscard]] - ox::Vector pixels() const noexcept; }; +[[nodiscard]] +std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; + +[[nodiscard]] +uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; + +[[nodiscard]] +uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; + +[[nodiscard]] +uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, std::size_t idx) noexcept; + +[[nodiscard]] +uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; + +[[nodiscard]] +uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; + +[[nodiscard]] +uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt) noexcept; + +constexpr void walkPixels(TileSheet::SubSheet const&ss, int8_t pBpp, auto callback) noexcept { + if (pBpp == 4) { + const auto pixelCnt = ox::min( + static_cast(ss.columns * ss.rows * PixelsPerTile) / 2, + ss.pixels.size()); + //oxAssert(pixels.size() == pixelCnt, "Pixel count does not match rows and columns"); + for (std::size_t i = 0; i < pixelCnt; ++i) { + const auto colorIdx1 = static_cast(ss.pixels[i] & 0xF); + const auto colorIdx2 = static_cast(ss.pixels[i] >> 4); + callback(i * 2 + 0, colorIdx1); + callback(i * 2 + 1, colorIdx2); + } + } else { + const auto pixelCnt = ox::min( + static_cast(ss.columns * ss.rows * PixelsPerTile), + ss.pixels.size()); + for (std::size_t i = 0; i < pixelCnt; ++i) { + const auto p = ss.pixels[i]; + callback(i, p); + } + } +} + +void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept; + +void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept; + +ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept; + +/** + * Gets a count of the pixels in this sheet, and not that of its children. + * @param pBpp bits per pixel, need for knowing how to count the pixels + * @return a count of the pixels in this sheet + */ +[[nodiscard]] +unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept; + +/** + * validateSubSheetIdx takes a SubSheetIdx and moves the index to the + * preceding or parent sheet if the current corresponding sheet does + * not exist. + * @param idx SubSheetIdx to validate and correct + * @return a valid version of idx + */ +[[nodiscard]] +TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept; + +[[nodiscard]] +TileSheet::SubSheet const&getSubSheet( + TileSheet::SubSheetIdx const&idx, + std::size_t idxIt, + TileSheet::SubSheet const&pSubsheet) noexcept; + +[[nodiscard]] +TileSheet::SubSheet &getSubSheet( + TileSheet::SubSheetIdx const&idx, + std::size_t idxIt, + TileSheet::SubSheet &pSubsheet) noexcept; + +[[nodiscard]] +TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept; + +[[nodiscard]] +TileSheet::SubSheet &getSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; + +ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; + +ox::Error rmSubSheet( + TileSheet &ts, + TileSheet::SubSheetIdx const&idx, + std::size_t idxIt, + TileSheet::SubSheet &pSubsheet) noexcept; + +ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; + +[[nodiscard]] +uint8_t getPixel4Bpp( + TileSheet const&ts, + ox::Point const&pt, + TileSheet::SubSheetIdx const&subsheetIdx) noexcept; + +[[nodiscard]] +uint8_t getPixel8Bpp( + TileSheet const&ts, + ox::Point const&pt, + TileSheet::SubSheetIdx const&subsheetIdx) noexcept; + +ox::Result getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept; + +ox::Result getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept; + +ox::Result getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept; + +ox::Result getNameFor(TileSheet const&ss, SubSheetId pId) noexcept; + +[[nodiscard]] +ox::Vector pixels(TileSheet &ts) noexcept; + using TileSheetV4 = TileSheet; struct CompactTileSheet { diff --git a/src/nostalgia/modules/core/src/keel/typeconv.cpp b/src/nostalgia/modules/core/src/keel/typeconv.cpp index e7d1eb39..9f4aefef 100644 --- a/src/nostalgia/modules/core/src/keel/typeconv.cpp +++ b/src/nostalgia/modules/core/src/keel/typeconv.cpp @@ -87,7 +87,7 @@ ox::Error TileSheetToCompactTileSheetConverter::convert( CompactTileSheet &dst) const noexcept { dst.bpp = src.bpp; dst.defaultPalette = std::move(src.defaultPalette); - dst.pixels = src.pixels(); + dst.pixels = pixels(src); return {}; } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp index 8a31bfb1..fdaa7775 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp @@ -10,7 +10,7 @@ AddSubSheetCommand::AddSubSheetCommand( TileSheet &img, TileSheet::SubSheetIdx parentIdx) noexcept: m_img(img), m_parentIdx(std::move(parentIdx)) { - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); if (!parent.subsheets.empty()) { auto idx = m_parentIdx; idx.emplace_back(parent.subsheets.size()); @@ -25,7 +25,7 @@ AddSubSheetCommand::AddSubSheetCommand( } void AddSubSheetCommand::redo() noexcept { - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); if (m_addedSheets.size() < 2) { auto i = parent.subsheets.size(); parent.subsheets.emplace_back(m_img.idIt++, ox::sfmt("Subsheet {}", i), 1, 1, m_img.bpp); @@ -38,7 +38,7 @@ void AddSubSheetCommand::redo() noexcept { } void AddSubSheetCommand::undo() noexcept { - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); if (parent.subsheets.size() == 2) { auto s = parent.subsheets[0]; parent.rows = s.rows; @@ -47,7 +47,7 @@ void AddSubSheetCommand::undo() noexcept { parent.subsheets.clear(); } else { for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) { - oxLogError(m_img.rmSubSheet(*idx)); + oxLogError(rmSubSheet(m_img, *idx)); } } } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.cpp index c011c633..cee911bd 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.cpp @@ -31,27 +31,27 @@ CutPasteCommand::CutPasteCommand( m_commandId(commandId), m_img(img), m_subSheetIdx(std::move(subSheetIdx)) { - const auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + const auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto &p : cb.pixels()) { const auto dstPt = p.pt + dstStart; if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) { - const auto idx = subsheet.idx(dstPt); - m_changes.emplace_back(static_cast(idx), p.colorIdx, subsheet.getPixel(m_img.bpp, idx)); + const auto idx = core::idx(subsheet, dstPt); + m_changes.emplace_back(static_cast(idx), p.colorIdx, getPixel(subsheet, m_img.bpp, idx)); } } } void CutPasteCommand::redo() noexcept { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto &c : m_changes) { - subsheet.setPixel(m_img.bpp, c.idx, static_cast(c.newPalIdx)); + setPixel(subsheet, m_img.bpp, c.idx, static_cast(c.newPalIdx)); } } void CutPasteCommand::undo() noexcept { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto &c : m_changes) { - subsheet.setPixel(m_img.bpp, c.idx, static_cast(c.oldPalIdx)); + setPixel(subsheet, m_img.bpp, c.idx, static_cast(c.oldPalIdx)); } } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/deletetilescommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/deletetilescommand.cpp index c6787096..57af0439 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/deletetilescommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/deletetilescommand.cpp @@ -19,7 +19,7 @@ core::DeleteTilesCommand::DeleteTilesCommand( m_deletedPixels.resize(m_deleteSz); // copy pixels to be erased { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; auto dst = m_deletedPixels.data(); auto src = p.data() + m_deletePos; @@ -29,7 +29,7 @@ core::DeleteTilesCommand::DeleteTilesCommand( } void core::DeleteTilesCommand::redo() noexcept { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; auto srcPos = m_deletePos + m_deleteSz; const auto src = p.data() + srcPos; @@ -40,7 +40,7 @@ void core::DeleteTilesCommand::redo() noexcept { } void DeleteTilesCommand::undo() noexcept { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; const auto src = p.data() + m_deletePos; const auto dst1 = p.data() + m_deletePos + m_deleteSz; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/drawcommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/drawcommand.cpp index 99e9964f..ea155eaf 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/drawcommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/drawcommand.cpp @@ -14,8 +14,8 @@ DrawCommand::DrawCommand( m_img(img), m_subSheetIdx(std::move(subSheetIdx)), m_palIdx(palIdx) { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); - m_changes.emplace_back(static_cast(idx), subsheet.getPixel(m_img.bpp, idx)); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); + m_changes.emplace_back(static_cast(idx), getPixel(subsheet, m_img.bpp, idx)); } DrawCommand::DrawCommand( @@ -26,22 +26,22 @@ DrawCommand::DrawCommand( m_img(img), m_subSheetIdx(std::move(subSheetIdx)), m_palIdx(palIdx) { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto idx : idxList) { - m_changes.emplace_back(static_cast(idx), subsheet.getPixel(m_img.bpp, idx)); + m_changes.emplace_back(static_cast(idx), getPixel(subsheet, m_img.bpp, idx)); } } bool DrawCommand::append(std::size_t idx) noexcept { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); - if (m_changes.back().value->idx != idx && subsheet.getPixel(m_img.bpp, idx) != m_palIdx) { + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); + if (m_changes.back().value->idx != idx && getPixel(subsheet, m_img.bpp, idx) != m_palIdx) { // duplicate entries are bad auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) { return c.idx == idx; }); if (existing == m_changes.cend()) { - m_changes.emplace_back(static_cast(idx), subsheet.getPixel(m_img.bpp, idx)); - subsheet.setPixel(m_img.bpp, idx, static_cast(m_palIdx)); + m_changes.emplace_back(static_cast(idx), getPixel(subsheet, m_img.bpp, idx)); + setPixel(subsheet, m_img.bpp, idx, static_cast(m_palIdx)); return true; } } @@ -57,16 +57,16 @@ bool DrawCommand::append(const ox::Vector &idxList) noexcept { } void DrawCommand::redo() noexcept { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto &c : m_changes) { - subsheet.setPixel(m_img.bpp, c.idx, static_cast(m_palIdx)); + setPixel(subsheet, m_img.bpp, c.idx, static_cast(m_palIdx)); } } void DrawCommand::undo() noexcept { - auto &subsheet = m_img.getSubSheet(m_subSheetIdx); + auto &subsheet = getSubSheet(m_img, m_subSheetIdx); for (const auto &c : m_changes) { - subsheet.setPixel(m_img.bpp, c.idx, static_cast(c.oldPalIdx)); + setPixel(subsheet, m_img.bpp, c.idx, static_cast(c.oldPalIdx)); } } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/inserttilescommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/inserttilescommand.cpp index 52b23807..ac0083ab 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/inserttilescommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/inserttilescommand.cpp @@ -19,7 +19,7 @@ core::InsertTilesCommand::InsertTilesCommand( m_deletedPixels.resize(m_insertCnt); // copy pixels to be erased { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; auto dst = m_deletedPixels.data(); auto src = p.data() + p.size() - m_insertCnt; @@ -29,7 +29,7 @@ core::InsertTilesCommand::InsertTilesCommand( } void InsertTilesCommand::redo() noexcept { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; auto dstPos = m_insertPos + m_insertCnt; const auto dst = p.data() + dstPos; @@ -39,7 +39,7 @@ void InsertTilesCommand::redo() noexcept { } void InsertTilesCommand::undo() noexcept { - auto &s = m_img.getSubSheet(m_idx); + auto &s = getSubSheet(m_img, m_idx); auto &p = s.pixels; const auto srcIdx = m_insertPos + m_insertCnt; const auto src = p.data() + srcIdx; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/rmsubsheetcommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/rmsubsheetcommand.cpp index ac7a9c38..afd3534a 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/rmsubsheetcommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/rmsubsheetcommand.cpp @@ -11,17 +11,17 @@ core::RmSubSheetCommand::RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetId m_idx(std::move(idx)), m_parentIdx(m_idx) { m_parentIdx.pop_back(); - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); m_sheet = parent.subsheets[*m_idx.back().value]; } void RmSubSheetCommand::redo() noexcept { - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); oxLogError(parent.subsheets.erase(*m_idx.back().value).error); } void RmSubSheetCommand::undo() noexcept { - auto &parent = m_img.getSubSheet(m_parentIdx); + auto &parent = getSubSheet(m_img, m_parentIdx); auto i = *m_idx.back().value; parent.subsheets.insert(i, m_sheet); } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/updatesubsheetcommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/updatesubsheetcommand.cpp index 5c16579f..93e2c74b 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/updatesubsheetcommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/updatesubsheetcommand.cpp @@ -14,22 +14,22 @@ core::UpdateSubSheetCommand::UpdateSubSheetCommand( int rows) noexcept: m_img(img), m_idx(std::move(idx)), - m_sheet(m_img.getSubSheet(m_idx)), + m_sheet(getSubSheet(m_img, m_idx)), m_newName(std::move(name)), m_newCols(cols), m_newRows(rows) { } void UpdateSubSheetCommand::redo() noexcept { - auto &sheet = m_img.getSubSheet(m_idx); + auto &sheet = getSubSheet(m_img, m_idx); sheet.name = m_newName; sheet.columns = m_newCols; sheet.rows = m_newRows; - oxLogError(sheet.setPixelCount(m_img.bpp, static_cast(PixelsPerTile * m_newCols * m_newRows))); + oxLogError(setPixelCount(sheet, m_img.bpp, static_cast(PixelsPerTile * m_newCols * m_newRows))); } void UpdateSubSheetCommand::undo() noexcept { - auto &sheet = m_img.getSubSheet(m_idx); + auto &sheet = getSubSheet(m_img, m_idx); sheet = m_sheet; } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp index 414ef3aa..998c25e9 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp @@ -47,8 +47,8 @@ void TileSheetEditorModel::cut() { for (int y = m_selectionBounds.y; y <= m_selectionBounds.y2(); ++y) { for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) { auto pt = ox::Point(x, y); - const auto idx = s->idx(pt); - const auto c = s->getPixel(m_img.bpp, idx); + const auto idx = core::idx(*s, pt); + const auto c = getPixel(*s, m_img.bpp, idx); pt.x -= m_selectionBounds.x; pt.y -= m_selectionBounds.y; cb->addPixel(pt, c); @@ -67,8 +67,8 @@ void TileSheetEditorModel::copy() { for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) { auto pt = ox::Point(x, y); const auto s = activeSubSheet(); - const auto idx = s->idx(pt); - const auto c = s->getPixel(m_img.bpp, idx); + const auto idx = core::idx(*s, pt); + const auto c = getPixel(*s, m_img.bpp, idx); pt.x -= m_selectionBounds.x; pt.y -= m_selectionBounds.y; cb->addPixel(pt, c); @@ -115,14 +115,14 @@ ox::Error TileSheetEditorModel::setPalette(ox::StringView path) noexcept { } void TileSheetEditorModel::drawCommand(ox::Point const&pt, std::size_t palIdx) noexcept { - const auto &activeSubSheet = m_img.getSubSheet(m_activeSubsSheetIdx); + const auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx); if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) { return; } - const auto idx = activeSubSheet.idx(pt); + const auto idx = core::idx(activeSubSheet, pt); if (m_ongoingDrawCommand) { m_updated = m_updated || m_ongoingDrawCommand->append(idx); - } else if (activeSubSheet.getPixel(m_img.bpp, idx) != palIdx) { + } else if (getPixel(activeSubSheet, m_img.bpp, idx) != palIdx) { pushCommand(ox::make(m_img, m_activeSubsSheetIdx, idx, static_cast(palIdx))); } } @@ -158,16 +158,16 @@ void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const&idx) n } void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept { - const auto &s = m_img.getSubSheet(m_activeSubsSheetIdx); + const auto &s = getSubSheet(m_img, m_activeSubsSheetIdx); // build idx list ox::Array updateMap = {}; - const auto oldColor = s.getPixel(m_img.bpp, pt); + const auto oldColor = getPixel(s, m_img.bpp, pt); if (pt.x >= s.columns * TileWidth || pt.y >= s.rows * TileHeight) { return; } getFillPixels(updateMap.data(), pt, oldColor); ox::Vector idxList; - auto i = s.idx(pt) / PixelsPerTile * PixelsPerTile; + auto i = core::idx(s, pt) / PixelsPerTile * PixelsPerTile; for (auto u : updateMap) { if (u) { idxList.emplace_back(i); @@ -177,7 +177,7 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept { // do updates to sheet if (m_ongoingDrawCommand) { m_updated = m_updated || m_ongoingDrawCommand->append(idxList); - } else if (s.getPixel(m_img.bpp, pt) != palIdx) { + } else if (getPixel(s, m_img.bpp, pt) != palIdx) { pushCommand(ox::make(m_img, m_activeSubsSheetIdx, idxList, palIdx)); } } @@ -221,7 +221,7 @@ ox::Error TileSheetEditorModel::markUpdatedCmdId(studio::UndoCommand const*cmd) paletteChanged.emit(); } auto tsCmd = dynamic_cast(cmd); - auto idx = m_img.validateSubSheetIdx(tsCmd->subsheetIdx()); + auto idx = validateSubSheetIdx(m_img, tsCmd->subsheetIdx()); if (idx != m_activeSubsSheetIdx) { setActiveSubsheet(idx); } @@ -267,16 +267,16 @@ void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int o const auto tile = tileIdx(pt); // mark pixels to update pixels[idx % PixelsPerTile] = true; - if (!pixels[leftIdx % PixelsPerTile] && tile == tileIdx(leftPt) && activeSubSheet.getPixel(m_img.bpp, leftIdx) == oldColor) { + if (!pixels[leftIdx % PixelsPerTile] && tile == tileIdx(leftPt) && getPixel(activeSubSheet, m_img.bpp, leftIdx) == oldColor) { getFillPixels(pixels, leftPt, oldColor); } - if (!pixels[rightIdx % PixelsPerTile] && tile == tileIdx(rightPt) && activeSubSheet.getPixel(m_img.bpp, rightIdx) == oldColor) { + if (!pixels[rightIdx % PixelsPerTile] && tile == tileIdx(rightPt) && getPixel(activeSubSheet, m_img.bpp, rightIdx) == oldColor) { getFillPixels(pixels, rightPt, oldColor); } - if (!pixels[topIdx % PixelsPerTile] && tile == tileIdx(topPt) && activeSubSheet.getPixel(m_img.bpp, topIdx) == oldColor) { + if (!pixels[topIdx % PixelsPerTile] && tile == tileIdx(topPt) && getPixel(activeSubSheet, m_img.bpp, topIdx) == oldColor) { getFillPixels(pixels, topPt, oldColor); } - if (!pixels[bottomIdx % PixelsPerTile] && tile == tileIdx(bottomPt) && activeSubSheet.getPixel(m_img.bpp, bottomIdx) == oldColor) { + if (!pixels[bottomIdx % PixelsPerTile] && tile == tileIdx(bottomPt) && getPixel(activeSubSheet, m_img.bpp, bottomIdx) == oldColor) { getFillPixels(pixels, bottomPt, oldColor); } } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp index 903398e5..cb4162c9 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp @@ -79,13 +79,13 @@ class TileSheetEditorModel: public ox::SignalHandler { [[nodiscard]] const TileSheet::SubSheet *activeSubSheet() const noexcept { - auto &activeSubSheet = m_img.getSubSheet(m_activeSubsSheetIdx); + auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx); return &activeSubSheet; } [[nodiscard]] TileSheet::SubSheet *activeSubSheet() noexcept { - auto &activeSubSheet = m_img.getSubSheet(m_activeSubsSheetIdx); + auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx); return &activeSubSheet; } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp index 358929a5..8bf018b3 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp @@ -102,7 +102,7 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { m_bufferSet.vertices.resize(pixels * VertexVboLength); m_bufferSet.elements.resize(pixels * VertexEboLength); // set pixels - subSheet->walkPixels(m_model.img().bpp, [&](std::size_t i, uint8_t p) { + walkPixels(*subSheet, m_model.img().bpp, [&](std::size_t i, uint8_t p) { auto color = pal->color(p); const auto pt = idxToPt(static_cast(i), subSheet->columns); const auto fx = static_cast(pt.x); diff --git a/src/nostalgia/modules/core/src/tilesheet.cpp b/src/nostalgia/modules/core/src/tilesheet.cpp index 41c792d4..91048e72 100644 --- a/src/nostalgia/modules/core/src/tilesheet.cpp +++ b/src/nostalgia/modules/core/src/tilesheet.cpp @@ -10,146 +10,47 @@ namespace nostalgia::core { -TileSheetV3::SubSheet::SubSheet( - SubSheetId pId, - ox::CRStringView pName, - int pColumns, - int pRows, - int bpp) noexcept: - id(pId), - name(pName), - columns(pColumns), - rows(pRows), - pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { +std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { + return ptToIdx(pt, ss.columns); } -TileSheet::SubSheet::SubSheet(SubSheet &&other) noexcept: - id (other.id), - name (std::move(other.name)), - columns (other.columns), - rows (other.rows), - subsheets(std::move(other.subsheets)), - pixels (std::move(other.pixels)) { - other.name = ""; - other.columns = {}; - other.rows = {}; -} - -TileSheet::SubSheet::SubSheet( - SubSheetId pId, - ox::CRStringView pName, - int pColumns, - int pRows, - int bpp) noexcept: - id(pId), - name(pName), - columns(pColumns), - rows(pRows), - pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { -} - -TileSheet::SubSheet::SubSheet( - SubSheetId pId, - ox::CRStringView pName, - int pColumns, - int pRows, - ox::Vector pPixels) noexcept: - id(pId), - name(pName), - columns(pColumns), - rows(pRows), - pixels(std::move(pPixels)) { -} - -TileSheet::SubSheet &TileSheet::SubSheet::operator=(TileSheet::SubSheet &&other) noexcept { - name = std::move(other.name); - columns = other.columns; - rows = other.rows; - subsheets = std::move(other.subsheets); - pixels = std::move(other.pixels); - return *this; -} - -std::size_t TileSheet::SubSheet::idx(ox::Point const&pt) const noexcept { - return ptToIdx(pt, columns); -} - -void TileSheet::SubSheet::readPixelsTo(ox::Vector &pPixels, int8_t pBpp) const noexcept { - if (!subsheets.empty()) { - for (auto &s: subsheets) { - s.readPixelsTo(pPixels); - } - } else { - if (pBpp == 4) { - for (auto p: this->pixels) { - pPixels.emplace_back(static_cast(p & 0b1111)); - pPixels.emplace_back(static_cast(p >> 4)); - } - } else { - for (auto p: this->pixels) { - pPixels.emplace_back(p); - } - } - } -} - -void TileSheet::SubSheet::readPixelsTo(ox::Vector &pPixels) const noexcept { - if (!subsheets.empty()) { - for (auto &s: subsheets) { - s.readPixelsTo(pPixels); - } - } else { - for (auto p : this->pixels) { - pPixels.emplace_back(p); - } - } -} - -std::size_t TileSheet::SubSheet::unusedPixels() const noexcept { - std::size_t childrenSize = 0; - for (auto &c : subsheets) { - childrenSize += c.size(); - } - return size() - childrenSize; -} - -uint8_t TileSheet::SubSheet::getPixel4Bpp(std::size_t idx) const noexcept { +uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept { if (idx & 1) { - return this->pixels[idx / 2] >> 4; + return ss.pixels[idx / 2] >> 4; } else { - return this->pixels[idx / 2] & 0b0000'1111; + return ss.pixels[idx / 2] & 0b0000'1111; } } -uint8_t TileSheet::SubSheet::getPixel8Bpp(std::size_t idx) const noexcept { - return this->pixels[idx]; +uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept { + return ss.pixels[idx]; } -uint8_t TileSheet::SubSheet::getPixel(int8_t pBpp, std::size_t idx) const noexcept { +uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, std::size_t idx) noexcept { if (pBpp == 4) { - return getPixel4Bpp(idx); + return getPixel4Bpp(ss, idx); } else { - return getPixel8Bpp(idx); + return getPixel8Bpp(ss, idx); } } -uint8_t TileSheet::SubSheet::getPixel4Bpp(ox::Point const&pt) const noexcept { - const auto idx = ptToIdx(pt, columns); - return getPixel4Bpp(idx); +uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { + const auto idx = ptToIdx(pt, ss.columns); + return getPixel4Bpp(ss, idx); } -uint8_t TileSheet::SubSheet::getPixel8Bpp(ox::Point const&pt) const noexcept { - const auto idx = ptToIdx(pt, columns); - return getPixel8Bpp(idx); +uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { + const auto idx = ptToIdx(pt, ss.columns); + return getPixel8Bpp(ss, idx); } -uint8_t TileSheet::SubSheet::getPixel(int8_t pBpp, ox::Point const&pt) const noexcept { - const auto idx = ptToIdx(pt, columns); - return getPixel(pBpp, idx); +uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt) noexcept { + const auto idx = ptToIdx(pt, ss.columns); + return getPixel(ss, pBpp, idx); } -void TileSheet::SubSheet::setPixel(int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept { - auto &pixel = this->pixels[static_cast(idx / 2)]; +void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept { + auto &pixel = ss.pixels[static_cast(idx / 2)]; if (pBpp == 4) { if (idx & 1) { pixel = static_cast((pixel & 0b0000'1111) | (palIdx << 4)); @@ -161,72 +62,35 @@ void TileSheet::SubSheet::setPixel(int8_t pBpp, uint64_t idx, uint8_t palIdx) no } } -void TileSheet::SubSheet::setPixel(int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept { - const auto idx = ptToIdx(pt, columns); - setPixel(pBpp, idx, palIdx); +void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept { + const auto idx = ptToIdx(pt, ss.columns); + setPixel(ss, pBpp, idx, palIdx); } -ox::Error TileSheet::SubSheet::setPixelCount(int8_t pBpp, std::size_t cnt) noexcept { +ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept { switch (pBpp) { case 4: - pixels.resize(cnt / 2); + ss.pixels.resize(cnt / 2); return OxError(0); case 8: - pixels.resize(cnt); + ss.pixels.resize(cnt); return OxError(0); default: return OxError(1, "Invalid pBpp used for TileSheet::SubSheet::setPixelCount"); } } -unsigned TileSheet::SubSheet::pixelCnt(int8_t pBpp) const noexcept { - const auto pixelsSize = static_cast(pixels.size()); +unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept { + const auto pixelsSize = static_cast(ss.pixels.size()); return pBpp == 4 ? pixelsSize * 2 : pixelsSize; } -ox::Result TileSheet::SubSheet::getTileOffset( - ox::SpanView const&pNamePath, - int8_t pBpp, - std::size_t pIt, - unsigned pCurrentTotal) const noexcept { - // pIt == pNamePath.size() - 1 && - if (name != pNamePath[pIt]) { - return OxError(2, "Wrong branch"); +ox::Result getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept { + if (ss.id == pId) { + return ox::StringView(ss.name); } - if (pIt == pNamePath.size() - 1) { - return pCurrentTotal; - } - for (auto &sub : subsheets) { - auto [offset, err] = sub.getTileOffset( - pNamePath, pBpp, pIt + 1, pCurrentTotal); - if (!err) { - return offset; - } - pCurrentTotal += sub.pixelCnt(pBpp) / PixelsPerTile; - } - return OxError(1, "SubSheet not found"); -} - -ox::Result TileSheet::SubSheet::getIdFor( - ox::SpanView const&pNamePath, - std::size_t pIt) const noexcept { - for (auto &sub : subsheets) { - if (sub.name == pNamePath[pIt]) { - if (pIt == pNamePath.size()) { - return id; - } - return getIdFor(pNamePath, pIt + 1); - } - } - return OxError(1, "SubSheet not found"); -} - -ox::Result TileSheet::SubSheet::getNameFor(SubSheetId pId) const noexcept { - if (id == pId) { - return ox::StringView(name); - } - for (const auto &sub : subsheets) { - const auto [name, err] = sub.getNameFor(pId); + for (const auto &sub : ss.subsheets) { + const auto [name, err] = getNameFor(sub, pId); if (!err) { return name; } @@ -235,28 +99,10 @@ ox::Result TileSheet::SubSheet::getNameFor(SubSheetId pId) const } -TileSheet &TileSheet::operator=(TileSheet const&other) noexcept { - if (this != &other) { - bpp = other.bpp; - idIt = other.idIt; - defaultPalette = other.defaultPalette; - subsheet = other.subsheet; - } - return *this; -} - -TileSheet &TileSheet::operator=(TileSheet &&other) noexcept { - bpp = other.bpp; - idIt = other.idIt; - defaultPalette = std::move(other.defaultPalette); - subsheet = std::move(other.subsheet); - return *this; -} - -TileSheet::SubSheetIdx TileSheet::validateSubSheetIdx( - SubSheetIdx const&pIdx, +TileSheet::SubSheetIdx validateSubSheetIdx( + TileSheet::SubSheetIdx const&pIdx, std::size_t pIdxIt, - SubSheet const&pSubsheet) noexcept { + TileSheet::SubSheet const&pSubsheet) noexcept { if (pIdxIt == pIdx.size()) { return pIdx; } @@ -273,14 +119,14 @@ TileSheet::SubSheetIdx TileSheet::validateSubSheetIdx( return validateSubSheetIdx(pIdx, pIdxIt + 1, pSubsheet.subsheets[pIdx[pIdxIt]]); } -TileSheet::SubSheetIdx TileSheet::validateSubSheetIdx(SubSheetIdx const&idx) noexcept { - return validateSubSheetIdx(idx, 0, subsheet); +TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept { + return validateSubSheetIdx(idx, 0, ts.subsheet); } -const TileSheet::SubSheet &TileSheet::getSubSheet( +const TileSheet::SubSheet &getSubSheet( TileSheet::SubSheetIdx const&idx, std::size_t idxIt, - SubSheet const&pSubsheet) noexcept { + TileSheet::SubSheet const&pSubsheet) noexcept { if (idxIt == idx.size()) { return pSubsheet; } @@ -291,7 +137,7 @@ const TileSheet::SubSheet &TileSheet::getSubSheet( return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[currentIdx]); } -TileSheet::SubSheet &TileSheet::getSubSheet( +TileSheet::SubSheet &getSubSheet( TileSheet::SubSheetIdx const&idx, std::size_t idxIt, TileSheet::SubSheet &pSubsheet) noexcept { @@ -301,72 +147,133 @@ TileSheet::SubSheet &TileSheet::getSubSheet( return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]); } -const TileSheet::SubSheet &TileSheet::getSubSheet(TileSheet::SubSheetIdx const&idx) const noexcept { - return getSubSheet(idx, 0, subsheet); +TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept { + return core::getSubSheet(idx, 0, ts.subsheet); } -TileSheet::SubSheet &TileSheet::getSubSheet(TileSheet::SubSheetIdx const&idx) noexcept { - return getSubSheet(idx, 0, subsheet); +TileSheet::SubSheet &getSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { + return core::getSubSheet(idx, 0, ts.subsheet); } -ox::Error TileSheet::addSubSheet(TileSheet::SubSheetIdx const&idx) noexcept { - auto &parent = getSubSheet(idx); +ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { + auto &parent = getSubSheet(ts, idx); if (parent.subsheets.size() < 2) { - parent.subsheets.emplace_back(++idIt, ox::sfmt("Subsheet {}", parent.subsheets.size()), 1, 1, bpp); + parent.subsheets.emplace_back(++ts.idIt, ox::sfmt("Subsheet {}", parent.subsheets.size()), 1, 1, ts.bpp); } else { - parent.subsheets.emplace_back(++idIt, "Subsheet 0", parent.columns, parent.rows, bpp); - parent.subsheets.emplace_back(++idIt, "Subsheet 1", 1, 1, bpp); + parent.subsheets.emplace_back(++ts.idIt, "Subsheet 0", parent.columns, parent.rows, ts.bpp); + parent.subsheets.emplace_back(++ts.idIt, "Subsheet 1", 1, 1, ts.bpp); } return OxError(0); } -ox::Error TileSheet::rmSubSheet( - SubSheetIdx const&idx, +ox::Error rmSubSheet( + TileSheet &ts, + TileSheet::SubSheetIdx const&idx, std::size_t idxIt, - SubSheet &pSubsheet) noexcept { + TileSheet::SubSheet &pSubsheet) noexcept { if (idxIt == idx.size() - 1) { return pSubsheet.subsheets.erase(idx[idxIt]).error; } - return rmSubSheet(idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]); + return rmSubSheet(ts, idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]); } -ox::Error TileSheet::rmSubSheet(TileSheet::SubSheetIdx const&idx) noexcept { - return rmSubSheet(idx, 0, subsheet); +ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { + return rmSubSheet(ts, idx, 0, ts.subsheet); } -uint8_t TileSheet::getPixel4Bpp( +uint8_t getPixel4Bpp( + TileSheet const&ts, ox::Point const&pt, - TileSheet::SubSheetIdx const&subsheetIdx) const noexcept { - oxAssert(bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); - auto &s = this->getSubSheet(subsheetIdx); + TileSheet::SubSheetIdx const&subsheetIdx) noexcept { + oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); + auto &s = getSubSheet(ts, subsheetIdx); const auto idx = ptToIdx(pt, s.columns); - return s.getPixel4Bpp(idx); + return getPixel4Bpp(s, idx); } -uint8_t TileSheet::getPixel8Bpp( +uint8_t getPixel8Bpp( + TileSheet const&ts, ox::Point const&pt, - TileSheet::SubSheetIdx const&subsheetIdx) const noexcept { - oxAssert(bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); - auto &s = this->getSubSheet(subsheetIdx); + TileSheet::SubSheetIdx const&subsheetIdx) noexcept { + oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); + auto &s = getSubSheet(ts, subsheetIdx); const auto idx = ptToIdx(pt, s.columns); - return s.getPixel8Bpp(idx); + return getPixel8Bpp(s, idx); } -ox::Result TileSheet::getIdFor(ox::CRStringView path) const noexcept { - return subsheet.getIdFor(ox::split<8>(path, '.')); +static ox::Result getIdFor( + TileSheet::SubSheet const&ss, + ox::SpanView const&pNamePath, + std::size_t pIt = 0) noexcept { + for (auto &sub : ss.subsheets) { + if (sub.name == pNamePath[pIt]) { + if (pIt == pNamePath.size()) { + return ss.id; + } + return getIdFor(ss, pNamePath, pIt + 1); + } + } + return OxError(1, "SubSheet not found"); } -ox::Result TileSheet::getTileOffset(ox::CRStringView pNamePath) const noexcept { - return subsheet.getTileOffset(ox::split<8>(pNamePath, '.'), bpp); +ox::Result getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept { + return getIdFor(ts.subsheet, ox::split<8>(path, '.')); } -ox::Result TileSheet::getNameFor(SubSheetId pId) const noexcept { - return subsheet.getNameFor(pId); +/** + * Gets the offset in tiles of the desired subsheet. + */ +static ox::Result getTileOffset( + TileSheet::SubSheet const&ss, + ox::SpanView const&pNamePath, + int8_t pBpp, + std::size_t pIt = 0, + unsigned pCurrentTotal = 0) noexcept { + // pIt == pNamePath.size() - 1 && + if (ss.name != pNamePath[pIt]) { + return OxError(2, "Wrong branch"); + } + if (pIt == pNamePath.size() - 1) { + return pCurrentTotal; + } + for (auto &sub : ss.subsheets) { + auto [offset, err] = getTileOffset( + sub, pNamePath, pBpp, pIt + 1, pCurrentTotal); + if (!err) { + return offset; + } + pCurrentTotal += pixelCnt(sub, pBpp) / PixelsPerTile; + } + return OxError(1, "SubSheet not found"); } -ox::Vector TileSheet::pixels() const noexcept { +ox::Result getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept { + return core::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.'), ts.bpp); +} + +ox::Result getNameFor(TileSheet &ts, SubSheetId pId) noexcept { + return core::getNameFor(ts.subsheet, pId); +} + +ox::Result getNameFor(TileSheet const&ts, SubSheetId pId) noexcept { + return core::getNameFor(ts.subsheet, pId); +} + +static void readPixelsTo(TileSheet::SubSheet &ss, ox::Vector &pPixels) noexcept { + if (!ss.subsheets.empty()) { + for (auto &s: ss.subsheets) { + readPixelsTo(s, pPixels); + } + } else { + for (auto p : ss.pixels) { + pPixels.emplace_back(p); + } + } +} + +ox::Vector pixels(TileSheet &ts) noexcept { ox::Vector out; - subsheet.readPixelsTo(out); + readPixelsTo(ts.subsheet, out); return out; } diff --git a/src/nostalgia/modules/scene/include/nostalgia/scene/scenestatic.hpp b/src/nostalgia/modules/scene/include/nostalgia/scene/scenestatic.hpp index 94c9db5f..5f09ac41 100644 --- a/src/nostalgia/modules/scene/include/nostalgia/scene/scenestatic.hpp +++ b/src/nostalgia/modules/scene/include/nostalgia/scene/scenestatic.hpp @@ -42,7 +42,7 @@ struct TileDoc { if (subsheetId > -1) { return subsheetId; } - return ts.getIdFor(subsheetPath); + return getIdFor(ts, subsheetPath); } [[nodiscard]] @@ -50,7 +50,7 @@ struct TileDoc { core::TileSheet const&ts) const noexcept { // prefer the already present path if (!subsheetPath.len()) { - return ts.getNameFor(subsheetId); + return core::getNameFor(ts, subsheetId); } return ox::StringView(subsheetPath); } diff --git a/src/nostalgia/modules/scene/src/keel/typeconv.cpp b/src/nostalgia/modules/scene/src/keel/typeconv.cpp index b502b2ff..0eae97c6 100644 --- a/src/nostalgia/modules/scene/src/keel/typeconv.cpp +++ b/src/nostalgia/modules/scene/src/keel/typeconv.cpp @@ -54,7 +54,7 @@ ox::Error SceneDocToSceneStaticConverter::convert( auto dstTile = dstLayer.tile(tileIdx); dstTile.tileType = srcTile.type; oxRequire(path, srcTile.getSubsheetPath(*ts)); - oxRequire(mapIdx, ts->getTileOffset(path)); + oxRequire(mapIdx, getTileOffset(*ts, path)); dstTile.tileMapIdx = static_cast(mapIdx); setLayerAttachments(layerIdx, srcTile, dstTile); ++tileIdx;