diff --git a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp index dfbe0303..9821cc46 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp @@ -33,7 +33,14 @@ struct TileSheetV1 { [[nodiscard]] constexpr bool valid(TileSheetV1 const&ts) noexcept { - return ts.bpp == 4 || ts.bpp == 8; + auto const bytes = static_cast(ts.columns * ts.rows * PixelsPerTile) / (ts.bpp == 4 ? 2 : 1); + return (ts.bpp == 4 || ts.bpp == 8) && ts.pixels.size() == bytes; +} + +constexpr ox::Error repair(TileSheetV1 &ts, int bpp) noexcept { + auto const bytes = static_cast(ts.columns * ts.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + ts.pixels.resize(bytes); + return {}; } @@ -65,9 +72,34 @@ struct TileSheetV2 { }; +[[nodiscard]] +constexpr bool valid(TileSheetV2::SubSheet const&ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(), + [bpp, bytes](TileSheetV2::SubSheet const&s) { + return bytes == s.pixels.size() && valid(s, bpp); + }); +} + [[nodiscard]] constexpr bool valid(TileSheetV2 const&ts) noexcept { - return ts.bpp == 4 || ts.bpp == 8; + return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp); +} + +constexpr void repair(TileSheetV2::SubSheet &ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + ss.pixels.resize(bytes); + for (auto &s : ss.subsheets) { + repair(s, bpp); + } +} + +constexpr ox::Error repair(TileSheetV2 &ts) noexcept { + if (ts.bpp != 4 && ts.bpp != 8) { + return OxError(1, "Unable to repair TileSheet"); + } + repair(ts.subsheet, ts.bpp); + return {}; } @@ -110,9 +142,34 @@ struct TileSheetV3 { }; +[[nodiscard]] +constexpr bool valid(TileSheetV3::SubSheet const&ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(), + [bpp, bytes](TileSheetV3::SubSheet const&s) { + return bytes == s.pixels.size() && valid(s, bpp); + }); +} + [[nodiscard]] constexpr bool valid(TileSheetV3 const&ts) noexcept { - return ts.bpp == 4 || ts.bpp == 8; + return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp); +} + +constexpr void repair(TileSheetV3::SubSheet &ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + ss.pixels.resize(bytes); + for (auto &s : ss.subsheets) { + repair(s, bpp); + } +} + +constexpr ox::Error repair(TileSheetV3 &ts) noexcept { + if (ts.bpp != 4 && ts.bpp != 8) { + return OxError(1, "Unable to repair TileSheet"); + } + repair(ts.subsheet, ts.bpp); + return {}; } @@ -173,9 +230,34 @@ struct TileSheetV4 { }; +[[nodiscard]] +constexpr bool valid(TileSheetV4::SubSheet const&ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(), + [bpp, bytes](TileSheetV4::SubSheet const&s) { + return bytes == s.pixels.size() && valid(s, bpp); + }); +} + [[nodiscard]] constexpr bool valid(TileSheetV4 const&ts) noexcept { - return ts.bpp == 4 || ts.bpp == 8; + return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp); +} + +constexpr void repair(TileSheetV4::SubSheet &ss, int bpp) noexcept { + auto const bytes = static_cast(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1); + ss.pixels.resize(bytes); + for (auto &s : ss.subsheets) { + repair(s, bpp); + } +} + +constexpr ox::Error repair(TileSheetV4 &ts) noexcept { + if (ts.bpp != 4 && ts.bpp != 8) { + return OxError(1, "Unable to repair TileSheet"); + } + repair(ts.subsheet, ts.bpp); + return {}; }