[nostalgia/core] Move most TileSheet member functions out of class
All checks were successful
Build / build (push) Successful in 2m4s

This commit is contained in:
Gary Talent 2023-12-27 23:10:38 -06:00
parent bf12b15fe6
commit 4b9758f478
15 changed files with 339 additions and 462 deletions

View File

@ -74,12 +74,19 @@ struct TileSheetV3 {
ox::Vector<SubSheet> subsheets; ox::Vector<SubSheet> subsheets;
ox::Vector<uint8_t> pixels; ox::Vector<uint8_t> pixels;
constexpr SubSheet() noexcept = default; constexpr SubSheet() noexcept = default;
SubSheet( inline SubSheet(
SubSheetId pId, SubSheetId pId,
ox::CRStringView pName, ox::CRStringView pName,
int pColumns, int pColumns,
int pRows, int pRows,
int bpp) noexcept; int bpp) noexcept:
id(pId),
name(pName),
columns(pColumns),
rows(pRows),
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
}
}; };
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet"; static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
@ -105,117 +112,36 @@ struct TileSheet {
ox::Vector<uint8_t> pixels; ox::Vector<uint8_t> pixels;
constexpr SubSheet() noexcept = default; constexpr SubSheet() noexcept = default;
constexpr SubSheet(SubSheet const&other) noexcept = default; inline SubSheet(
SubSheet(SubSheet &&other) noexcept;
SubSheet(
SubSheetId pId, SubSheetId pId,
ox::CRStringView pName, ox::CRStringView pName,
int pColumns, int pColumns,
int pRows, int pRows,
int bpp) noexcept; int bpp) noexcept:
SubSheet( id(pId),
name(pName),
columns(pColumns),
rows(pRows),
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
}
inline SubSheet(
SubSheetId pId, SubSheetId pId,
ox::CRStringView pName, ox::CRStringView pName,
int pColumns, int pColumns,
int pRows, int pRows,
ox::Vector<uint8_t> pPixels) noexcept; ox::Vector<uint8_t> pPixels) noexcept:
id(pId),
constexpr SubSheet &operator=(const SubSheet &other) noexcept = default; name(pName),
columns(pColumns),
SubSheet &operator=(SubSheet &&other) noexcept; rows(pRows),
pixels(std::move(pPixels)) {
[[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<uint8_t> &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<uint8_t> &pPixels) const noexcept;
[[nodiscard]] [[nodiscard]]
constexpr std::size_t size() const noexcept { constexpr std::size_t size() const noexcept {
return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows); return static_cast<std::size_t>(columns) * static_cast<std::size_t>(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<std::size_t>(static_cast<std::size_t>(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<uint8_t>(pixels[i] & 0xF);
const auto colorIdx2 = static_cast<uint8_t>(pixels[i] >> 4);
callback(i * 2 + 0, colorIdx1);
callback(i * 2 + 1, colorIdx2);
}
} else {
const auto pixelCnt = ox::min<std::size_t>(
static_cast<std::size_t>(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<unsigned> getTileOffset(
ox::SpanView<ox::StringView> const&pNamePath,
int8_t pBpp,
std::size_t pIt = 0,
unsigned pCurrentTotal = 0) const noexcept;
ox::Result<SubSheetId> getIdFor(
ox::SpanView<ox::StringView> const&pNamePath,
std::size_t pIt = 0) const noexcept;
ox::Result<ox::StringView> getNameFor(SubSheetId pId) const noexcept;
}; };
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet"; static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
@ -226,84 +152,128 @@ struct TileSheet {
SubSheet subsheet{0, "Root", 1, 1, bpp}; SubSheet subsheet{0, "Root", 1, 1, bpp};
constexpr TileSheet() noexcept = default; 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<SubSheetId> getIdFor(ox::CRStringView path) const noexcept;
ox::Result<unsigned> getTileOffset(ox::CRStringView pNamePath) const noexcept;
ox::Result<ox::StringView> getNameFor(SubSheetId pId) const noexcept;
[[nodiscard]]
ox::Vector<uint8_t> 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<std::size_t>(
static_cast<std::size_t>(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<uint8_t>(ss.pixels[i] & 0xF);
const auto colorIdx2 = static_cast<uint8_t>(ss.pixels[i] >> 4);
callback(i * 2 + 0, colorIdx1);
callback(i * 2 + 1, colorIdx2);
}
} else {
const auto pixelCnt = ox::min<std::size_t>(
static_cast<std::size_t>(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<SubSheetId> getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept;
ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept;
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept;
ox::Result<ox::StringView> getNameFor(TileSheet const&ss, SubSheetId pId) noexcept;
[[nodiscard]]
ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept;
using TileSheetV4 = TileSheet; using TileSheetV4 = TileSheet;
struct CompactTileSheet { struct CompactTileSheet {

View File

@ -87,7 +87,7 @@ ox::Error TileSheetToCompactTileSheetConverter::convert(
CompactTileSheet &dst) const noexcept { CompactTileSheet &dst) const noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.defaultPalette = std::move(src.defaultPalette); dst.defaultPalette = std::move(src.defaultPalette);
dst.pixels = src.pixels(); dst.pixels = pixels(src);
return {}; return {};
} }

View File

@ -10,7 +10,7 @@ AddSubSheetCommand::AddSubSheetCommand(
TileSheet &img, TileSheet &img,
TileSheet::SubSheetIdx parentIdx) noexcept: TileSheet::SubSheetIdx parentIdx) noexcept:
m_img(img), m_parentIdx(std::move(parentIdx)) { 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()) { if (!parent.subsheets.empty()) {
auto idx = m_parentIdx; auto idx = m_parentIdx;
idx.emplace_back(parent.subsheets.size()); idx.emplace_back(parent.subsheets.size());
@ -25,7 +25,7 @@ AddSubSheetCommand::AddSubSheetCommand(
} }
void AddSubSheetCommand::redo() noexcept { void AddSubSheetCommand::redo() noexcept {
auto &parent = m_img.getSubSheet(m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
if (m_addedSheets.size() < 2) { if (m_addedSheets.size() < 2) {
auto i = parent.subsheets.size(); auto i = parent.subsheets.size();
parent.subsheets.emplace_back(m_img.idIt++, ox::sfmt("Subsheet {}", i), 1, 1, m_img.bpp); 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 { void AddSubSheetCommand::undo() noexcept {
auto &parent = m_img.getSubSheet(m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
if (parent.subsheets.size() == 2) { if (parent.subsheets.size() == 2) {
auto s = parent.subsheets[0]; auto s = parent.subsheets[0];
parent.rows = s.rows; parent.rows = s.rows;
@ -47,7 +47,7 @@ void AddSubSheetCommand::undo() noexcept {
parent.subsheets.clear(); parent.subsheets.clear();
} else { } else {
for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) { for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) {
oxLogError(m_img.rmSubSheet(*idx)); oxLogError(rmSubSheet(m_img, *idx));
} }
} }
} }

View File

@ -31,27 +31,27 @@ CutPasteCommand::CutPasteCommand(
m_commandId(commandId), m_commandId(commandId),
m_img(img), m_img(img),
m_subSheetIdx(std::move(subSheetIdx)) { 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()) { for (const auto &p : cb.pixels()) {
const auto dstPt = p.pt + dstStart; const auto dstPt = p.pt + dstStart;
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) { if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
const auto idx = subsheet.idx(dstPt); const auto idx = core::idx(subsheet, dstPt);
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, subsheet.getPixel(m_img.bpp, idx)); m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, getPixel(subsheet, m_img.bpp, idx));
} }
} }
} }
void CutPasteCommand::redo() noexcept { void CutPasteCommand::redo() noexcept {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(c.newPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.newPalIdx));
} }
} }
void CutPasteCommand::undo() noexcept { void CutPasteCommand::undo() noexcept {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
} }
} }

View File

@ -19,7 +19,7 @@ core::DeleteTilesCommand::DeleteTilesCommand(
m_deletedPixels.resize(m_deleteSz); m_deletedPixels.resize(m_deleteSz);
// copy pixels to be erased // copy pixels to be erased
{ {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto dst = m_deletedPixels.data(); auto dst = m_deletedPixels.data();
auto src = p.data() + m_deletePos; auto src = p.data() + m_deletePos;
@ -29,7 +29,7 @@ core::DeleteTilesCommand::DeleteTilesCommand(
} }
void core::DeleteTilesCommand::redo() noexcept { void core::DeleteTilesCommand::redo() noexcept {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto srcPos = m_deletePos + m_deleteSz; auto srcPos = m_deletePos + m_deleteSz;
const auto src = p.data() + srcPos; const auto src = p.data() + srcPos;
@ -40,7 +40,7 @@ void core::DeleteTilesCommand::redo() noexcept {
} }
void DeleteTilesCommand::undo() noexcept { void DeleteTilesCommand::undo() noexcept {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
const auto src = p.data() + m_deletePos; const auto src = p.data() + m_deletePos;
const auto dst1 = p.data() + m_deletePos + m_deleteSz; const auto dst1 = p.data() + m_deletePos + m_deleteSz;

View File

@ -14,8 +14,8 @@ DrawCommand::DrawCommand(
m_img(img), m_img(img),
m_subSheetIdx(std::move(subSheetIdx)), m_subSheetIdx(std::move(subSheetIdx)),
m_palIdx(palIdx) { m_palIdx(palIdx) {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img.bpp, idx)); m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx));
} }
DrawCommand::DrawCommand( DrawCommand::DrawCommand(
@ -26,22 +26,22 @@ DrawCommand::DrawCommand(
m_img(img), m_img(img),
m_subSheetIdx(std::move(subSheetIdx)), m_subSheetIdx(std::move(subSheetIdx)),
m_palIdx(palIdx) { m_palIdx(palIdx) {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto idx : idxList) { for (const auto idx : idxList) {
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img.bpp, idx)); m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx));
} }
} }
bool DrawCommand::append(std::size_t idx) noexcept { bool DrawCommand::append(std::size_t idx) noexcept {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
if (m_changes.back().value->idx != idx && subsheet.getPixel(m_img.bpp, idx) != m_palIdx) { if (m_changes.back().value->idx != idx && getPixel(subsheet, m_img.bpp, idx) != m_palIdx) {
// duplicate entries are bad // duplicate entries are bad
auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) { auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) {
return c.idx == idx; return c.idx == idx;
}); });
if (existing == m_changes.cend()) { if (existing == m_changes.cend()) {
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img.bpp, idx)); m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx));
subsheet.setPixel(m_img.bpp, idx, static_cast<uint8_t>(m_palIdx)); setPixel(subsheet, m_img.bpp, idx, static_cast<uint8_t>(m_palIdx));
return true; return true;
} }
} }
@ -57,16 +57,16 @@ bool DrawCommand::append(const ox::Vector<std::size_t> &idxList) noexcept {
} }
void DrawCommand::redo() 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) { for (const auto &c : m_changes) {
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(m_palIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(m_palIdx));
} }
} }
void DrawCommand::undo() noexcept { void DrawCommand::undo() noexcept {
auto &subsheet = m_img.getSubSheet(m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
} }
} }

