diff --git a/src/jasper/modules/world/include/jasper/world/world.hpp b/src/jasper/modules/world/include/jasper/world/world.hpp index 3b745c3..5463733 100644 --- a/src/jasper/modules/world/include/jasper/world/world.hpp +++ b/src/jasper/modules/world/include/jasper/world/world.hpp @@ -16,15 +16,19 @@ namespace ncore = nostalgia::core; class World { private: + ncore::Context &m_nctx; + ox::Vector, 10> m_palettes; WorldStatic const&m_worldStatic; public: - explicit World(WorldStatic const&worldStatic) noexcept; + explicit World(ncore::Context &nctx, WorldStatic const&worldStatic) noexcept; - ox::Error setupDisplay(ncore::Context &ctx) const noexcept; + ox::Error setupDisplay() noexcept; + + ox::Result update() const noexcept; private: - void setupLayer(ncore::Context&, uint_t lyr, uint_t cbb) const noexcept; + void setupLayer(uint_t lyr, uint_t cbb) const noexcept; }; diff --git a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp index 447110d..8155e85 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp +++ b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp @@ -11,7 +11,7 @@ namespace jasper::world { WorldEditorView::WorldEditorView(turbine::Context &tctx, WorldStatic const&worldStatic): m_cctx(ncore::init(tctx, {.glInstallDrawer = false}).unwrapThrow()), m_worldStatic(worldStatic), - m_world(m_worldStatic) { + m_world(*m_cctx, m_worldStatic) { } ox::Error WorldEditorView::setupWorld() noexcept { @@ -22,7 +22,7 @@ ox::Error WorldEditorView::setupWorld() noexcept { m_rows = m_worldStatic.rows; m_selection.reset(); } - return m_world.setupDisplay(*m_cctx); + return m_world.setupDisplay(); } void WorldEditorView::draw(ox::Size const&targetSz) noexcept { diff --git a/src/jasper/modules/world/src/world.cpp b/src/jasper/modules/world/src/world.cpp index d4eb17f..8a6a326 100644 --- a/src/jasper/modules/world/src/world.cpp +++ b/src/jasper/modules/world/src/world.cpp @@ -2,60 +2,65 @@ * Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. */ +#include + #include #include namespace jasper::world { -World::World(WorldStatic const&worldStatic) noexcept: +World::World(ncore::Context &nctx, WorldStatic const&worldStatic) noexcept: + m_nctx(nctx), m_worldStatic(worldStatic) { } -ox::Error World::setupDisplay(ncore::Context &ctx) const noexcept { +ox::Error World::setupDisplay() noexcept { if (m_worldStatic.palettes.empty()) { return OxError(1, "World has no palettes"); } + m_palettes.clear(); for (auto i = 0u; auto const&pal : m_worldStatic.palettes) { - oxReturnError(ncore::loadBgPalette(ctx, i, pal.palette)); + auto &palRef = m_palettes.emplace_back(); + oxReturnError(readObj(keelCtx(m_nctx), pal.palette).moveTo(palRef)); + oxReturnError(ncore::loadBgPalette(m_nctx, i, *palRef)); ++i; } - oxReturnError(ncore::loadBgTileSheet(ctx, 0, m_worldStatic.tilesheets)); - ncore::setBgStatus(ctx, 0); // disable all backgrounds + oxReturnError(ncore::loadBgTileSheet(m_nctx, 0, m_worldStatic.tilesheets)); + ncore::setBgStatus(m_nctx, 0); // disable all backgrounds for (auto layerNo = 0u; auto const&layer : m_worldStatic.map) { - setupLayer(ctx, layerNo, layer.cbb); + setupLayer(layerNo, layer.cbb); ++layerNo; } return {}; } void World::setupLayer( - ncore::Context &ctx, uint_t lyr, uint_t cbb) const noexcept { - ncore::clearBg(ctx, lyr); - ncore::setBgStatus(ctx, lyr, true); - ncore::setBgCbb(ctx, lyr, cbb); - auto const rows = ox::min(m_worldStatic.rows, ncore::tileRows(ctx) / 2); - auto const columns = ox::min(m_worldStatic.columns, ncore::tileColumns(ctx) / 2); + ncore::clearBg(m_nctx, lyr); + ncore::setBgStatus(m_nctx, lyr, true); + ncore::setBgCbb(m_nctx, lyr, cbb); + auto const rows = ox::min(m_worldStatic.rows, ncore::tileRows(m_nctx) / 2); + auto const columns = ox::min(m_worldStatic.columns, ncore::tileColumns(m_nctx) / 2); for (auto y = 0; y < rows; ++y) { for (auto x = 0; x < columns; ++x) { auto &t = tile(m_worldStatic, lyr, x, y); auto const tx = x * 2; auto const ty = y * 2; - ncore::setBgTile(ctx, lyr, tx + 0, ty + 0, { + ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 0, { .tileIdx = static_cast(t.tileIdx + 0), .palBank = t.palBank, }); - ncore::setBgTile(ctx, lyr, tx + 1, ty + 0, { + ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 0, { .tileIdx = static_cast(t.tileIdx + 1), .palBank = t.palBank, }); - ncore::setBgTile(ctx, lyr, tx + 0, ty + 1, { + ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 1, { .tileIdx = static_cast(t.tileIdx + 2), .palBank = t.palBank, }); - ncore::setBgTile(ctx, lyr, tx + 1, ty + 1, { + ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 1, { .tileIdx = static_cast(t.tileIdx + 3), .palBank = t.palBank, }); @@ -63,4 +68,15 @@ void World::setupLayer( } } +ox::Result World::update() const noexcept { + auto const time = ticksMs(turbineCtx(m_nctx)); + for (size_t i = 0; auto const&pal : m_palettes) { + auto const interval = m_worldStatic.palettes[i].intervalMs; + auto const page = (time / interval) % pal->pages.size(); + oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal, static_cast(page))); + ++i; + } + return -1; +} + } diff --git a/src/jasper/player/app.cpp b/src/jasper/player/app.cpp index 3a3b7ce..36c3a02 100644 --- a/src/jasper/player/app.cpp +++ b/src/jasper/player/app.cpp @@ -21,8 +21,18 @@ ox::Error run(turbine::Context &tctx, ox::StringView, ox::SpanView a oxRequire(nctx, ncore::init(tctx)); auto const&worldPath = args[0]; oxRequire(worldStatic, readObj(keelCtx(tctx), worldPath)); - world::World const world(*worldStatic); - oxReturnError(world.setupDisplay(*nctx)); + world::World world(*nctx, *worldStatic); + oxReturnError(world.setupDisplay()); + turbine::setApplicationData(tctx, &world); + setUpdateHandler(tctx, [](turbine::Context &tctx) -> int { + auto const&world = *applicationData(tctx); + auto [sleepTime, err] = world.update(); + if (err) { + oxDebugf("error: {}", toStr(err)); + oxLogError(err); + } + return 0; + }); oxReturnError(turbine::run(tctx)); oxOut("Exiting...\n"); return {};