diff --git a/src/nostalgia/modules/core/include/nostalgia/core/context.hpp b/src/nostalgia/modules/core/include/nostalgia/core/context.hpp index 8efa2756..27024123 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/context.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/context.hpp @@ -15,19 +15,15 @@ namespace nostalgia::core { -// User Input Output -class Context { - - public: - Context() noexcept = default; - Context(Context &other) noexcept = delete; - Context(Context const&other) noexcept = delete; - Context(Context const&&other) noexcept = delete; - virtual ~Context() noexcept = default; +class Context; +struct ContextDeleter { + void operator()(Context *p) noexcept; }; -ox::Result> init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; +using ContextUPtr = ox::UPtr; + +ox::Result init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; } diff --git a/src/nostalgia/modules/core/src/gba/context.cpp b/src/nostalgia/modules/core/src/gba/context.cpp index dec6c390..eefa51f8 100644 --- a/src/nostalgia/modules/core/src/gba/context.cpp +++ b/src/nostalgia/modules/core/src/gba/context.cpp @@ -8,15 +8,19 @@ namespace nostalgia::core { -GbaContext::GbaContext(turbine::Context &tctx) noexcept: turbineCtx(tctx) { +void ContextDeleter::operator()(Context *p) noexcept { + ox::safeDelete(p); +} + +Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx) { } ox::Error initGfx(Context &ctx, InitParams const&) noexcept; -ox::Result> init(turbine::Context &tctx, InitParams const¶ms) noexcept { - auto ctx = ox::make_unique(tctx); +ox::Result init(turbine::Context &tctx, InitParams const¶ms) noexcept { + auto ctx = ox::make_unique(tctx); oxReturnError(initGfx(*ctx, params)); - return ox::UPtr(std::move(ctx)); + return ContextUPtr(std::move(ctx)); } } \ No newline at end of file diff --git a/src/nostalgia/modules/core/src/gba/context.hpp b/src/nostalgia/modules/core/src/gba/context.hpp index 5661eaf9..149e56d7 100644 --- a/src/nostalgia/modules/core/src/gba/context.hpp +++ b/src/nostalgia/modules/core/src/gba/context.hpp @@ -8,16 +8,21 @@ namespace nostalgia::core { -struct GbaContext: public core::Context { +class Context { - turbine::Context &turbineCtx; + public: + turbine::Context &turbineCtx; - explicit GbaContext(turbine::Context &tctx) noexcept; + explicit Context(turbine::Context &tctx) noexcept; + Context(Context &other) noexcept = delete; + Context(Context const&other) noexcept = delete; + Context(Context const&&other) noexcept = delete; + virtual ~Context() noexcept = default; - [[nodiscard]] - ox::MemFS const&rom() const noexcept { - return static_cast(*turbine::rom(turbineCtx)); - } + [[nodiscard]] + ox::MemFS const&rom() const noexcept { + return static_cast(*turbine::rom(turbineCtx)); + } }; diff --git a/src/nostalgia/modules/core/src/gba/gfx.cpp b/src/nostalgia/modules/core/src/gba/gfx.cpp index e684eb2f..5119c92c 100644 --- a/src/nostalgia/modules/core/src/gba/gfx.cpp +++ b/src/nostalgia/modules/core/src/gba/gfx.cpp @@ -141,8 +141,7 @@ ox::Error loadBgTileSheet( unsigned cbb, ox::FileAddress const&tilesheetAddr, ox::FileAddress const&paletteAddr) noexcept { - auto &gctx = static_cast(ctx); - auto &rom = gctx.rom(); + auto &rom = ctx.rom(); return loadBgTileSheet(rom, cbb, tilesheetAddr, paletteAddr); } @@ -150,9 +149,8 @@ ox::Error loadSpriteTileSheet( Context &ctx, ox::FileAddress const&tilesheetAddr, ox::FileAddress const&paletteAddr) noexcept { - auto &gctx = static_cast(ctx); - auto &rom = gctx.rom(); - oxRequire(tsStat, gctx.rom().stat(tilesheetAddr)); + auto &rom = ctx.rom(); + oxRequire(tsStat, ctx.rom().stat(tilesheetAddr)); oxRequire(ts, rom.directAccess(tilesheetAddr)); GbaTileMapTarget target; target.pal.palette = MEM_SPRITE_PALETTE; @@ -160,7 +158,7 @@ ox::Error loadSpriteTileSheet( oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); // load external palette if available if (paletteAddr) { - oxRequire(palStat, gctx.rom().stat(paletteAddr)); + oxRequire(palStat, ctx.rom().stat(paletteAddr)); oxRequire(pal, rom.directAccess(paletteAddr)); oxReturnError(ox::readMC(pal, static_cast(palStat.size), &target.pal)); } @@ -168,19 +166,17 @@ ox::Error loadSpriteTileSheet( } ox::Error loadBgPalette(Context &ctx, unsigned, ox::FileAddress const&paletteAddr) noexcept { - auto &gctx = static_cast(ctx); - auto &rom = gctx.rom(); + auto &rom = ctx.rom(); GbaPaletteTarget target; target.palette = MEM_BG_PALETTE; - oxRequire(palStat, gctx.rom().stat(paletteAddr)); + 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 &gctx = static_cast(ctx); - auto &rom = gctx.rom(); + auto &rom = ctx.rom(); GbaPaletteTarget target; target.palette = &MEM_SPRITE_PALETTE[cbb]; oxRequire(palStat, rom.stat(paletteAddr)); diff --git a/src/nostalgia/modules/core/src/opengl/CMakeLists.txt b/src/nostalgia/modules/core/src/opengl/CMakeLists.txt index 48a0e7fb..060dbb35 100644 --- a/src/nostalgia/modules/core/src/opengl/CMakeLists.txt +++ b/src/nostalgia/modules/core/src/opengl/CMakeLists.txt @@ -6,4 +6,5 @@ target_sources( target_link_libraries( NostalgiaCore PUBLIC GlUtils + lodepng ) diff --git a/src/nostalgia/modules/core/src/opengl/context.cpp b/src/nostalgia/modules/core/src/opengl/context.cpp index 95204232..f9916ed3 100644 --- a/src/nostalgia/modules/core/src/opengl/context.cpp +++ b/src/nostalgia/modules/core/src/opengl/context.cpp @@ -7,19 +7,23 @@ namespace nostalgia::core { -GlContext::GlContext(turbine::Context &tctx) noexcept: +void ContextDeleter::operator()(Context *p) noexcept { + ox::safeDelete(p); +} + +Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx), drawer(*this) { } -GlContext::~GlContext() noexcept { +Context::~Context() noexcept { shutdownGfx(*this); } -ox::Result> init(turbine::Context &tctx, InitParams const¶ms) noexcept { - auto ctx = ox::make_unique(tctx); +ox::Result init(turbine::Context &tctx, InitParams const¶ms) noexcept { + auto ctx = ox::make_unique(tctx); oxReturnError(initGfx(*ctx, params)); - return ox::UPtr(ctx.release()); + return ContextUPtr(ctx.release()); } } diff --git a/src/nostalgia/modules/core/src/opengl/context.hpp b/src/nostalgia/modules/core/src/opengl/context.hpp index 150048e7..d50ad810 100644 --- a/src/nostalgia/modules/core/src/opengl/context.hpp +++ b/src/nostalgia/modules/core/src/opengl/context.hpp @@ -15,17 +15,19 @@ namespace nostalgia::core { -struct GlContext: public core::Context { - turbine::Context &turbineCtx; - glutils::GLProgram bgShader; - glutils::GLProgram spriteShader; - ox::Array cbbs; - renderer::SpriteBlockset spriteBlocks; - ox::Array spriteStates; - ox::Array backgrounds; - renderer::Drawer drawer; - explicit GlContext(turbine::Context &tctx) noexcept; - ~GlContext() noexcept override; +class Context { + + public: + turbine::Context &turbineCtx; + glutils::GLProgram bgShader; + glutils::GLProgram spriteShader; + ox::Array cbbs; + renderer::SpriteBlockset spriteBlocks; + ox::Array spriteStates; + ox::Array backgrounds; + renderer::Drawer drawer; + explicit Context(turbine::Context &tctx) noexcept; + ~Context() noexcept; }; } diff --git a/src/nostalgia/modules/core/src/opengl/gfx.cpp b/src/nostalgia/modules/core/src/opengl/gfx.cpp index 21e5358d..f1492133 100644 --- a/src/nostalgia/modules/core/src/opengl/gfx.cpp +++ b/src/nostalgia/modules/core/src/opengl/gfx.cpp @@ -2,6 +2,8 @@ * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. */ +#include + #include #include #include @@ -21,15 +23,6 @@ namespace nostalgia::core { constexpr auto Scale = 10; -[[nodiscard]] -inline GlContext &glctx(Context &ctx) noexcept { - if constexpr(ox::defines::Debug) { - return dynamic_cast(ctx); - } else { - return static_cast(ctx); - } -} - namespace renderer { Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {} @@ -267,20 +260,20 @@ static void drawBackground(CBB &cbb) noexcept { } static void drawBackgrounds( - GlContext &gctx, + Context &ctx, ox::Size const&renderSz) noexcept { // load background shader and its uniforms - glUseProgram(gctx.bgShader); - const auto uniformSrcImgSz = glGetUniformLocation(gctx.bgShader, "fSrcImgSz"); - const auto uniformXScale = static_cast(glGetUniformLocation(gctx.bgShader, "vXScale")); - const auto uniformTileHeight = static_cast(glGetUniformLocation(gctx.bgShader, "vTileHeight")); + glUseProgram(ctx.bgShader); + const auto uniformSrcImgSz = glGetUniformLocation(ctx.bgShader, "fSrcImgSz"); + const auto uniformXScale = static_cast(glGetUniformLocation(ctx.bgShader, "vXScale")); + const auto uniformTileHeight = static_cast(glGetUniformLocation(ctx.bgShader, "vTileHeight")); const auto [wi, hi] = renderSz; const auto wf = static_cast(wi); const auto hf = static_cast(hi); glUniform1f(uniformXScale, hf / wf); - for (const auto &bg : gctx.backgrounds) { + for (const auto &bg : ctx.backgrounds) { if (bg.enabled) { - auto &cbb = gctx.cbbs[bg.cbbIdx]; + auto &cbb = ctx.cbbs[bg.cbbIdx]; const auto tileRows = cbb.tex.height / (TileHeight * Scale); glUniform1f(uniformTileHeight, 1.0f / static_cast(tileRows)); glUniform2f( @@ -292,11 +285,11 @@ static void drawBackgrounds( } } -static void drawSprites(GlContext &gctx, ox::Size const&renderSz) noexcept { - glUseProgram(gctx.spriteShader); - auto &sb = gctx.spriteBlocks; - const auto uniformXScale = glGetUniformLocation(gctx.bgShader, "vXScale"); - const auto uniformTileHeight = glGetUniformLocation(gctx.spriteShader, "vTileHeight"); +static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept { + glUseProgram(ctx.spriteShader); + auto &sb = ctx.spriteBlocks; + const auto uniformXScale = glGetUniformLocation(ctx.bgShader, "vXScale"); + const auto uniformTileHeight = glGetUniformLocation(ctx.spriteShader, "vTileHeight"); const auto [wi, hi] = renderSz; const auto wf = static_cast(wi); const auto hf = static_cast(hi); @@ -335,31 +328,31 @@ static void loadPalette( glUniform4fv(uniformPalette, ColorCnt, palette.data()); } -static void loadBgPalette(GlContext &gctx, Palette const&pal) noexcept { - loadPalette(gctx.bgShader, pal); +static void loadBgPalette(Context &ctx, Palette const&pal) noexcept { + loadPalette(ctx.bgShader, pal); } -static void loadSpritePalette(GlContext &gctx, Palette const&pal) noexcept { - loadPalette(gctx.spriteShader, pal, true); +static void loadSpritePalette(Context &ctx, Palette const&pal) noexcept { + loadPalette(ctx.spriteShader, pal, true); } static void loadBgTexture( - GlContext &gctx, + 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); - gctx.cbbs[cbbIdx].tex = createTexture(w, h, pixels); + ctx.cbbs[cbbIdx].tex = createTexture(w, h, pixels); } static void loadSpriteTexture( - GlContext &gctx, + Context &ctx, const void *pixels, int w, int h) noexcept { oxTracef("nostalgia.core.gfx.gl", "loadSpriteTexture: { w: {}, h: {} }", w, h); - gctx.spriteBlocks.tex = createTexture(w, h, pixels); + ctx.spriteBlocks.tex = createTexture(w, h, pixels); } } @@ -373,23 +366,21 @@ ox::Error initGfx( const auto bgFshad = ox::sfmt(renderer::bgfshadTmpl, gl::GlslVersion); const auto spriteVshad = ox::sfmt(renderer::spritevshadTmpl, gl::GlslVersion); const auto spriteFshad = ox::sfmt(renderer::spritefshadTmpl, gl::GlslVersion); - auto &gctx = glctx(ctx); - oxReturnError(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(&gctx.bgShader)); + oxReturnError(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(&ctx.bgShader)); oxReturnError( - glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(&gctx.spriteShader)); - for (auto &bg : gctx.cbbs) { - initBackgroundBufferset(gctx.bgShader, bg); + glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(&ctx.spriteShader)); + for (auto &bg : ctx.cbbs) { + initBackgroundBufferset(ctx.bgShader, bg); } - initSpritesBufferset(gctx.spriteShader, gctx.spriteBlocks); + initSpritesBufferset(ctx.spriteShader, ctx.spriteBlocks); if (initParams.glInstallDrawer) { - turbine::gl::addDrawer(gctx.turbineCtx, &gctx.drawer); + turbine::gl::addDrawer(ctx.turbineCtx, &ctx.drawer); } return {}; } void shutdownGfx(Context &ctx) noexcept { - auto &gctx = glctx(ctx); - turbine::gl::removeDrawer(gctx.turbineCtx, &gctx.drawer); + turbine::gl::removeDrawer(ctx.turbineCtx, &ctx.drawer); } struct TileSheetData { @@ -405,7 +396,6 @@ struct TileSheetData { static ox::Result loadTileSheet( Context &ctx, CompactTileSheet const&tilesheet) noexcept { - auto &gctx = glctx(ctx); const uint_t bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2; const auto tiles = tilesheet.pixels.size() / bytesPerTile; constexpr int width = 8; @@ -423,7 +413,7 @@ static ox::Result loadTileSheet( pixels[i * 2 + 1] = tilesheet.pixels[i] >> 4; } } - renderer::loadSpriteTexture(gctx, pixels.data(), width, height); + renderer::loadSpriteTexture(ctx, pixels.data(), width, height); return TileSheetData{std::move(pixels), width, height}; } @@ -432,8 +422,7 @@ ox::Error loadBgTileSheet( uint_t cbb, ox::FileAddress const&tilesheetAddr, ox::FileAddress const&paletteAddr) noexcept { - auto &gctx = glctx(ctx); - auto &kctx = keelCtx(gctx.turbineCtx); + 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 { @@ -443,8 +432,8 @@ ox::Error loadBgTileSheet( .height = t.height * Scale, }; })); - renderer::loadBgTexture(gctx, cbb, tsd.pixels.data(), tsd.width, tsd.height); - renderer::loadBgPalette(gctx, *palette); + renderer::loadBgTexture(ctx, cbb, tsd.pixels.data(), tsd.width, tsd.height); + renderer::loadBgPalette(ctx, *palette); return {}; } @@ -452,13 +441,12 @@ ox::Error loadSpriteTileSheet( Context &ctx, ox::FileAddress const&tilesheetAddr, ox::FileAddress const&paletteAddr) noexcept { - auto &gctx = glctx(ctx); - auto &kctx = keelCtx(gctx.turbineCtx); + 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(gctx, tsd.pixels.data(), tsd.width, tsd.height); - renderer::loadSpritePalette(gctx, *palette); + renderer::loadSpriteTexture(ctx, tsd.pixels.data(), tsd.width, tsd.height); + renderer::loadSpritePalette(ctx, *palette); return {}; } @@ -483,52 +471,45 @@ void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept { } void setBgCbb(Context &ctx, uint_t bgIdx, uint_t cbbIdx) noexcept { - auto &gctx = glctx(ctx); - auto &bg = gctx.backgrounds[bgIdx]; + auto &bg = ctx.backgrounds[bgIdx]; bg.cbbIdx = cbbIdx; } uint8_t bgStatus(Context &ctx) noexcept { - auto const&gctx = glctx(ctx); uint8_t out = 0; - for (uint_t i = 0; i < gctx.cbbs.size(); ++i) { - out |= static_cast(static_cast(gctx.backgrounds[i].enabled) << i); + for (uint_t i = 0; i < ctx.cbbs.size(); ++i) { + out |= static_cast(static_cast(ctx.backgrounds[i].enabled) << i); } return out; } void setBgStatus(Context &ctx, uint32_t status) noexcept { - auto &gctx = glctx(ctx); - for (uint_t i = 0; i < gctx.cbbs.size(); ++i) { - gctx.backgrounds[i].enabled = (status >> i) & 1; + for (uint_t i = 0; i < ctx.cbbs.size(); ++i) { + ctx.backgrounds[i].enabled = (status >> i) & 1; } } bool bgStatus(Context &ctx, uint_t bg) noexcept { - auto const&gctx = glctx(ctx); - return gctx.backgrounds[bg].enabled; + return ctx.backgrounds[bg].enabled; } void setBgStatus(Context &ctx, uint_t bg, bool status) noexcept { - auto &gctx = glctx(ctx); - gctx.backgrounds[bg].enabled = status; + ctx.backgrounds[bg].enabled = status; } void clearTileLayer(Context &ctx, uint_t bgIdx) noexcept { - auto &gctx = glctx(ctx); - auto &bg = gctx.cbbs[static_cast(bgIdx)]; + auto &bg = ctx.cbbs[static_cast(bgIdx)]; initBackgroundBufferObjects(bg); bg.updated = true; } void hideSprite(Context &ctx, uint_t idx) noexcept { - auto &gctx = glctx(ctx); - auto vbo = &gctx.spriteBlocks.vertices[idx * renderer::SpriteVertexVboLength]; - auto ebo = &gctx.spriteBlocks.elements[idx * renderer::SpriteVertexEboLength]; + auto vbo = &ctx.spriteBlocks.vertices[idx * renderer::SpriteVertexVboLength]; + auto ebo = &ctx.spriteBlocks.elements[idx * renderer::SpriteVertexEboLength]; renderer::setSpriteBufferObject( idx * renderer::SpriteVertexVboRows, 0, 0, 0, 0, false, vbo, ebo); - gctx.spriteBlocks.updated = true; + ctx.spriteBlocks.updated = true; } void setSprite( @@ -563,14 +544,13 @@ void setSprite( const auto dim = dimensions[(spriteShape << 2) | spriteSize]; const auto uX = static_cast(x) % 255; const auto uY = static_cast(y + 8) % 255 - 8; - auto &gctx = glctx(ctx); auto i = 0u; const auto set = [&](int xIt, int yIt) { const auto fX = static_cast(uX + xIt * 8) / 8; const auto fY = static_cast(uY + yIt * 8) / 8; const auto cidx = idx + i; - auto vbo = &gctx.spriteBlocks.vertices[cidx * renderer::SpriteVertexVboLength]; - auto ebo = &gctx.spriteBlocks.elements[cidx * renderer::SpriteVertexEboLength]; + auto vbo = &ctx.spriteBlocks.vertices[cidx * renderer::SpriteVertexVboLength]; + auto ebo = &ctx.spriteBlocks.elements[cidx * renderer::SpriteVertexEboLength]; renderer::setSpriteBufferObject( cidx * renderer::SpriteVertexVboRows, 1, @@ -595,7 +575,7 @@ void setSprite( } } } - gctx.spriteBlocks.updated = true; + ctx.spriteBlocks.updated = true; } void setTile( @@ -608,12 +588,11 @@ void setTile( "nostalgia.core.gfx.setTile", "bgIdx: {}, column: {}, row: {}, tile: {}", bgIdx, column, row, tile); - auto &gctx = glctx(ctx); 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 &bg = gctx.cbbs[z]; + auto &bg = ctx.cbbs[z]; const auto vbo = &bg.vertices[i * renderer::BgVertexVboLength]; const auto ebo = &bg.elements[i * renderer::BgVertexEboLength]; renderer::setTileBufferObject( @@ -631,10 +610,9 @@ namespace gl { void draw(core::Context &ctx, ox::Size const&renderSz) noexcept { glViewport(0, 0, renderSz.width, renderSz.height); glutils::clearScreen(); - auto &gctx = glctx(ctx); - renderer::drawBackgrounds(gctx, renderSz); - if (gctx.spriteBlocks.tex) { - renderer::drawSprites(gctx, renderSz); + renderer::drawBackgrounds(ctx, renderSz); + if (ctx.spriteBlocks.tex) { + renderer::drawSprites(ctx, renderSz); } } diff --git a/src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp b/src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp index 66ffa856..46b64a86 100644 --- a/src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp +++ b/src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp @@ -14,7 +14,7 @@ namespace nostalgia::scene { class SceneEditorView { private: - ox::UPtr m_cctx; + core::ContextUPtr m_cctx; SceneStatic const&m_sceneStatic; Scene m_scene; glutils::FrameBuffer m_frameBuffer;