View File

@ -19,7 +19,7 @@ core::InsertTilesCommand::InsertTilesCommand(
m_deletedPixels.resize(m_insertCnt); m_deletedPixels.resize(m_insertCnt);
// copy pixels to be erased // copy pixels to be erased
{ {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto dst = m_deletedPixels.data(); auto dst = m_deletedPixels.data();
auto src = p.data() + p.size() - m_insertCnt; auto src = p.data() + p.size() - m_insertCnt;
@ -29,7 +29,7 @@ core::InsertTilesCommand::InsertTilesCommand(
} }
void InsertTilesCommand::redo() noexcept { void InsertTilesCommand::redo() noexcept {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto dstPos = m_insertPos + m_insertCnt; auto dstPos = m_insertPos + m_insertCnt;
const auto dst = p.data() + dstPos; const auto dst = p.data() + dstPos;
@ -39,7 +39,7 @@ void InsertTilesCommand::redo() noexcept {
} }
void InsertTilesCommand::undo() noexcept { void InsertTilesCommand::undo() noexcept {
auto &s = m_img.getSubSheet(m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
const auto srcIdx = m_insertPos + m_insertCnt; const auto srcIdx = m_insertPos + m_insertCnt;
const auto src = p.data() + srcIdx; const auto src = p.data() + srcIdx;

View File

@ -11,17 +11,17 @@ core::RmSubSheetCommand::RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetId
m_idx(std::move(idx)), m_idx(std::move(idx)),
m_parentIdx(m_idx) { m_parentIdx(m_idx) {
m_parentIdx.pop_back(); 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]; m_sheet = parent.subsheets[*m_idx.back().value];
} }
void RmSubSheetCommand::redo() noexcept { 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); oxLogError(parent.subsheets.erase(*m_idx.back().value).error);
} }
void RmSubSheetCommand::undo() noexcept { void RmSubSheetCommand::undo() noexcept {
auto &parent = m_img.getSubSheet(m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
auto i = *m_idx.back().value; auto i = *m_idx.back().value;
parent.subsheets.insert(i, m_sheet); parent.subsheets.insert(i, m_sheet);
} }

View File

@ -14,22 +14,22 @@ core::UpdateSubSheetCommand::UpdateSubSheetCommand(
int rows) noexcept: int rows) noexcept:
m_img(img), m_img(img),
m_idx(std::move(idx)), 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_newName(std::move(name)),
m_newCols(cols), m_newCols(cols),
m_newRows(rows) { m_newRows(rows) {
} }
void UpdateSubSheetCommand::redo() noexcept { void UpdateSubSheetCommand::redo() noexcept {
auto &sheet = m_img.getSubSheet(m_idx); auto &sheet = getSubSheet(m_img, m_idx);
sheet.name = m_newName; sheet.name = m_newName;
sheet.columns = m_newCols; sheet.columns = m_newCols;
sheet.rows = m_newRows; sheet.rows = m_newRows;
oxLogError(sheet.setPixelCount(m_img.bpp, static_cast<std::size_t>(PixelsPerTile * m_newCols * m_newRows))); oxLogError(setPixelCount(sheet, m_img.bpp, static_cast<std::size_t>(PixelsPerTile * m_newCols * m_newRows)));
} }
void UpdateSubSheetCommand::undo() noexcept { void UpdateSubSheetCommand::undo() noexcept {
auto &sheet = m_img.getSubSheet(m_idx); auto &sheet = getSubSheet(m_img, m_idx);
sheet = m_sheet; sheet = m_sheet;
} }

View File

@ -47,8 +47,8 @@ void TileSheetEditorModel::cut() {
for (int y = m_selectionBounds.y; y <= m_selectionBounds.y2(); ++y) { for (int y = m_selectionBounds.y; y <= m_selectionBounds.y2(); ++y) {
for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) { for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) {
auto pt = ox::Point(x, y); auto pt = ox::Point(x, y);
const auto idx = s->idx(pt); const auto idx = core::idx(*s, pt);
const auto c = s->getPixel(m_img.bpp, idx); const auto c = getPixel(*s, m_img.bpp, idx);
pt.x -= m_selectionBounds.x; pt.x -= m_selectionBounds.x;
pt.y -= m_selectionBounds.y; pt.y -= m_selectionBounds.y;
cb->addPixel(pt, c); cb->addPixel(pt, c);
@ -67,8 +67,8 @@ void TileSheetEditorModel::copy() {
for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) { for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) {
auto pt = ox::Point(x, y); auto pt = ox::Point(x, y);
const auto s = activeSubSheet(); const auto s = activeSubSheet();
const auto idx = s->idx(pt); const auto idx = core::idx(*s, pt);
const auto c = s->getPixel(m_img.bpp, idx); const auto c = getPixel(*s, m_img.bpp, idx);
pt.x -= m_selectionBounds.x; pt.x -= m_selectionBounds.x;
pt.y -= m_selectionBounds.y; pt.y -= m_selectionBounds.y;
cb->addPixel(pt, c); 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 { 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) { if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
return; return;
} }
const auto idx = activeSubSheet.idx(pt); const auto idx = core::idx(activeSubSheet, pt);
if (m_ongoingDrawCommand) { if (m_ongoingDrawCommand) {
m_updated = m_updated || m_ongoingDrawCommand->append(idx); 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<DrawCommand>(m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx))); pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
} }
} }
@ -158,16 +158,16 @@ void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const&idx) n
} }
void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept { 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 // build idx list
ox::Array<bool, PixelsPerTile> updateMap = {}; ox::Array<bool, PixelsPerTile> 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) { if (pt.x >= s.columns * TileWidth || pt.y >= s.rows * TileHeight) {
return; return;
} }
getFillPixels(updateMap.data(), pt, oldColor); getFillPixels(updateMap.data(), pt, oldColor);
ox::Vector<std::size_t> idxList; ox::Vector<std::size_t> idxList;
auto i = s.idx(pt) / PixelsPerTile * PixelsPerTile; auto i = core::idx(s, pt) / PixelsPerTile * PixelsPerTile;
for (auto u : updateMap) { for (auto u : updateMap) {
if (u) { if (u) {
idxList.emplace_back(i); idxList.emplace_back(i);
@ -177,7 +177,7 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept {
// do updates to sheet // do updates to sheet
if (m_ongoingDrawCommand) { if (m_ongoingDrawCommand) {
m_updated = m_updated || m_ongoingDrawCommand->append(idxList); 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<DrawCommand>(m_img, m_activeSubsSheetIdx, idxList, palIdx)); pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idxList, palIdx));
} }
} }
@ -221,7 +221,7 @@ ox::Error TileSheetEditorModel::markUpdatedCmdId(studio::UndoCommand const*cmd)
paletteChanged.emit(); paletteChanged.emit();
} }
auto tsCmd = dynamic_cast<const TileSheetCommand*>(cmd); auto tsCmd = dynamic_cast<const TileSheetCommand*>(cmd);
auto idx = m_img.validateSubSheetIdx(tsCmd->subsheetIdx()); auto idx = validateSubSheetIdx(m_img, tsCmd->subsheetIdx());
if (idx != m_activeSubsSheetIdx) { if (idx != m_activeSubsSheetIdx) {
setActiveSubsheet(idx); setActiveSubsheet(idx);
} }
@ -267,16 +267,16 @@ void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int o
const auto tile = tileIdx(pt); const auto tile = tileIdx(pt);
// mark pixels to update // mark pixels to update
pixels[idx % PixelsPerTile] = true; 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); 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); 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); 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); getFillPixels(pixels, bottomPt, oldColor);
} }
} }

