[nostalgia/core] Add a function for resizing tile sheets

This commit is contained in:
Gary Talent 2023-06-25 17:11:18 -05:00
parent 341217b78e
commit 07fb60ed3d
4 changed files with 56 additions and 16 deletions

View File

@ -11,36 +11,42 @@
namespace nostalgia::core { namespace nostalgia::core {
[[nodiscard]] [[nodiscard]]
constexpr std::size_t ptToIdx(int x, int y, int c) noexcept { constexpr std::size_t ptToIdx(int x, int y, int c, int scale = 1) noexcept {
constexpr auto colLength = static_cast<std::size_t>(PixelsPerTile); const auto tileWidth = TileWidth * scale;
const auto rowLength = static_cast<std::size_t>(static_cast<std::size_t>(c / TileWidth) * colLength); const auto tileHeight = TileHeight * scale;
const auto colStart = static_cast<std::size_t>(colLength * static_cast<std::size_t>(x / TileWidth)); const auto pixelsPerTile = tileWidth * tileHeight;
const auto rowStart = static_cast<std::size_t>(rowLength * static_cast<std::size_t>(y / TileHeight)); const auto colLength = static_cast<std::size_t>(pixelsPerTile);
const auto colOffset = static_cast<std::size_t>(x % TileWidth); const auto rowLength = static_cast<std::size_t>(static_cast<std::size_t>(c / tileWidth) * colLength);
const auto rowOffset = static_cast<std::size_t>(static_cast<std::size_t>(y % TileHeight) * TileHeight); const auto colStart = static_cast<std::size_t>(colLength * static_cast<std::size_t>(x / tileWidth));
const auto rowStart = static_cast<std::size_t>(rowLength * static_cast<std::size_t>(y / tileHeight));
const auto colOffset = static_cast<std::size_t>(x % tileWidth);
const auto rowOffset = static_cast<std::size_t>(static_cast<std::size_t>((y % tileHeight) * tileHeight));
return static_cast<std::size_t>(colStart + colOffset + rowStart + rowOffset); return static_cast<std::size_t>(colStart + colOffset + rowStart + rowOffset);
} }
[[nodiscard]] [[nodiscard]]
constexpr std::size_t ptToIdx(const ox::Point &pt, int c) noexcept { constexpr std::size_t ptToIdx(const ox::Point &pt, int c, int scale = 1) noexcept {
return ptToIdx(pt.x, pt.y, c * TileWidth); return ptToIdx(pt.x, pt.y, c * TileWidth, scale);
} }
[[nodiscard]] [[nodiscard]]
constexpr ox::Point idxToPt(int i, int c) noexcept { constexpr ox::Point idxToPt(int i, int c, int scale = 1) noexcept {
const auto tileWidth = TileWidth * scale;
const auto tileHeight = TileHeight * scale;
const auto pixelsPerTile = tileWidth * tileHeight;
// prevent divide by zeros // prevent divide by zeros
if (!c) { if (!c) {
++c; ++c;
} }
const auto t = i / PixelsPerTile; // tile number const auto t = i / pixelsPerTile; // tile number
const auto iti = i % PixelsPerTile; // in tile index const auto iti = i % pixelsPerTile; // in tile index
const auto tc = t % c; // tile column const auto tc = t % c; // tile column
const auto tr = t / c; // tile row const auto tr = t / c; // tile row
const auto itx = iti % TileWidth; // in tile x const auto itx = iti % tileWidth; // in tile x
const auto ity = iti / TileHeight; // in tile y const auto ity = iti / tileHeight; // in tile y
return { return {
itx + tc * TileWidth, itx + tc * tileWidth,
ity + tr * TileHeight, ity + tr * tileHeight,
}; };
} }

View File

@ -565,4 +565,9 @@ oxModelBegin(CompactTileSheet)
oxModelField(pixels) oxModelField(pixels)
oxModelEnd() oxModelEnd()
ox::Vector<uint32_t> resizeTileSheetData(
ox::Vector<uint32_t> const&srcPixels,
ox::Size const&srcSize,
int scale = 2) noexcept;
} }

View File

@ -1,6 +1,7 @@
add_library( add_library(
NostalgiaCore NostalgiaCore
gfx.cpp gfx.cpp
tilesheet.cpp
) )
add_subdirectory(gba) add_subdirectory(gba)

View File

@ -0,0 +1,28 @@
#include <ox/std/size.hpp>
#include <ox/std/vector.hpp>
#include <nostalgia/core/ptidxconv.hpp>
namespace nostalgia::core {
ox::Vector<uint32_t> resizeTileSheetData(
ox::Vector<uint32_t> const&srcPixels,
ox::Size const&srcSize,
int scale = 2) noexcept {
ox::Vector<uint32_t> dst;
auto dstWidth = srcSize.width * scale;
auto dstHeight = srcSize.height * scale;
const auto pixelCnt = dstWidth * dstHeight;
dst.resize(static_cast<std::size_t>(pixelCnt));
for (auto i = 0; i < pixelCnt; ++i) {
const auto dstPt = idxToPt(i, 1, scale);
const auto srcPt = dstPt / ox::Point{scale, scale};
const auto srcIdx = ptToIdx(srcPt, 1);
const auto srcPixel = srcPixels[srcIdx];
dst[static_cast<std::size_t>(i)] = srcPixel;
}
return dst;
}
}