[nostalgia/core] Upgrade TileSheet format to support subsheets and add conversion system

This commit is contained in:
2022-02-17 04:27:23 -06:00
parent 3c44c86e91
commit 7ac7909510
11 changed files with 290 additions and 36 deletions
+157 -7
View File
@@ -35,7 +35,7 @@ struct Palette {
ox::Vector<Color16> colors;
};
struct TileSheet {
struct TileSheetV1 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaGraphic";
static constexpr auto TypeVersion = 1;
int8_t bpp = 0;
@@ -48,7 +48,7 @@ struct TileSheet {
[[nodiscard]]
constexpr uint8_t getPixel4Bpp(std::size_t idx) const noexcept {
oxAssert(bpp == 4, "NostalgiaGraphic::getPixel4Bpp: wrong bpp");
oxAssert(bpp == 4, "TileSheetV1::getPixel4Bpp: wrong bpp");
if (idx & 1) {
return this->pixels[idx / 2] >> 4;
} else {
@@ -58,7 +58,7 @@ struct TileSheet {
[[nodiscard]]
constexpr uint8_t getPixel8Bpp(std::size_t idx) const noexcept {
oxAssert(bpp == 8, "NostalgiaGraphic::getPixel8Bpp: wrong bpp");
oxAssert(bpp == 8, "TileSheetV1::getPixel8Bpp: wrong bpp");
return this->pixels[idx];
}
@@ -73,14 +73,14 @@ struct TileSheet {
[[nodiscard]]
constexpr auto getPixel4Bpp(const geo::Point &pt) const noexcept {
oxAssert(bpp == 4, "NostalgiaGraphic::getPixel4Bpp: wrong bpp");
oxAssert(bpp == 4, "TileSheetV1::getPixel4Bpp: wrong bpp");
const auto idx = ptToIdx(pt, this->columns);
return getPixel4Bpp(idx);
}
[[nodiscard]]
constexpr auto getPixel8Bpp(const geo::Point &pt) const noexcept {
oxAssert(bpp == 8, "NostalgiaGraphic::getPixel8Bpp: wrong bpp");
oxAssert(bpp == 8, "TileSheetV1::getPixel8Bpp: wrong bpp");
const auto idx = ptToIdx(pt, this->columns);
return getPixel8Bpp(idx);
}
@@ -92,7 +92,7 @@ struct TileSheet {
}
constexpr void setPixel(uint64_t idx, uint8_t palIdx) noexcept {
auto &pixel = this->pixels[idx / 2];
auto &pixel = this->pixels[idx / 2];
if (bpp == 4) {
if (idx & 1) {
pixel = (pixel & 0b0000'1111) | (palIdx << 4);
@@ -110,11 +110,144 @@ struct TileSheet {
}
};
struct TileSheet {
using SubSheetIdx = ox::Vector<std::size_t, 4>;
struct SubSheet {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
static constexpr auto TypeVersion = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
ox::BString<32> name;
std::size_t begin = 0;
std::size_t size = 0;
int rows = 1;
int columns = 1;
ox::Vector<SubSheet> subsheets;
};
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
static constexpr auto TypeVersion = 2;
int8_t bpp = 0;
// rows and columns are really only used by TileSheetEditor
ox::FileAddress defaultPalette;
Palette pal;
ox::Vector<uint8_t> pixels;
SubSheet subsheet;
[[nodiscard]]
constexpr const auto &getSubSheet(const SubSheetIdx &idx, std::size_t idxIt, const SubSheet *pSubsheet) const noexcept {
if (idxIt == idx.size()) {
return *pSubsheet;
}
return getSubSheet(idx, idxIt + 1, &pSubsheet->subsheets[idx[idxIt]]);
}
[[nodiscard]]
constexpr const auto &getSubSheet(const SubSheetIdx &idx) const noexcept {
return getSubSheet(idx, 0, &subsheet);
}
[[nodiscard]]
constexpr auto &getSubSheet(const SubSheetIdx &idx, std::size_t idxIt, const SubSheet *pSubsheet) noexcept {
if (idxIt == idx.size()) {
return *pSubsheet;
}
return getSubSheet(idx, idxIt + 1, &pSubsheet->subsheets[idx[idxIt]]);
}
[[nodiscard]]
constexpr auto &getSubSheet(const SubSheetIdx &idx) noexcept {
return getSubSheet(idx, 0, &subsheet);
}
[[nodiscard]]
constexpr const auto &columns(const SubSheetIdx &idx = {}) const noexcept {
return getSubSheet(idx).columns;
}
[[nodiscard]]
constexpr const auto &rows(const SubSheetIdx &idx = {}) const noexcept {
return getSubSheet(idx).rows;
}
[[nodiscard]]
constexpr auto &columns(const SubSheetIdx &idx = {}) noexcept {
return getSubSheet(idx).columns;
}
[[nodiscard]]
constexpr auto &rows(const SubSheetIdx &idx = {}) noexcept {
return getSubSheet(idx).rows;
}
[[nodiscard]]
constexpr uint8_t getPixel4Bpp(std::size_t idx) const noexcept {
oxAssert(bpp == 4, "TileSheetV1::getPixel4Bpp: wrong bpp");
if (idx & 1) {
return this->pixels[idx / 2] >> 4;
} else {
return this->pixels[idx / 2] & 0b0000'1111;
}
}
[[nodiscard]]
constexpr uint8_t getPixel8Bpp(std::size_t idx) const noexcept {
oxAssert(bpp == 8, "TileSheetV1::getPixel8Bpp: wrong bpp");
return this->pixels[idx];
}
[[nodiscard]]
constexpr auto getPixel(std::size_t idx) const noexcept {
if (this->bpp == 4) {
return getPixel4Bpp(idx);
} else {
return getPixel8Bpp(idx);
}
}
[[nodiscard]]
constexpr auto getPixel4Bpp(const geo::Point &pt, const SubSheetIdx &subsheetIdx) const noexcept {
oxAssert(bpp == 4, "TileSheetV1::getPixel4Bpp: wrong bpp");
const auto idx = ptToIdx(pt, this->getSubSheet(subsheetIdx).columns);
return getPixel4Bpp(idx);
}
[[nodiscard]]
constexpr auto getPixel8Bpp(const geo::Point &pt, const SubSheetIdx &subsheetIdx) const noexcept {
oxAssert(bpp == 8, "TileSheetV1::getPixel8Bpp: wrong bpp");
const auto idx = ptToIdx(pt, this->getSubSheet(subsheetIdx).columns);
return getPixel8Bpp(idx);
}
[[nodiscard]]
constexpr auto getPixel(const geo::Point &pt, const SubSheetIdx &subsheetIdx) const noexcept {
const auto idx = ptToIdx(pt, this->getSubSheet(subsheetIdx).columns);
return getPixel(idx);
}
constexpr void setPixel(uint64_t idx, uint8_t palIdx) noexcept {
auto &pixel = this->pixels[idx / 2];
if (bpp == 4) {
if (idx & 1) {
pixel = (pixel & 0b0000'1111) | (palIdx << 4);
} else {
pixel = (pixel & 0b1111'0000) | (palIdx);
}
} else {
pixel = palIdx;
}
}
constexpr void setPixel(const SubSheetIdx &subsheetIdx, const geo::Point &pt, uint8_t palIdx) noexcept {
const auto idx = ptToIdx(pt, this->getSubSheet(subsheetIdx).columns);
setPixel(idx, palIdx);
}
};
oxModelBegin(Palette)
oxModelField(colors)
oxModelEnd()
oxModelBegin(TileSheet)
oxModelBegin(TileSheetV1)
oxModelField(bpp)
oxModelField(rows)
oxModelField(columns)
@@ -123,6 +256,23 @@ oxModelBegin(TileSheet)
oxModelField(pixels)
oxModelEnd()
oxModelBegin(TileSheet)
oxModelField(bpp)
oxModelField(defaultPalette)
oxModelField(pal)
oxModelField(pixels)
oxModelField(subsheet)
oxModelEnd()
oxModelBegin(TileSheet::SubSheet)
oxModelField(name);
oxModelField(begin);
oxModelField(size);
oxModelField(rows);
oxModelField(columns);
oxModelField(subsheets)
oxModelEnd()
struct Sprite {
unsigned idx = 0;
unsigned x = 0;