View File

@ -79,13 +79,13 @@ class TileSheetEditorModel: public ox::SignalHandler {
[[nodiscard]] [[nodiscard]]
const TileSheet::SubSheet *activeSubSheet() const noexcept { const TileSheet::SubSheet *activeSubSheet() const noexcept {
auto &activeSubSheet = m_img.getSubSheet(m_activeSubsSheetIdx); auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
return &activeSubSheet; return &activeSubSheet;
} }
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheet *activeSubSheet() noexcept { TileSheet::SubSheet *activeSubSheet() noexcept {
auto &activeSubSheet = m_img.getSubSheet(m_activeSubsSheetIdx); auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
return &activeSubSheet; return &activeSubSheet;
} }

View File

@ -102,7 +102,7 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept {
m_bufferSet.vertices.resize(pixels * VertexVboLength); m_bufferSet.vertices.resize(pixels * VertexVboLength);
m_bufferSet.elements.resize(pixels * VertexEboLength); m_bufferSet.elements.resize(pixels * VertexEboLength);
// set pixels // 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); auto color = pal->color(p);
const auto pt = idxToPt(static_cast<int>(i), subSheet->columns); const auto pt = idxToPt(static_cast<int>(i), subSheet->columns);
const auto fx = static_cast<float>(pt.x); const auto fx = static_cast<float>(pt.x);

View File

@ -10,146 +10,47 @@
namespace nostalgia::core { namespace nostalgia::core {
TileSheetV3::SubSheet::SubSheet( std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept {
SubSheetId pId, return ptToIdx(pt, ss.columns);
ox::CRStringView pName,
int pColumns,
int pRows,
int bpp) noexcept:
id(pId),
name(pName),
columns(pColumns),
rows(pRows),
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
} }
TileSheet::SubSheet::SubSheet(SubSheet &&other) noexcept: uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) 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<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
}
TileSheet::SubSheet::SubSheet(
SubSheetId pId,
ox::CRStringView pName,
int pColumns,
int pRows,
ox::Vector<uint8_t> 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<uint8_t> &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<uint8_t>(p & 0b1111));
pPixels.emplace_back(static_cast<uint8_t>(p >> 4));
}
} else {
for (auto p: this->pixels) {
pPixels.emplace_back(p);
}
}
}
}
void TileSheet::SubSheet::readPixelsTo(ox::Vector<uint8_t> &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 {
if (idx & 1) { if (idx & 1) {
return this->pixels[idx / 2] >> 4; return ss.pixels[idx / 2] >> 4;
} else { } 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 { uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept {
return this->pixels[idx]; 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) { if (pBpp == 4) {
return getPixel4Bpp(idx); return getPixel4Bpp(ss, idx);
} else { } else {
return getPixel8Bpp(idx); return getPixel8Bpp(ss, idx);
} }
} }
uint8_t TileSheet::SubSheet::getPixel4Bpp(ox::Point const&pt) const noexcept { uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept {
const auto idx = ptToIdx(pt, columns); const auto idx = ptToIdx(pt, ss.columns);
return getPixel4Bpp(idx); return getPixel4Bpp(ss, idx);
} }
uint8_t TileSheet::SubSheet::getPixel8Bpp(ox::Point const&pt) const noexcept { uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept {
const auto idx = ptToIdx(pt, columns); const auto idx = ptToIdx(pt, ss.columns);
return getPixel8Bpp(idx); return getPixel8Bpp(ss, idx);
} }
uint8_t TileSheet::SubSheet::getPixel(int8_t pBpp, ox::Point const&pt) const noexcept { uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt) noexcept {
const auto idx = ptToIdx(pt, columns); const auto idx = ptToIdx(pt, ss.columns);
return getPixel(pBpp, idx); return getPixel(ss, pBpp, idx);
} }
void TileSheet::SubSheet::setPixel(int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept { void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept {
auto &pixel = this->pixels[static_cast<std::size_t>(idx / 2)]; auto &pixel = ss.pixels[static_cast<std::size_t>(idx / 2)];
if (pBpp == 4) { if (pBpp == 4) {
if (idx & 1) { if (idx & 1) {
pixel = static_cast<uint8_t>((pixel & 0b0000'1111) | (palIdx << 4)); pixel = static_cast<uint8_t>((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 { void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept {
const auto idx = ptToIdx(pt, columns); const auto idx = ptToIdx(pt, ss.columns);
setPixel(pBpp, idx, palIdx); 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) { switch (pBpp) {
case 4: case 4:
pixels.resize(cnt / 2); ss.pixels.resize(cnt / 2);
return OxError(0); return OxError(0);
case 8: case 8:
pixels.resize(cnt); ss.pixels.resize(cnt);
return OxError(0); return OxError(0);
default: default:
return OxError(1, "Invalid pBpp used for TileSheet::SubSheet::setPixelCount"); return OxError(1, "Invalid pBpp used for TileSheet::SubSheet::setPixelCount");
} }
} }
unsigned TileSheet::SubSheet::pixelCnt(int8_t pBpp) const noexcept { unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept {
const auto pixelsSize = static_cast<unsigned>(pixels.size()); const auto pixelsSize = static_cast<unsigned>(ss.pixels.size());
return pBpp == 4 ? pixelsSize * 2 : pixelsSize; return pBpp == 4 ? pixelsSize * 2 : pixelsSize;
} }
ox::Result<unsigned> TileSheet::SubSheet::getTileOffset( ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept {
ox::SpanView<ox::StringView> const&pNamePath, if (ss.id == pId) {
int8_t pBpp, return ox::StringView(ss.name);
std::size_t pIt,
unsigned pCurrentTotal) const noexcept {
// pIt == pNamePath.size() - 1 &&
if (name != pNamePath[pIt]) {
return OxError(2, "Wrong branch");
} }
if (pIt == pNamePath.size() - 1) { for (const auto &sub : ss.subsheets) {
return pCurrentTotal; const auto [name, err] = getNameFor(sub, pId);
}
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<SubSheetId> TileSheet::SubSheet::getIdFor(
ox::SpanView<ox::StringView> 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<ox::StringView> 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);
if (!err) { if (!err) {
return name; return name;
} }
@ -235,28 +99,10 @@ ox::Result<ox::StringView> TileSheet::SubSheet::getNameFor(SubSheetId pId) const
} }
TileSheet &TileSheet::operator=(TileSheet const&other) noexcept { TileSheet::SubSheetIdx validateSubSheetIdx(
if (this != &other) { TileSheet::SubSheetIdx const&pIdx,
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,
std::size_t pIdxIt, std::size_t pIdxIt,
SubSheet const&pSubsheet) noexcept { TileSheet::SubSheet const&pSubsheet) noexcept {
if (pIdxIt == pIdx.size()) { if (pIdxIt == pIdx.size()) {
return pIdx; return pIdx;
} }
@ -273,14 +119,14 @@ TileSheet::SubSheetIdx TileSheet::validateSubSheetIdx(
return validateSubSheetIdx(pIdx, pIdxIt + 1, pSubsheet.subsheets[pIdx[pIdxIt]]); return validateSubSheetIdx(pIdx, pIdxIt + 1, pSubsheet.subsheets[pIdx[pIdxIt]]);
} }
TileSheet::SubSheetIdx TileSheet::validateSubSheetIdx(SubSheetIdx const&idx) noexcept { TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept {
return validateSubSheetIdx(idx, 0, subsheet); return validateSubSheetIdx(idx, 0, ts.subsheet);
} }
const TileSheet::SubSheet &TileSheet::getSubSheet( const TileSheet::SubSheet &getSubSheet(
TileSheet::SubSheetIdx const&idx, TileSheet::SubSheetIdx const&idx,
std::size_t idxIt, std::size_t idxIt,
SubSheet const&pSubsheet) noexcept { TileSheet::SubSheet const&pSubsheet) noexcept {
if (idxIt == idx.size()) { if (idxIt == idx.size()) {
return pSubsheet; return pSubsheet;
} }
@ -291,7 +137,7 @@ const TileSheet::SubSheet &TileSheet::getSubSheet(
return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[currentIdx]); return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[currentIdx]);
} }
TileSheet::SubSheet &TileSheet::getSubSheet( TileSheet::SubSheet &getSubSheet(
TileSheet::SubSheetIdx const&idx, TileSheet::SubSheetIdx const&idx,
std::size_t idxIt, std::size_t idxIt,
TileSheet::SubSheet &pSubsheet) noexcept { TileSheet::SubSheet &pSubsheet) noexcept {
@ -301,72 +147,133 @@ TileSheet::SubSheet &TileSheet::getSubSheet(
return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]); return getSubSheet(idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]);
} }
const TileSheet::SubSheet &TileSheet::getSubSheet(TileSheet::SubSheetIdx const&idx) const noexcept { TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept {
return getSubSheet(idx, 0, subsheet); return core::getSubSheet(idx, 0, ts.subsheet);
} }
TileSheet::SubSheet &TileSheet::getSubSheet(TileSheet::SubSheetIdx const&idx) noexcept { TileSheet::SubSheet &getSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept {
return getSubSheet(idx, 0, subsheet); return core::getSubSheet(idx, 0, ts.subsheet);
} }
ox::Error TileSheet::addSubSheet(TileSheet::SubSheetIdx const&idx) noexcept { ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept {
auto &parent = getSubSheet(idx); auto &parent = getSubSheet(ts, idx);
if (parent.subsheets.size() < 2) { 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 { } else {
parent.subsheets.emplace_back(++idIt, "Subsheet 0", parent.columns, parent.rows, bpp); parent.subsheets.emplace_back(++ts.idIt, "Subsheet 0", parent.columns, parent.rows, ts.bpp);
parent.subsheets.emplace_back(++idIt, "Subsheet 1", 1, 1, bpp); parent.subsheets.emplace_back(++ts.idIt, "Subsheet 1", 1, 1, ts.bpp);
} }
return OxError(0); return OxError(0);
} }
ox::Error TileSheet::rmSubSheet( ox::Error rmSubSheet(
SubSheetIdx const&idx, TileSheet &ts,
TileSheet::SubSheetIdx const&idx,
std::size_t idxIt, std::size_t idxIt,
SubSheet &pSubsheet) noexcept { TileSheet::SubSheet &pSubsheet) noexcept {
if (idxIt == idx.size() - 1) { if (idxIt == idx.size() - 1) {
return pSubsheet.subsheets.erase(idx[idxIt]).error; 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 { ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept {
return rmSubSheet(idx, 0, subsheet); return rmSubSheet(ts, idx, 0, ts.subsheet);
} }
uint8_t TileSheet::getPixel4Bpp( uint8_t getPixel4Bpp(
TileSheet const&ts,
ox::Point const&pt, ox::Point const&pt,
TileSheet::SubSheetIdx const&subsheetIdx) const noexcept { TileSheet::SubSheetIdx const&subsheetIdx) noexcept {
oxAssert(bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
auto &s = this->getSubSheet(subsheetIdx); auto &s = getSubSheet(ts, subsheetIdx);
const auto idx = ptToIdx(pt, s.columns); 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, ox::Point const&pt,
TileSheet::SubSheetIdx const&subsheetIdx) const noexcept { TileSheet::SubSheetIdx const&subsheetIdx) noexcept {
oxAssert(bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
auto &s = this->getSubSheet(subsheetIdx); auto &s = getSubSheet(ts, subsheetIdx);
const auto idx = ptToIdx(pt, s.columns); const auto idx = ptToIdx(pt, s.columns);
return s.getPixel8Bpp(idx); return getPixel8Bpp(s, idx);
} }
ox::Result<SubSheetId> TileSheet::getIdFor(ox::CRStringView path) const noexcept { static ox::Result<SubSheetId> getIdFor(
return subsheet.getIdFor(ox::split<8>(path, '.')); TileSheet::SubSheet const&ss,
ox::SpanView<ox::StringView> 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<unsigned> TileSheet::getTileOffset(ox::CRStringView pNamePath) const noexcept { ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept {
return subsheet.getTileOffset(ox::split<8>(pNamePath, '.'), bpp); return getIdFor(ts.subsheet, ox::split<8>(path, '.'));
} }
ox::Result<ox::StringView> TileSheet::getNameFor(SubSheetId pId) const noexcept { /**
return subsheet.getNameFor(pId); * Gets the offset in tiles of the desired subsheet.
*/
static ox::Result<unsigned> getTileOffset(
TileSheet::SubSheet const&ss,
ox::SpanView<ox::StringView> 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<uint8_t> TileSheet::pixels() const noexcept { ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept {
return core::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.'), ts.bpp);
}
ox::Result<ox::StringView> getNameFor(TileSheet &ts, SubSheetId pId) noexcept {
return core::getNameFor(ts.subsheet, pId);
}
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept {
return core::getNameFor(ts.subsheet, pId);
}
static void readPixelsTo(TileSheet::SubSheet &ss, ox::Vector<uint8_t> &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<uint8_t> pixels(TileSheet &ts) noexcept {
ox::Vector<uint8_t> out; ox::Vector<uint8_t> out;
subsheet.readPixelsTo(out); readPixelsTo(ts.subsheet, out);
return out; return out;
} }

View File

@ -42,7 +42,7 @@ struct TileDoc {
if (subsheetId > -1) { if (subsheetId > -1) {
return subsheetId; return subsheetId;
} }
return ts.getIdFor(subsheetPath); return getIdFor(ts, subsheetPath);
} }
[[nodiscard]] [[nodiscard]]
@ -50,7 +50,7 @@ struct TileDoc {
core::TileSheet const&ts) const noexcept { core::TileSheet const&ts) const noexcept {
// prefer the already present path // prefer the already present path
if (!subsheetPath.len()) { if (!subsheetPath.len()) {
return ts.getNameFor(subsheetId); return core::getNameFor(ts, subsheetId);
} }
return ox::StringView(subsheetPath); return ox::StringView(subsheetPath);
} }

View File

@ -54,7 +54,7 @@ ox::Error SceneDocToSceneStaticConverter::convert(
auto dstTile = dstLayer.tile(tileIdx); auto dstTile = dstLayer.tile(tileIdx);
dstTile.tileType = srcTile.type; dstTile.tileType = srcTile.type;
oxRequire(path, srcTile.getSubsheetPath(*ts)); oxRequire(path, srcTile.getSubsheetPath(*ts));
oxRequire(mapIdx, ts->getTileOffset(path)); oxRequire(mapIdx, getTileOffset(*ts, path));
dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx); dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx);
setLayerAttachments(layerIdx, srcTile, dstTile); setLayerAttachments(layerIdx, srcTile, dstTile);
++tileIdx; ++tileIdx;