[nostalgia/core] Upgrade TileSheet format to support subsheets and add conversion system
This commit is contained in:
+157
-7
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user