From d29118d78398d22fedf32b7b0f5571a20838d878 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 21 Dec 2023 21:18:31 -0600 Subject: [PATCH] [nostalgia/core] Cleanup graphics API --- .../core/include/nostalgia/core/gfx.hpp | 55 +++-- .../modules/core/src/gba/context.hpp | 5 + src/nostalgia/modules/core/src/gba/gfx.cpp | 220 ++++++++---------- src/nostalgia/modules/core/src/gba/panic.cpp | 2 +- src/nostalgia/modules/core/src/gfx.cpp | 27 ++- src/nostalgia/modules/core/src/opengl/gfx.cpp | 192 +++++++-------- src/nostalgia/modules/scene/src/scene.cpp | 12 +- src/nostalgia/player/app.cpp | 43 ++-- 8 files changed, 268 insertions(+), 288 deletions(-) diff --git a/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp b/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp index 6191cc7d..3af19bfe 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp @@ -13,8 +13,6 @@ namespace nostalgia::core { -extern ox::Array charMap; - struct Sprite { bool enabled = false; int x = 0; @@ -41,11 +39,35 @@ oxModelBegin(Sprite) oxModelField(priority) oxModelEnd() +ox::Error loadBgPalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept; + +ox::Error loadSpritePalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept; + +ox::Error loadBgTileSheet( + Context &ctx, + unsigned cbb, + ox::FileAddress const&tilesheetAddr, + bool loadDefaultPalette = false) noexcept; + +ox::Error loadSpriteTileSheet( + Context &ctx, + ox::FileAddress const&tilesheetAddr, + bool loadDefaultPalette = false) noexcept; + +void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, uint8_t tile) noexcept; + +void clearBg(Context &ctx, uint_t bgIdx) noexcept; + [[nodiscard]] uint8_t bgStatus(Context &ctx) noexcept; void setBgStatus(Context &ctx, uint32_t status) noexcept; +[[nodiscard]] bool bgStatus(Context &ctx, unsigned bg) noexcept; void setBgStatus(Context &ctx, unsigned bg, bool status) noexcept; @@ -54,34 +76,19 @@ void setBgCbb(Context &ctx, unsigned bgIdx, unsigned cbb) noexcept; void setBgPriority(Context &ctx, uint_t bgIdx, uint_t priority) noexcept; -/** - * @param section describes which section of the selected TileSheetSpace to use (e.g. MEM_PALLETE_BG[section]) - */ -ox::Error loadBgTileSheet( - Context &ctx, - unsigned cbb, - ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr = nullptr) noexcept; - -ox::Error loadSpriteTileSheet( - Context &ctx, - ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept; - -ox::Error initConsole(Context &ctx) noexcept; - -void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept; - -void setTile(Context &ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept; - -void clearTileLayer(Context &ctx, unsigned bgIdx) noexcept; - void hideSprite(Context &ctx, unsigned) noexcept; void showSprite(Context &ctx, unsigned) noexcept; void setSprite(Context &c, uint_t idx, Sprite const&s) noexcept; +[[nodiscard]] +uint_t spriteCount(Context &ctx) noexcept; + +ox::Error initConsole(Context &ctx) noexcept; + +void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept; + } namespace nostalgia::core::gl { diff --git a/src/nostalgia/modules/core/src/gba/context.hpp b/src/nostalgia/modules/core/src/gba/context.hpp index 149e56d7..18449e4b 100644 --- a/src/nostalgia/modules/core/src/gba/context.hpp +++ b/src/nostalgia/modules/core/src/gba/context.hpp @@ -8,10 +8,15 @@ namespace nostalgia::core { +struct BgCbbData { + unsigned bpp = 4; +}; + class Context { public: turbine::Context &turbineCtx; + ox::Array cbbData; explicit Context(turbine::Context &tctx) noexcept; Context(Context &other) noexcept = delete; diff --git a/src/nostalgia/modules/core/src/gba/gfx.cpp b/src/nostalgia/modules/core/src/gba/gfx.cpp index ca0352c3..1ecf0536 100644 --- a/src/nostalgia/modules/core/src/gba/gfx.cpp +++ b/src/nostalgia/modules/core/src/gba/gfx.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -22,11 +21,6 @@ namespace nostalgia::core { -struct BgCbbData { - unsigned bpp = 4; -}; -static ox::Array g_cbbData; - constexpr auto GbaTileColumns = 32; constexpr auto GbaTileRows = 32; @@ -41,17 +35,23 @@ struct GbaTileMapTarget { static constexpr auto TypeVersion = CompactTileSheet::TypeVersion; BgCbbData *cbbData = nullptr; ox::FileAddress defaultPalette; - GbaPaletteTarget pal; volatile uint16_t *tileMap = nullptr; }; constexpr ox::Error model(auto *io, ox::CommonPtrWith auto *t) noexcept { oxReturnError(io->template setTypeInfo()); - const auto colorHandler = [t](std::size_t i, const Color16 *c) { - t->palette[i] = *c; - return OxError(0); - }; - return io->template field("colors", colorHandler); + if (t->palette) { + const auto colorHandler = [t](std::size_t i, const Color16 *c) { + t->palette[i] = *c; + return ox::Error{}; + }; + return io->template field("colors", colorHandler); + } else { + constexpr auto colorHandler = [](std::size_t, const Color16*) { + return ox::Error{}; + }; + return io->template field("colors", colorHandler); + } } constexpr ox::Error model(auto *io, ox::CommonPtrWith auto *t) noexcept { @@ -73,11 +73,87 @@ constexpr ox::Error model(auto *io, ox::CommonPtrWith auto *t) ox::Error initGfx(Context&, InitParams const&) noexcept { for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) { - teagba::bgSetSbb(bgCtl, 28); + teagba::bgSetSbb(*bgCtl, 28); } return {}; } +ox::Error loadBgPalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept { + auto &rom = ctx.rom(); + GbaPaletteTarget const palTarget{.palette = MEM_BG_PALETTE}; + oxRequire(palStat, rom.stat(paletteAddr)); + oxRequire(pal, rom.directAccess(paletteAddr)); + oxReturnError(ox::readMC(pal, static_cast(palStat.size), &palTarget)); + return {}; +} + +ox::Error loadSpritePalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept { + auto &rom = ctx.rom(); + GbaPaletteTarget const palTarget{.palette = MEM_SPRITE_PALETTE}; + oxRequire(palStat, rom.stat(paletteAddr)); + oxRequire(pal, rom.directAccess(paletteAddr)); + oxReturnError(ox::readMC(pal, static_cast(palStat.size), &palTarget)); + return {}; +} + +ox::Error loadBgTileSheet( + Context &ctx, + unsigned cbb, + ox::FileAddress const&tilesheetAddr, + bool loadDefaultPalette) noexcept { + auto &rom = ctx.rom(); + oxRequire(tsStat, rom.stat(tilesheetAddr)); + oxRequire(ts, rom.directAccess(tilesheetAddr)); + GbaTileMapTarget target{ + .cbbData = &ctx.cbbData[cbb], + .defaultPalette = {}, + .tileMap = MEM_BG_TILES[cbb].data(), + }; + oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); + // update bpp of all bgs with the updated cbb + const auto bpp = ctx.cbbData[cbb].bpp; + teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) { + if (teagba::bgCbb(bgCtl) == cbb) { + teagba::bgSetBpp(bgCtl, bpp); + } + }); + if (loadDefaultPalette && target.defaultPalette) { + oxReturnError(loadBgPalette(ctx, target.defaultPalette)); + } + return {}; +} + +ox::Error loadSpriteTileSheet( + Context &ctx, + ox::FileAddress const&tilesheetAddr, + bool loadDefaultPalette) noexcept { + auto &rom = ctx.rom(); + oxRequire(tsStat, ctx.rom().stat(tilesheetAddr)); + oxRequire(ts, rom.directAccess(tilesheetAddr)); + GbaTileMapTarget target{ + .defaultPalette = {}, + .tileMap = MEM_SPRITE_TILES, + }; + oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); + if (loadDefaultPalette && target.defaultPalette) { + oxReturnError(loadSpritePalette(ctx, target.defaultPalette)); + } + return {}; +} + +void setBgTile(Context&, uint_t bgIdx, int column, int row, uint8_t tile) noexcept { + const auto tileIdx = static_cast(row * GbaTileColumns + column); + MEM_BG_MAP[bgIdx][tileIdx] = tile; +} + +void clearBg(Context&, uint_t bgIdx) noexcept { + memset(MEM_BG_MAP[bgIdx].data(), 0, GbaTileRows * GbaTileColumns); +} + uint8_t bgStatus(Context&) noexcept { return (REG_DISPCTL >> 8u) & 0b1111u; } @@ -97,11 +173,11 @@ void setBgStatus(Context&, unsigned bg, bool status) noexcept { REG_DISPCTL = REG_DISPCTL | ((REG_DISPCTL & ~mask) | mask); } -void setBgCbb(Context&, unsigned bgIdx, unsigned cbb) noexcept { +void setBgCbb(Context &ctx, unsigned bgIdx, unsigned cbb) noexcept { auto &bgCtl = regBgCtl(bgIdx); - const auto &cbbData = g_cbbData[cbb]; - teagba::bgSetBpp(&bgCtl, cbbData.bpp); - teagba::bgSetCbb(&bgCtl, cbb); + const auto &cbbData = ctx.cbbData[cbb]; + teagba::bgSetBpp(bgCtl, cbbData.bpp); + teagba::bgSetCbb(bgCtl, cbb); } void setBgPriority(Context&, uint_t bgIdx, uint_t priority) noexcept { @@ -109,111 +185,6 @@ void setBgPriority(Context&, uint_t bgIdx, uint_t priority) noexcept { bgCtl = (bgCtl & 0b1111'1111'1111'1100u) | (priority & 0b11); } -static ox::Error loadBgTileSheet( - ox::MemFS const&rom, - unsigned cbb, - ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept { - oxRequire(tsStat, rom.stat(tilesheetAddr)); - oxRequire(ts, rom.directAccess(tilesheetAddr)); - GbaTileMapTarget target; - target.pal.palette = MEM_BG_PALETTE; - target.cbbData = &g_cbbData[cbb]; - target.tileMap = MEM_BG_TILES[cbb].data(); - oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); - // load external palette if available - if (paletteAddr) { - oxRequire(palStat, rom.stat(paletteAddr)); - oxRequire(pal, rom.directAccess(paletteAddr)); - oxReturnError(ox::readMC(pal, static_cast(palStat.size), &target.pal)); - } - // update bpp of all bgs with the updated cbb - const auto bpp = g_cbbData[cbb].bpp; - teagba::iterateBgCtl([bpp, cbb](auto bgCtl) { - if (teagba::bgCbb(bgCtl) == cbb) { - teagba::bgSetBpp(bgCtl, bpp); - } - }); - return {}; -} - -ox::Error loadBgTileSheet( - Context &ctx, - unsigned cbb, - ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept { - auto &rom = ctx.rom(); - return loadBgTileSheet(rom, cbb, tilesheetAddr, paletteAddr); -} - -ox::Error loadSpriteTileSheet( - Context &ctx, - ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept { - auto &rom = ctx.rom(); - oxRequire(tsStat, ctx.rom().stat(tilesheetAddr)); - oxRequire(ts, rom.directAccess(tilesheetAddr)); - GbaTileMapTarget target; - target.pal.palette = MEM_SPRITE_PALETTE; - target.tileMap = MEM_SPRITE_TILES; - oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); - // load external palette if available - if (paletteAddr) { - oxRequire(palStat, ctx.rom().stat(paletteAddr)); - oxRequire(pal, rom.directAccess(paletteAddr)); - oxReturnError(ox::readMC(pal, static_cast(palStat.size), &target.pal)); - } - return {}; -} - -ox::Error loadBgPalette(Context &ctx, unsigned, ox::FileAddress const&paletteAddr) noexcept { - auto &rom = ctx.rom(); - GbaPaletteTarget target; - target.palette = MEM_BG_PALETTE; - oxRequire(palStat, ctx.rom().stat(paletteAddr)); - oxRequire(pal, rom.directAccess(paletteAddr)); - oxReturnError(ox::readMC(pal, static_cast(palStat.size), &target)); - return {}; -} - -ox::Error loadSpritePalette(Context &ctx, unsigned cbb, ox::FileAddress const&paletteAddr) noexcept { - auto &rom = ctx.rom(); - GbaPaletteTarget target; - target.palette = &MEM_SPRITE_PALETTE[cbb]; - oxRequire(palStat, rom.stat(paletteAddr)); - oxRequire(pal, rom.directAccess(paletteAddr)); - oxReturnError(ox::readMC(pal, static_cast(palStat.size), &target)); - return {}; -} - -ox::Error initConsole(Context &ctx) noexcept { - constexpr ox::FileAddress TilesheetAddr = ox::StringLiteral("/TileSheets/Charset.ng"); - constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal"); - setBgStatus(ctx, 0b0001); - oxReturnError(loadBgTileSheet(ctx, 0, TilesheetAddr, PaletteAddr)); - setBgCbb(ctx, 0, 0); - return {}; -} - -void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept { - const auto col = static_cast(column); - for (auto i = 0u; i < str.bytes(); i++) { - const auto c = charMap[static_cast(str[i])]; - setTile(ctx, 0, static_cast(col + i), row, static_cast(c)); - } -} - -void setTile(Context&, unsigned bgIdx, int column, int row, uint8_t tile) noexcept { - const auto tileIdx = static_cast(row * GbaTileColumns + column); - MEM_BG_MAP[bgIdx][tileIdx] = tile; -} - -// Do NOT use Context in the GBA version of this function. -void clearTileLayer(Context&, unsigned bgIdx) noexcept { - memset(MEM_BG_MAP[bgIdx].data(), 0, GbaTileRows * GbaTileColumns); -} - -[[maybe_unused]] void hideSprite(Context&, unsigned idx) noexcept { //oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); teagba::addSpriteUpdate({ @@ -222,7 +193,6 @@ void hideSprite(Context&, unsigned idx) noexcept { }); } -[[maybe_unused]] void showSprite(Context&, unsigned idx) noexcept { //oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); teagba::addSpriteUpdate({ @@ -249,4 +219,8 @@ void setSprite(Context&, uint_t idx, Sprite const&s) noexcept { }); } +uint_t spriteCount(Context&) noexcept { + return 128; +} + } diff --git a/src/nostalgia/modules/core/src/gba/panic.cpp b/src/nostalgia/modules/core/src/gba/panic.cpp index 33bd7425..1b0b36b3 100644 --- a/src/nostalgia/modules/core/src/gba/panic.cpp +++ b/src/nostalgia/modules/core/src/gba/panic.cpp @@ -31,7 +31,7 @@ void panic(const char *file, int line, const char *panicMsg, ox::Error const&err oxIgnoreError(initGfx(*ctx, {})); oxIgnoreError(initConsole(*ctx)); setBgStatus(*ctx, 0, true); - clearTileLayer(*ctx, 0); + clearBg(*ctx, 0); ox::BString<23> serr = "Error code: "; serr += static_cast(err); puts(*ctx, 32 + 1, 1, "SADNESS..."); diff --git a/src/nostalgia/modules/core/src/gfx.cpp b/src/nostalgia/modules/core/src/gfx.cpp index d4204fb9..db44ed66 100644 --- a/src/nostalgia/modules/core/src/gfx.cpp +++ b/src/nostalgia/modules/core/src/gfx.cpp @@ -7,7 +7,7 @@ namespace nostalgia::core { // map ASCII values to the nostalgia charset -ox::Array charMap = { +constexpr ox::Array charMap = { 0, 0, 0, @@ -137,4 +137,29 @@ ox::Array charMap = { 50, // ~ }; +ox::Error initConsole(Context &ctx) noexcept { + constexpr ox::FileAddress TilesheetAddr = ox::StringLiteral("/TileSheets/Charset.ng"); + constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal"); + setBgStatus(ctx, 0b0001); + setBgCbb(ctx, 0, 0); + oxReturnError(loadBgTileSheet(ctx, 0, TilesheetAddr)); + return loadBgPalette(ctx, PaletteAddr); +} + +void puts( + Context &ctx, + int const column, + int const row, + ox::CRStringView str) noexcept { + auto const col = static_cast(column); + for (auto i = 0u; i < str.bytes(); ++i) { + setBgTile( + ctx, + 0, + static_cast(col + i), + row, + static_cast(charMap[static_cast(str[i])])); + } +} + } diff --git a/src/nostalgia/modules/core/src/opengl/gfx.cpp b/src/nostalgia/modules/core/src/opengl/gfx.cpp index cffb3469..2872e7a3 100644 --- a/src/nostalgia/modules/core/src/opengl/gfx.cpp +++ b/src/nostalgia/modules/core/src/opengl/gfx.cpp @@ -19,11 +19,11 @@ namespace nostalgia::core { +namespace renderer { + constexpr auto Scale = 1; constexpr auto PriorityScale = 0.01f; -namespace renderer { - Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {} void Drawer::draw(turbine::Context &tctx) noexcept { @@ -98,7 +98,7 @@ constexpr ox::CStringView spritefshadTmpl = R"glsl( if (outColor.a == 0) { discard; } - })glsl";; + })glsl"; [[nodiscard]] static constexpr auto bgVertexRow(uint_t x, uint_t y) noexcept { @@ -338,8 +338,7 @@ static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept { static void loadPalette( GLuint shaderPgrm, - Palette const&pal, - bool firstIsTransparent) noexcept { + Palette const&pal) noexcept { static constexpr std::size_t ColorCnt = 256; ox::Array palette{}; for (auto i = 0u; const auto c : pal.colors) { @@ -348,41 +347,13 @@ static void loadPalette( palette[i++] = bluef(c); palette[i++] = 255; } - if (firstIsTransparent) { - palette[3] = 0; - } + // make first color transparent + palette[3] = 0; glUseProgram(shaderPgrm); const auto uniformPalette = static_cast(glGetUniformLocation(shaderPgrm, "fPalette")); glUniform4fv(uniformPalette, ColorCnt, palette.data()); } -static void loadBgPalette(Context &ctx, Palette const&pal) noexcept { - loadPalette(ctx.bgShader, pal, true); -} - -static void loadSpritePalette(Context &ctx, Palette const&pal) noexcept { - loadPalette(ctx.spriteShader, pal, true); -} - -static void loadBgTexture( - Context &ctx, - uint_t cbbIdx, - const void *pixels, - int w, - int h) noexcept { - oxTracef("nostalgia.core.gfx.gl", "loadBgTexture: { cbbIdx: {}, w: {}, h: {} }", cbbIdx, w, h); - ctx.cbbs[cbbIdx].tex = createTexture(w, h, pixels); -} - -static void loadSpriteTexture( - Context &ctx, - const void *pixels, - int w, - int h) noexcept { - oxTracef("nostalgia.core.gfx.gl", "loadSpriteTexture: { w: {}, h: {} }", w, h); - ctx.spriteBlocks.tex = createTexture(w, h, pixels); -} - static void setSprite( Context &ctx, uint_t const idx, @@ -493,8 +464,7 @@ struct TileSheetData { } }; -static ox::Result loadTileSheet( - Context &ctx, +static ox::Result normalizeTileSheet( CompactTileSheet const&tilesheet) noexcept { const uint_t bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2; const auto tiles = tilesheet.pixels.size() / bytesPerTile; @@ -513,71 +483,93 @@ static ox::Result loadTileSheet( pixels[i * 2 + 1] = tilesheet.pixels[i] >> 4; } } - renderer::loadSpriteTexture(ctx, pixels.data(), width, height); return TileSheetData{std::move(pixels), width, height}; } +ox::Error loadBgPalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept { + auto &kctx = keelCtx(ctx.turbineCtx); + oxRequire(palette, readObj(kctx, paletteAddr)); + renderer::loadPalette(ctx.bgShader, *palette); + return {}; +} + +ox::Error loadSpritePalette( + Context &ctx, + ox::FileAddress const&paletteAddr) noexcept { + auto &kctx = keelCtx(ctx.turbineCtx); + oxRequire(palette, readObj(kctx, paletteAddr)); + renderer::loadPalette(ctx.spriteShader, *palette); + return {}; +} + ox::Error loadBgTileSheet( Context &ctx, uint_t cbb, ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept { + bool loadDefaultPalette) noexcept { auto &kctx = keelCtx(ctx.turbineCtx); oxRequire(tilesheet, readObj(kctx, tilesheetAddr)); - oxRequire(palette, readObj(kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette)); - oxRequire(tsd, loadTileSheet(ctx, *tilesheet).to([](TileSheetData const&t) -> TileSheetData { - return { - .pixels = resizeTileSheetData(t.pixels, t.size(), Scale), - .width = t.width * Scale, - .height = t.height * Scale, - }; - })); - renderer::loadBgTexture(ctx, cbb, tsd.pixels.data(), tsd.width, tsd.height); - renderer::loadBgPalette(ctx, *palette); + oxRequire(tsd, normalizeTileSheet(*tilesheet)); + 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()); + if (loadDefaultPalette) { + oxReturnError(loadBgPalette(ctx, tilesheet->defaultPalette)); + } return {}; } ox::Error loadSpriteTileSheet( Context &ctx, ox::FileAddress const&tilesheetAddr, - ox::FileAddress const&paletteAddr) noexcept { + bool loadDefaultPalette) noexcept { auto &kctx = keelCtx(ctx.turbineCtx); oxRequire(tilesheet, readObj(kctx, tilesheetAddr)); - oxRequire(palette, readObj(kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette)); - oxRequire(tsd, loadTileSheet(ctx, *tilesheet)); - renderer::loadSpriteTexture(ctx, tsd.pixels.data(), tsd.width, tsd.height); - renderer::loadSpritePalette(ctx, *palette); + oxRequire(tsd, normalizeTileSheet(*tilesheet)); + oxTracef("nostalgia.core.gfx.gl", "loadSpriteTexture: { w: {}, h: {} }", tsd.width, tsd.height); + ctx.spriteBlocks.tex = renderer::createTexture(tsd.width, tsd.height, tsd.pixels.data()); + if (loadDefaultPalette) { + oxReturnError(loadSpritePalette(ctx, tilesheet->defaultPalette)); + } return {}; } -ox::Error initConsole(Context &ctx) noexcept { - constexpr ox::FileAddress TilesheetAddr = ox::StringLiteral("/TileSheets/Charset.ng"); - constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal"); - setBgStatus(ctx, 0b0001); - setBgCbb(ctx, 0, 0); - return loadBgTileSheet(ctx, 0, TilesheetAddr, PaletteAddr); -} - -void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept { - const auto col = static_cast(column); - for (auto i = 0u; i < str.bytes(); ++i) { - setTile( - ctx, - 0, - static_cast(col + i), - row, - static_cast(charMap[static_cast(str[i])])); - } -} - -void setBgCbb(Context &ctx, uint_t bgIdx, uint_t cbbIdx) noexcept { +void setBgTile( + Context &ctx, + uint_t bgIdx, + int column, + int row, + uint8_t tile) noexcept { + oxTracef( + "nostalgia.core.gfx.setBgTile", + "bgIdx: {}, column: {}, row: {}, tile: {}", + bgIdx, column, row, tile); + const auto z = static_cast(bgIdx); + const auto y = static_cast(row); + const auto x = static_cast(column); + const auto i = renderer::bgVertexRow(x, y); + auto &cbb = ctx.cbbs[z]; + const auto vbo = &cbb.vertices[i * renderer::BgVertexVboLength]; + const auto ebo = &cbb.elements[i * renderer::BgVertexEboLength]; auto &bg = ctx.backgrounds[bgIdx]; - bg.cbbIdx = cbbIdx; + renderer::setTileBufferObject( + static_cast(i * renderer::BgVertexVboRows), + static_cast(x), + static_cast(y), + static_cast(tile), + bg.priority, + vbo, + ebo); + cbb.updated = true; } -void setBgPriority(Context &ctx, uint_t bgIdx, uint_t priority) noexcept { - auto &bg = ctx.backgrounds[bgIdx]; - bg.priority = static_cast(priority & 0b11); +void clearBg(Context &ctx, uint_t bgIdx) noexcept { + auto &cbb = ctx.cbbs[static_cast(bgIdx)]; + initBackgroundBufferObjects(cbb); + cbb.updated = true; + auto &bg = ctx.backgrounds[static_cast(bgIdx)]; + bg.priority = 0; } uint8_t bgStatus(Context &ctx) noexcept { @@ -602,13 +594,14 @@ void setBgStatus(Context &ctx, uint_t bg, bool status) noexcept { ctx.backgrounds[bg].enabled = status; } +void setBgCbb(Context &ctx, uint_t bgIdx, uint_t cbbIdx) noexcept { + auto &bg = ctx.backgrounds[bgIdx]; + bg.cbbIdx = cbbIdx; +} -void clearTileLayer(Context &ctx, uint_t bgIdx) noexcept { - auto &cbb = ctx.cbbs[static_cast(bgIdx)]; - initBackgroundBufferObjects(cbb); - cbb.updated = true; - auto &bg = ctx.backgrounds[static_cast(bgIdx)]; - bg.priority = 0; +void setBgPriority(Context &ctx, uint_t bgIdx, uint_t priority) noexcept { + auto &bg = ctx.backgrounds[bgIdx]; + bg.priority = static_cast(priority & 0b11); } void hideSprite(Context &ctx, uint_t idx) noexcept { @@ -629,33 +622,8 @@ void setSprite(Context &ctx, uint_t idx, Sprite const&sprite) noexcept { renderer::setSprite(ctx, idx, s); } -void setTile( - Context &ctx, - uint_t bgIdx, - int column, - int row, - uint8_t tile) noexcept { - oxTracef( - "nostalgia.core.gfx.setTile", - "bgIdx: {}, column: {}, row: {}, tile: {}", - bgIdx, column, row, tile); - const auto z = static_cast(bgIdx); - const auto y = static_cast(row); - const auto x = static_cast(column); - const auto i = renderer::bgVertexRow(x, y); - auto &cbb = ctx.cbbs[z]; - const auto vbo = &cbb.vertices[i * renderer::BgVertexVboLength]; - const auto ebo = &cbb.elements[i * renderer::BgVertexEboLength]; - auto &bg = ctx.backgrounds[bgIdx]; - renderer::setTileBufferObject( - static_cast(i * renderer::BgVertexVboRows), - static_cast(x), - static_cast(y), - static_cast(tile), - bg.priority, - vbo, - ebo); - cbb.updated = true; +uint_t spriteCount(Context &ctx) noexcept { + return ctx.spriteCount; } namespace gl { diff --git a/src/nostalgia/modules/scene/src/scene.cpp b/src/nostalgia/modules/scene/src/scene.cpp index c7efe557..46ec2f83 100644 --- a/src/nostalgia/modules/scene/src/scene.cpp +++ b/src/nostalgia/modules/scene/src/scene.cpp @@ -17,8 +17,8 @@ ox::Error Scene::setupDisplay(core::Context &ctx) const noexcept { return OxError(1, "Scene has no palettes"); } auto const&palette = m_sceneStatic.palettes[0]; - oxReturnError(core::loadBgTileSheet( - ctx, 0, m_sceneStatic.tilesheet, palette)); + oxReturnError(core::loadBgTileSheet(ctx, 0, m_sceneStatic.tilesheet)); + oxReturnError(core::loadBgPalette(ctx, palette)); // disable all backgrounds core::setBgStatus(ctx, 0); for (auto layerNo = 0u; auto const&layer : m_sceneStatic.tileMapIdx) { @@ -39,10 +39,10 @@ void Scene::setupLayer( const auto width = m_sceneStatic.rows[layerNo]; for (auto const&tile : layer) { const auto tile8 = static_cast(tile); - core::setTile(ctx, layerNo, x, y, tile8); - core::setTile(ctx, layerNo, x + 1, y, tile8 + 1); - core::setTile(ctx, layerNo, x, y + 1, tile8 + 2); - core::setTile(ctx, layerNo, x + 1, y + 1, tile8 + 3); + core::setBgTile(ctx, layerNo, x, y, tile8); + core::setBgTile(ctx, layerNo, x + 1, y, tile8 + 1); + core::setBgTile(ctx, layerNo, x, y + 1, tile8 + 2); + core::setBgTile(ctx, layerNo, x + 1, y + 1, tile8 + 3); x += 2; if (x >= width * 2) { x = 0; diff --git a/src/nostalgia/player/app.cpp b/src/nostalgia/player/app.cpp index 012ba6c4..e1ca6b57 100644 --- a/src/nostalgia/player/app.cpp +++ b/src/nostalgia/player/app.cpp @@ -14,25 +14,6 @@ static int spriteX{}; static int spriteY{}; static bool s_paused = false; -static int sceneUpdateHandler(turbine::Context&) noexcept { - constexpr auto sleepTime = 16; - if (s_paused) { - return sleepTime; - } - // do stuff - return sleepTime; -} - -static void sceneKeyEventHandler(turbine::Context &tctx, turbine::Key key, bool down) noexcept { - if (down) { - if (key == turbine::Key::Alpha_Q) { - turbine::requestShutdown(tctx); - } else if (key == turbine::Key::Alpha_P) { - s_paused = !s_paused; - } - } -} - [[maybe_unused]] static int testUpdateHandler(turbine::Context &tctx) noexcept { auto &cctx = *turbine::applicationData(tctx); @@ -82,7 +63,6 @@ static void testKeyEventHandler(turbine::Context &tctx, turbine::Key key, bool d } } - [[maybe_unused]] static ox::Error runTest(turbine::Context &tctx) { constexpr ox::FileAddress TileSheetAddr = ox::StringLiteral("/TileSheets/Charset.ng"); @@ -90,7 +70,8 @@ static ox::Error runTest(turbine::Context &tctx) { oxRequireM(cctx, core::init(tctx)); turbine::setApplicationData(tctx, cctx.get()); oxRequire(tsStat, turbine::rom(tctx)->stat(PaletteAddr)); - oxReturnError(core::loadSpriteTileSheet(*cctx, TileSheetAddr, PaletteAddr)); + oxReturnError(core::loadSpriteTileSheet(*cctx, TileSheetAddr)); + oxReturnError(core::loadSpritePalette(*cctx, PaletteAddr)); oxReturnError(core::initConsole(*cctx)); core::puts(*cctx, 10, 9, "DOPENESS!!!"); turbine::setUpdateHandler(tctx, testUpdateHandler); @@ -101,6 +82,26 @@ static ox::Error runTest(turbine::Context &tctx) { return turbine::run(tctx); } + +static int sceneUpdateHandler(turbine::Context&) noexcept { + constexpr auto sleepTime = 16; + if (s_paused) { + return sleepTime; + } + // do stuff + return sleepTime; +} + +static void sceneKeyEventHandler(turbine::Context &tctx, turbine::Key key, bool down) noexcept { + if (down) { + if (key == turbine::Key::Alpha_Q) { + turbine::requestShutdown(tctx); + } else if (key == turbine::Key::Alpha_P) { + s_paused = !s_paused; + } + } +} + [[maybe_unused]] static ox::Error runScene(turbine::Context &tctx) { constexpr ox::FileAddress SceneAddr = ox::StringLiteral("/Scenes/Chester.nscn");