[nostalgia] Add support for partial tilesheet loading
This commit is contained in:
parent
da23c9304d
commit
c599905000
@ -139,7 +139,15 @@ ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
CompactTileSheet const&ts,
|
||||
ox::Optional<unsigned> const&paletteBank) noexcept;
|
||||
size_t dstTileIdx,
|
||||
size_t srcTileIdx,
|
||||
size_t tileCnt) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
CompactTileSheet const&ts,
|
||||
ox::Optional<unsigned> const&paletteBank = {}) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
|
@ -31,6 +31,12 @@ struct TileSheetV1 {
|
||||
ox::Vector<uint8_t> pixels = {};
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV1 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
}
|
||||
|
||||
|
||||
struct TileSheetV2 {
|
||||
using SubSheetIdx = ox::Vector<std::size_t, 4>;
|
||||
|
||||
@ -43,8 +49,8 @@ struct TileSheetV2 {
|
||||
ox::Vector<SubSheet> subsheets;
|
||||
ox::Vector<uint8_t> pixels;
|
||||
constexpr SubSheet() noexcept = default;
|
||||
constexpr SubSheet(ox::CRStringView pName, int pColumns, int pRows, int bpp) noexcept:
|
||||
name(pName),
|
||||
constexpr SubSheet(ox::StringParam pName, int pColumns, int pRows, int bpp) noexcept:
|
||||
name(std::move(pName)),
|
||||
columns(pColumns),
|
||||
rows(pRows),
|
||||
pixels(static_cast<size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
||||
@ -59,6 +65,12 @@ struct TileSheetV2 {
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV2 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
}
|
||||
|
||||
|
||||
using SubSheetId = int32_t;
|
||||
|
||||
struct TileSheetV3 {
|
||||
@ -74,14 +86,14 @@ struct TileSheetV3 {
|
||||
ox::Vector<SubSheet> subsheets;
|
||||
ox::Vector<uint8_t> pixels;
|
||||
constexpr SubSheet() noexcept = default;
|
||||
inline SubSheet(
|
||||
SubSheet(
|
||||
SubSheetId pId,
|
||||
ox::CRStringView pName,
|
||||
ox::StringParam pName,
|
||||
int pColumns,
|
||||
int pRows,
|
||||
int bpp) noexcept:
|
||||
id(pId),
|
||||
name(pName),
|
||||
name(std::move(pName)),
|
||||
columns(pColumns),
|
||||
rows(pRows),
|
||||
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
||||
@ -98,7 +110,13 @@ struct TileSheetV3 {
|
||||
|
||||
};
|
||||
|
||||
struct TileSheet {
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV3 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
}
|
||||
|
||||
|
||||
struct TileSheetV4 {
|
||||
using SubSheetIdx = ox::Vector<std::size_t, 4>;
|
||||
|
||||
struct SubSheet {
|
||||
@ -112,26 +130,26 @@ struct TileSheet {
|
||||
ox::Vector<uint8_t> pixels;
|
||||
|
||||
constexpr SubSheet() noexcept = default;
|
||||
inline SubSheet(
|
||||
SubSheet(
|
||||
SubSheetId pId,
|
||||
ox::CRStringView pName,
|
||||
ox::StringParam pName,
|
||||
int pColumns,
|
||||
int pRows,
|
||||
int bpp) noexcept:
|
||||
id(pId),
|
||||
name(pName),
|
||||
name(std::move(pName)),
|
||||
columns(pColumns),
|
||||
rows(pRows),
|
||||
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
||||
}
|
||||
inline SubSheet(
|
||||
SubSheet(
|
||||
SubSheetId pId,
|
||||
ox::CRStringView pName,
|
||||
ox::StringParam pName,
|
||||
int pColumns,
|
||||
int pRows,
|
||||
ox::Vector<uint8_t> pPixels) noexcept:
|
||||
id(pId),
|
||||
name(pName),
|
||||
name(std::move(pName)),
|
||||
columns(pColumns),
|
||||
rows(pRows),
|
||||
pixels(std::move(pPixels)) {
|
||||
@ -151,10 +169,18 @@ struct TileSheet {
|
||||
ox::FileAddress defaultPalette;
|
||||
SubSheet subsheet{0, "Root", 1, 1, bpp};
|
||||
|
||||
constexpr TileSheet() noexcept = default;
|
||||
constexpr TileSheetV4() noexcept = default;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV4 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
}
|
||||
|
||||
|
||||
using TileSheet = TileSheetV4;
|
||||
|
||||
[[nodiscard]]
|
||||
std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
||||
|
||||
@ -286,12 +312,11 @@ ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::CRStringView pNamePat
|
||||
|
||||
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept;
|
||||
|
||||
ox::Result<ox::StringView> getNameFor(TileSheet const&ss, SubSheetId pId) noexcept;
|
||||
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept;
|
||||
|
||||
using TileSheetV4 = TileSheet;
|
||||
|
||||
struct CompactTileSheetV1 {
|
||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactTileSheet";
|
||||
@ -307,8 +332,29 @@ constexpr bool valid(CompactTileSheetV1 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
}
|
||||
|
||||
|
||||
using CompactTileSheet = CompactTileSheetV1;
|
||||
|
||||
[[nodiscard]]
|
||||
uint8_t getPixel4Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t idx) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
uint8_t getPixel8Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t idx) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
ox::Pair<uint8_t> get2Pixels4Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t idx) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
ox::Pair<uint8_t> get2Pixels8Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t idx) noexcept;
|
||||
|
||||
oxModelBegin(TileSheetV1)
|
||||
oxModelField(bpp)
|
||||
oxModelField(rows)
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/mc/mc.hpp>
|
||||
#include <ox/std/array.hpp>
|
||||
|
||||
#include <teagba/addresses.hpp>
|
||||
@ -11,9 +10,7 @@
|
||||
#include <teagba/registers.hpp>
|
||||
|
||||
#include <keel/keel.hpp>
|
||||
#include <turbine/turbine.hpp>
|
||||
|
||||
#include <nostalgia/core/color.hpp>
|
||||
#include <nostalgia/core/context.hpp>
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <nostalgia/core/tilesheet.hpp>
|
||||
@ -22,7 +19,7 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
constexpr auto SpriteCount = 128;
|
||||
static constexpr auto SpriteCount = 128;
|
||||
|
||||
ox::Error initGfx(Context&, InitParams const&) noexcept {
|
||||
for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) {
|
||||
@ -81,7 +78,7 @@ ox::Error loadSpritePalette(
|
||||
|
||||
static ox::Error loadTileSheetSet(
|
||||
Context &ctx,
|
||||
uint16_t *tileMapTargetMem,
|
||||
ox::Span<uint16_t> tileMapTargetMem,
|
||||
TileSheetSet const&set) noexcept {
|
||||
size_t tileWriteIdx = 0;
|
||||
size_t const bppMod = set.bpp == 4;
|
||||
@ -106,6 +103,34 @@ static ox::Error loadTileSheetSet(
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned const cbb,
|
||||
CompactTileSheet const&ts,
|
||||
size_t const dstTileIdx,
|
||||
size_t const srcTileIdx,
|
||||
size_t const tileCnt) noexcept {
|
||||
size_t const bppMod = ts.bpp == 4;
|
||||
size_t const bytesPerTile = PixelsPerTile >> bppMod;
|
||||
auto const pixCnt = tileCnt * bytesPerTile;
|
||||
auto const srcPxIdx = srcTileIdx * bytesPerTile;
|
||||
auto const dstPxIdx = (dstTileIdx * bytesPerTile) / 2;
|
||||
for (size_t i = 0; i < pixCnt; ++i) {
|
||||
auto const srcIdx = srcPxIdx + i * 2;
|
||||
auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]);
|
||||
auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]);
|
||||
MEM_BG_TILES[cbb][dstPxIdx + i] = static_cast<uint16_t>(p1 | (p2 << 8));
|
||||
}
|
||||
// update bpp of all bgs with the updated cbb
|
||||
auto const bpp = ctx.cbbData[cbb].bpp;
|
||||
teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) {
|
||||
if (teagba::bgCbb(bgCtl) == cbb) {
|
||||
teagba::bgSetBpp(bgCtl, bpp);
|
||||
}
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
@ -142,10 +167,10 @@ ox::Error loadBgTileSheet(
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
unsigned const cbb,
|
||||
TileSheetSet const&set) noexcept {
|
||||
auto const bpp = static_cast<unsigned>(set.bpp);
|
||||
oxReturnError(loadTileSheetSet(ctx, MEM_BG_TILES[cbb].data(), set));
|
||||
oxReturnError(loadTileSheetSet(ctx, MEM_BG_TILES[cbb], set));
|
||||
// update bpp of all bgs with the updated cbb
|
||||
ctx.cbbData[cbb].bpp = bpp;
|
||||
teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) {
|
||||
@ -193,7 +218,7 @@ ox::Error loadSpriteTileSheet(
|
||||
Context &ctx,
|
||||
TileSheetSet const&set) noexcept {
|
||||
auto const bpp = static_cast<unsigned>(set.bpp);
|
||||
oxReturnError(loadTileSheetSet(ctx, MEM_SPRITE_TILES, set));
|
||||
oxReturnError(loadTileSheetSet(ctx, {MEM_SPRITE_TILES, 32 * ox::units::KB}, set));
|
||||
setSpritesBpp(bpp);
|
||||
return {};
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ namespace nostalgia::core {
|
||||
|
||||
namespace renderer {
|
||||
|
||||
constexpr auto Scale = 1;
|
||||
constexpr auto PriorityScale = 0.01f;
|
||||
static constexpr auto Scale = 1;
|
||||
static constexpr auto PriorityScale = 0.01f;
|
||||
|
||||
Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {}
|
||||
|
||||
@ -31,7 +31,7 @@ void Drawer::draw(turbine::Context &tctx) noexcept {
|
||||
core::gl::draw(m_ctx, turbine::getScreenSize(tctx));
|
||||
}
|
||||
|
||||
constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||
static constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||
{}
|
||||
in vec2 vTexCoord;
|
||||
in vec3 vPosition;
|
||||
@ -55,7 +55,7 @@ constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||
fPalOffset = vPalOffset;
|
||||
})glsl";
|
||||
|
||||
constexpr ox::CStringView bgfshadTmpl = R"glsl(
|
||||
static constexpr ox::CStringView bgfshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in float fPalOffset;
|
||||
@ -71,7 +71,7 @@ constexpr ox::CStringView bgfshadTmpl = R"glsl(
|
||||
}
|
||||
})glsl";
|
||||
|
||||
constexpr ox::CStringView spritevshadTmpl = R"glsl(
|
||||
static constexpr ox::CStringView spritevshadTmpl = R"glsl(
|
||||
{}
|
||||
in float vEnabled;
|
||||
in vec3 vPosition;
|
||||
@ -90,7 +90,7 @@ constexpr ox::CStringView spritevshadTmpl = R"glsl(
|
||||
fTexCoord = vTexCoord * vec2(1, vTileHeight);
|
||||
})glsl";
|
||||
|
||||
constexpr ox::CStringView spritefshadTmpl = R"glsl(
|
||||
static constexpr ox::CStringView spritefshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in vec2 fTexCoord;
|
||||
@ -279,7 +279,7 @@ static void initBackgroundBufferset(
|
||||
static glutils::GLTexture createTexture(
|
||||
GLsizei w,
|
||||
GLsizei h,
|
||||
const void *pixels) noexcept {
|
||||
void const*pixels) noexcept {
|
||||
GLuint texId = 0;
|
||||
glGenTextures(1, &texId);
|
||||
glutils::GLTexture tex(texId);
|
||||
@ -492,22 +492,22 @@ struct TileSheetData {
|
||||
};
|
||||
|
||||
static ox::Result<TileSheetData> normalizeTileSheet(
|
||||
CompactTileSheet const&tilesheet) noexcept {
|
||||
const uint_t bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
|
||||
const auto tiles = tilesheet.pixels.size() / bytesPerTile;
|
||||
CompactTileSheet const&ts) noexcept {
|
||||
const uint_t bytesPerTile = ts.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
|
||||
const auto tiles = ts.pixels.size() / bytesPerTile;
|
||||
constexpr int width = 8;
|
||||
const int height = 8 * static_cast<int>(tiles);
|
||||
ox::Vector<uint32_t> pixels;
|
||||
if (bytesPerTile == 64) { // 8 BPP
|
||||
pixels.resize(tilesheet.pixels.size());
|
||||
for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) {
|
||||
pixels[i] = tilesheet.pixels[i];
|
||||
pixels.resize(ts.pixels.size());
|
||||
for (std::size_t i = 0; i < ts.pixels.size(); ++i) {
|
||||
pixels[i] = ts.pixels[i];
|
||||
}
|
||||
} else { // 4 BPP
|
||||
pixels.resize(tilesheet.pixels.size() * 2);
|
||||
for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) {
|
||||
pixels[i * 2 + 0] = tilesheet.pixels[i] & 0xF;
|
||||
pixels[i * 2 + 1] = tilesheet.pixels[i] >> 4;
|
||||
pixels.resize(ts.pixels.size() * 2);
|
||||
for (std::size_t i = 0; i < ts.pixels.size(); ++i) {
|
||||
pixels[i * 2 + 0] = ts.pixels[i] & 0xF;
|
||||
pixels[i * 2 + 1] = ts.pixels[i] >> 4;
|
||||
}
|
||||
}
|
||||
return TileSheetData{std::move(pixels), width, height};
|
||||
@ -572,14 +572,58 @@ static ox::Result<TileSheetData> buildSetTsd(
|
||||
return setTsd;
|
||||
}
|
||||
|
||||
static void copyPixels(
|
||||
CompactTileSheet const&ts,
|
||||
uint32_t *dst,
|
||||
size_t const srcPxIdx,
|
||||
size_t pxlCnt) noexcept {
|
||||
if (ts.bpp == 4) {
|
||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
||||
auto const [a, b] = get2Pixels4Bpp(ts, i + srcPxIdx);
|
||||
*(dst++) = a;
|
||||
*(dst++) = b;
|
||||
}
|
||||
} else if (ts.bpp == 8) {
|
||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
||||
auto const [a, b] = get2Pixels8Bpp(ts, i + srcPxIdx);
|
||||
*(dst++) = a;
|
||||
*(dst++) = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned const cbb,
|
||||
CompactTileSheet const&ts,
|
||||
size_t const dstTileIdx,
|
||||
size_t const srcTileIdx,
|
||||
size_t const tileCnt) noexcept {
|
||||
auto &cbbPxls = ctx.cbbs[cbb].pixels;
|
||||
auto const bytesPerTile = static_cast<uint64_t>(PixelsPerTile / (1 + (ts.bpp == 4)));
|
||||
auto const pxlCnt = tileCnt * PixelsPerTile;
|
||||
auto const srcPxIdx = srcTileIdx * PixelsPerTile;
|
||||
auto const dstPxIdx = dstTileIdx * PixelsPerTile;
|
||||
if (dstPxIdx + pxlCnt >= cbbPxls.size()) {
|
||||
return OxError(1, "video mem dst overflow");
|
||||
}
|
||||
auto const dst = &cbbPxls[dstPxIdx];
|
||||
copyPixels(ts, dst, srcPxIdx, pxlCnt);
|
||||
auto const cbbTiles = cbbPxls.size() / bytesPerTile;
|
||||
int constexpr cbbWidth = 8;
|
||||
int const cbbHeight = 8 * static_cast<int>(cbbTiles);
|
||||
ctx.cbbs[cbb].tex = renderer::createTexture(cbbWidth, cbbHeight, cbbPxls.data());
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
uint_t cbb,
|
||||
CompactTileSheet const&ts,
|
||||
ox::Optional<unsigned> const&paletteBank) noexcept {
|
||||
oxRequire(tsd, normalizeTileSheet(ts));
|
||||
oxTracef("nostalgia.core.gfx.gl", "loadBgTexture: { cbbIdx: {}, w: {}, h: {} }", cbb, tsd.width, tsd.height);
|
||||
ctx.cbbs[cbb].tex = renderer::createTexture(tsd.width, tsd.height, tsd.pixels.data());
|
||||
auto const bytesPerTile = static_cast<uint64_t>(PixelsPerTile / (1 + (ts.bpp == 4)));
|
||||
auto const tiles = ts.pixels.size() / bytesPerTile;
|
||||
oxReturnError(loadBgTileSheet(ctx, cbb, ts, 0, 0, tiles));
|
||||
if (paletteBank.has_value() && ts.defaultPalette) {
|
||||
oxReturnError(loadBgPalette(ctx, *paletteBank, ts.defaultPalette));
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ constexpr uint64_t SpriteVertexEboLength = 6;
|
||||
|
||||
struct CBB: public glutils::BufferSet {
|
||||
bool updated = false;
|
||||
ox::Array<uint32_t, 32768> pixels;
|
||||
constexpr CBB() noexcept {
|
||||
vertices.resize(TileCount * BgVertexVboLength);
|
||||
elements.resize(TileCount * BgVertexEboLength);
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
oxModelFwdDecl(class TileSheetClipboard);
|
||||
|
||||
class TileSheetClipboard: public turbine::ClipboardObject<TileSheetClipboard> {
|
||||
public:
|
||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard";
|
||||
|
@ -312,9 +312,8 @@ void TileSheetEditorImGui::drawSubsheetSelector(
|
||||
for (auto i = 0ul; auto &child : subsheet.subsheets) {
|
||||
path.push_back(i);
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
ImGui::Indent(-indentReduce);
|
||||
ig::IndentStackItem const indentStackItem{-indentReduce};
|
||||
drawSubsheetSelector(child, path);
|
||||
ImGui::Indent(indentReduce);
|
||||
ImGui::PopID();
|
||||
path.pop_back();
|
||||
++i;
|
||||
@ -440,7 +439,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
||||
}
|
||||
auto const pages = m_model.pal().pages.size();
|
||||
if (pages > 1) {
|
||||
ImGui::Indent(20);
|
||||
ig::IndentStackItem const indentStackItem{20};
|
||||
using Str = ox::IString<55>;
|
||||
auto numStr = ox::sfmt<Str>(
|
||||
"{} - {}", m_model.palettePage() + 1, m_model.pal().pages[m_model.palettePage()].name);
|
||||
@ -458,7 +457,6 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::Indent(-20);
|
||||
}
|
||||
// header
|
||||
if (ImGui::BeginTable(
|
||||
|
@ -280,7 +280,7 @@ uint8_t getPixel4Bpp(
|
||||
TileSheet::SubSheetIdx const&subsheetIdx) noexcept {
|
||||
oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
|
||||
auto &s = getSubSheet(ts, subsheetIdx);
|
||||
const auto idx = ptToIdx(pt, s.columns);
|
||||
auto const idx = ptToIdx(pt, s.columns);
|
||||
return getPixel4Bpp(s, idx);
|
||||
}
|
||||
|
||||
@ -290,10 +290,49 @@ uint8_t getPixel8Bpp(
|
||||
TileSheet::SubSheetIdx const&subsheetIdx) noexcept {
|
||||
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
|
||||
auto &s = getSubSheet(ts, subsheetIdx);
|
||||
const auto idx = ptToIdx(pt, s.columns);
|
||||
auto const idx = ptToIdx(pt, s.columns);
|
||||
return getPixel8Bpp(s, idx);
|
||||
}
|
||||
|
||||
uint8_t getPixel4Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t const idx) noexcept {
|
||||
oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
|
||||
if (idx & 1) {
|
||||
return ts.pixels[idx / 2] >> 4;
|
||||
} else {
|
||||
return ts.pixels[idx / 2] & 0b0000'1111;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getPixel8Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t const idx) noexcept {
|
||||
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
|
||||
return ts.pixels[idx];
|
||||
}
|
||||
|
||||
ox::Pair<uint8_t> get2Pixels4Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t const idx) noexcept {
|
||||
oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
|
||||
auto const out = ts.pixels[idx / 2];
|
||||
return {
|
||||
static_cast<uint8_t>(out & 0x0f),
|
||||
static_cast<uint8_t>(out >> 4),
|
||||
};
|
||||
}
|
||||
|
||||
ox::Pair<uint8_t> get2Pixels8Bpp(
|
||||
CompactTileSheet const&ts,
|
||||
size_t const idx) noexcept {
|
||||
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
|
||||
return {
|
||||
static_cast<uint8_t>(ts.pixels[idx]),
|
||||
static_cast<uint8_t>(ts.pixels[idx + 1]),
|
||||
};
|
||||
}
|
||||
|
||||
static ox::Result<SubSheetId> getIdFor(
|
||||
TileSheet::SubSheet const&ss,
|
||||
ox::SpanView<ox::StringView> const&pNamePath,
|
||||
|
Loading…
Reference in New Issue
Block a user