[jasper/world] Add world background animation
All checks were successful
Build / build (push) Successful in 3m15s
All checks were successful
Build / build (push) Successful in 3m15s
This commit is contained in:
parent
79d7f76407
commit
e861b4f6e7
@ -16,15 +16,19 @@ namespace ncore = nostalgia::core;
|
|||||||
|
|
||||||
class World {
|
class World {
|
||||||
private:
|
private:
|
||||||
|
ncore::Context &m_nctx;
|
||||||
|
ox::Vector<keel::AssetRef<ncore::CompactPalette>, 10> m_palettes;
|
||||||
WorldStatic const&m_worldStatic;
|
WorldStatic const&m_worldStatic;
|
||||||
|
|
||||||
public:
|
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<int> update() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupLayer(ncore::Context&, uint_t lyr, uint_t cbb) const noexcept;
|
void setupLayer(uint_t lyr, uint_t cbb) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace jasper::world {
|
|||||||
WorldEditorView::WorldEditorView(turbine::Context &tctx, WorldStatic const&worldStatic):
|
WorldEditorView::WorldEditorView(turbine::Context &tctx, WorldStatic const&worldStatic):
|
||||||
m_cctx(ncore::init(tctx, {.glInstallDrawer = false}).unwrapThrow()),
|
m_cctx(ncore::init(tctx, {.glInstallDrawer = false}).unwrapThrow()),
|
||||||
m_worldStatic(worldStatic),
|
m_worldStatic(worldStatic),
|
||||||
m_world(m_worldStatic) {
|
m_world(*m_cctx, m_worldStatic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error WorldEditorView::setupWorld() noexcept {
|
ox::Error WorldEditorView::setupWorld() noexcept {
|
||||||
@ -22,7 +22,7 @@ ox::Error WorldEditorView::setupWorld() noexcept {
|
|||||||
m_rows = m_worldStatic.rows;
|
m_rows = m_worldStatic.rows;
|
||||||
m_selection.reset();
|
m_selection.reset();
|
||||||
}
|
}
|
||||||
return m_world.setupDisplay(*m_cctx);
|
return m_world.setupDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldEditorView::draw(ox::Size const&targetSz) noexcept {
|
void WorldEditorView::draw(ox::Size const&targetSz) noexcept {
|
||||||
|
@ -2,60 +2,65 @@
|
|||||||
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <keel/keel.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/core/gfx.hpp>
|
||||||
|
|
||||||
#include <jasper/world/world.hpp>
|
#include <jasper/world/world.hpp>
|
||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
World::World(WorldStatic const&worldStatic) noexcept:
|
World::World(ncore::Context &nctx, WorldStatic const&worldStatic) noexcept:
|
||||||
|
m_nctx(nctx),
|
||||||
m_worldStatic(worldStatic) {
|
m_worldStatic(worldStatic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error World::setupDisplay(ncore::Context &ctx) const noexcept {
|
ox::Error World::setupDisplay() noexcept {
|
||||||
if (m_worldStatic.palettes.empty()) {
|
if (m_worldStatic.palettes.empty()) {
|
||||||
return OxError(1, "World has no palettes");
|
return OxError(1, "World has no palettes");
|
||||||
}
|
}
|
||||||
|
m_palettes.clear();
|
||||||
for (auto i = 0u; auto const&pal : m_worldStatic.palettes) {
|
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<ncore::CompactPalette>(keelCtx(m_nctx), pal.palette).moveTo(palRef));
|
||||||
|
oxReturnError(ncore::loadBgPalette(m_nctx, i, *palRef));
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
oxReturnError(ncore::loadBgTileSheet(ctx, 0, m_worldStatic.tilesheets));
|
oxReturnError(ncore::loadBgTileSheet(m_nctx, 0, m_worldStatic.tilesheets));
|
||||||
ncore::setBgStatus(ctx, 0); // disable all backgrounds
|
ncore::setBgStatus(m_nctx, 0); // disable all backgrounds
|
||||||
for (auto layerNo = 0u; auto const&layer : m_worldStatic.map) {
|
for (auto layerNo = 0u; auto const&layer : m_worldStatic.map) {
|
||||||
setupLayer(ctx, layerNo, layer.cbb);
|
setupLayer(layerNo, layer.cbb);
|
||||||
++layerNo;
|
++layerNo;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::setupLayer(
|
void World::setupLayer(
|
||||||
ncore::Context &ctx,
|
|
||||||
uint_t lyr,
|
uint_t lyr,
|
||||||
uint_t cbb) const noexcept {
|
uint_t cbb) const noexcept {
|
||||||
ncore::clearBg(ctx, lyr);
|
ncore::clearBg(m_nctx, lyr);
|
||||||
ncore::setBgStatus(ctx, lyr, true);
|
ncore::setBgStatus(m_nctx, lyr, true);
|
||||||
ncore::setBgCbb(ctx, lyr, cbb);
|
ncore::setBgCbb(m_nctx, lyr, cbb);
|
||||||
auto const rows = ox::min<int>(m_worldStatic.rows, ncore::tileRows(ctx) / 2);
|
auto const rows = ox::min<int>(m_worldStatic.rows, ncore::tileRows(m_nctx) / 2);
|
||||||
auto const columns = ox::min<int>(m_worldStatic.columns, ncore::tileColumns(ctx) / 2);
|
auto const columns = ox::min<int>(m_worldStatic.columns, ncore::tileColumns(m_nctx) / 2);
|
||||||
for (auto y = 0; y < rows; ++y) {
|
for (auto y = 0; y < rows; ++y) {
|
||||||
for (auto x = 0; x < columns; ++x) {
|
for (auto x = 0; x < columns; ++x) {
|
||||||
auto &t = tile(m_worldStatic, lyr, x, y);
|
auto &t = tile(m_worldStatic, lyr, x, y);
|
||||||
auto const tx = x * 2;
|
auto const tx = x * 2;
|
||||||
auto const ty = y * 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<uint_t>(t.tileIdx + 0),
|
.tileIdx = static_cast<uint_t>(t.tileIdx + 0),
|
||||||
.palBank = t.palBank,
|
.palBank = t.palBank,
|
||||||
});
|
});
|
||||||
ncore::setBgTile(ctx, lyr, tx + 1, ty + 0, {
|
ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 0, {
|
||||||
.tileIdx = static_cast<uint_t>(t.tileIdx + 1),
|
.tileIdx = static_cast<uint_t>(t.tileIdx + 1),
|
||||||
.palBank = t.palBank,
|
.palBank = t.palBank,
|
||||||
});
|
});
|
||||||
ncore::setBgTile(ctx, lyr, tx + 0, ty + 1, {
|
ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 1, {
|
||||||
.tileIdx = static_cast<uint_t>(t.tileIdx + 2),
|
.tileIdx = static_cast<uint_t>(t.tileIdx + 2),
|
||||||
.palBank = t.palBank,
|
.palBank = t.palBank,
|
||||||
});
|
});
|
||||||
ncore::setBgTile(ctx, lyr, tx + 1, ty + 1, {
|
ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 1, {
|
||||||
.tileIdx = static_cast<uint_t>(t.tileIdx + 3),
|
.tileIdx = static_cast<uint_t>(t.tileIdx + 3),
|
||||||
.palBank = t.palBank,
|
.palBank = t.palBank,
|
||||||
});
|
});
|
||||||
@ -63,4 +68,15 @@ void World::setupLayer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Result<int> 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<size_t>(page)));
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,18 @@ ox::Error run(turbine::Context &tctx, ox::StringView, ox::SpanView<ox::String> a
|
|||||||
oxRequire(nctx, ncore::init(tctx));
|
oxRequire(nctx, ncore::init(tctx));
|
||||||
auto const&worldPath = args[0];
|
auto const&worldPath = args[0];
|
||||||
oxRequire(worldStatic, readObj<world::WorldStatic>(keelCtx(tctx), worldPath));
|
oxRequire(worldStatic, readObj<world::WorldStatic>(keelCtx(tctx), worldPath));
|
||||||
world::World const world(*worldStatic);
|
world::World world(*nctx, *worldStatic);
|
||||||
oxReturnError(world.setupDisplay(*nctx));
|
oxReturnError(world.setupDisplay());
|
||||||
|
turbine::setApplicationData(tctx, &world);
|
||||||
|
setUpdateHandler(tctx, [](turbine::Context &tctx) -> int {
|
||||||
|
auto const&world = *applicationData<world::World>(tctx);
|
||||||
|
auto [sleepTime, err] = world.update();
|
||||||
|
if (err) {
|
||||||
|
oxDebugf("error: {}", toStr(err));
|
||||||
|
oxLogError(err);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
oxReturnError(turbine::run(tctx));
|
oxReturnError(turbine::run(tctx));
|
||||||
oxOut("Exiting...\n");
|
oxOut("Exiting...\n");
|
||||||
return {};
|
return {};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user