[jasper/world] Remove palette based animation system

This commit is contained in:
2024-06-04 00:25:32 -05:00
parent 97c92cac87
commit 1fc681b23e
26 changed files with 110 additions and 203 deletions

View File

@ -26,7 +26,7 @@ class ObjectCache {
ox::Vector<Obj> objects;
};
ox::Vector<ox::FileAddress> m_tilesheets;
ox::Vector<PaletteCycle> m_palettes;
ox::Vector<ox::FileAddress> m_palettes;
size_t m_tileIdx{};
size_t m_palBank{};
ox::Vector<ObjSet> m_objSets;
@ -42,7 +42,7 @@ class ObjectCache {
[[nodiscard]]
ncore::TileSheetSet const&tilesheets() const noexcept;
[[nodiscard]]
ox::Vector<PaletteCycle> const&palettes() const noexcept;
ox::Vector<ox::FileAddress> const&palettes() const noexcept;
private:
void addTileSheet(ox::FileAddress path, int32_t tiles) noexcept;
};

View File

@ -16,15 +16,10 @@ namespace ncore = nostalgia::core;
class World {
private:
struct PaletteTracker {
keel::AssetRef<ncore::CompactPalette> pal;
int page{};
};
ox::Vector<PaletteTracker, 10> m_palettes;
ncore::Context &m_nctx;
WorldStatic const&m_worldStatic;
#ifndef OX_OS_BareMetal
turbine::TimeMs m_prevUpdateTime{};
//turbine::TimeMs m_prevUpdateTime{};
turbine::TimeMs m_nextUpdateTime{};
#endif

View File

@ -13,19 +13,6 @@ namespace jasper::world {
namespace ncore = nostalgia::core;
struct PaletteCycle {
static constexpr auto TypeName = "net.drinkingtea.jasper.world.PaletteCycle";
static constexpr auto TypeVersion = 1;
ox::FileAddress palette;
uint16_t intervalMs = 1000;
};
oxModelBegin(PaletteCycle)
oxModelField(palette)
oxModelField(intervalMs)
oxModelEnd()
using CollisionMap = uint32_t;
enum class ObjectType: uint8_t {
@ -42,6 +29,7 @@ struct WorldObject {
static constexpr auto TypeVersion = 1;
ObjectId id{};
ox::String name;
uint16_t intervalMs{};
uint16_t palBank{};
ncore::SubSheetId subsheetId{};
CollisionMap collisionMap{};
@ -54,6 +42,7 @@ struct WorldObject {
oxModelBegin(WorldObject)
oxModelField(id)
oxModelField(name)
oxModelFieldRename(intervalMs, interval_ms)
oxModelFieldRename(palBank, pal_bank)
oxModelFieldRename(subsheetId, subsheet_id)
oxModelFieldRename(collisionMap, collision_map)
@ -80,7 +69,7 @@ struct WorldObjectSet {
// index used to assign unique IDs to objects in the set
ObjectId objIdIdx = 0;
ox::FileAddress tilesheet;
ox::Vector<PaletteCycle> palettes;
ox::Vector<ox::FileAddress> palettes;
ox::Vector<WorldObject> objects;
};

View File

@ -91,7 +91,7 @@ struct WorldStatic {
constexpr static auto TypeVersion = 1;
constexpr static auto Preloadable = true;
ncore::TileSheetSet tilesheets;
ox::Vector<PaletteCycle> palettes;
ox::Vector<ox::FileAddress> palettes;
int16_t columns{};
int16_t rows{};
ox::Array<BgLayer, 3> map;

View File

@ -24,7 +24,6 @@ static class: public keel::Module {
[[nodiscard]]
ox::Vector<keel::TypeDescGenerator> types() const noexcept override {
return {
keel::generateTypeDesc<PaletteCycle>,
keel::generateTypeDesc<WorldObjectSet>,
keel::generateTypeDesc<WorldDoc>,
keel::generateTypeDesc<WorldStatic>,

View File

@ -41,7 +41,7 @@ ox::Error ObjectCache::indexSet(
addTileSheet(objSet.tilesheet, static_cast<int32_t>(tileCnt));
for (auto const&pal : objSet.palettes) {
m_palettes.emplace_back(pal);
oxRequire(p, readObj<ncore::Palette>(kctx, pal.palette));
oxRequire(p, readObj<ncore::Palette>(kctx, pal));
m_palBank += largestPage(*p);
}
return {};
@ -65,7 +65,7 @@ ncore::TileSheetSet const&ObjectCache::tilesheets() const noexcept {
return m_tilesheetSet;
}
ox::Vector<PaletteCycle> const&ObjectCache::palettes() const noexcept {
ox::Vector<ox::FileAddress> const&ObjectCache::palettes() const noexcept {
return m_palettes;
}

View File

@ -431,7 +431,7 @@ ox::Error WorldEditorImGui::loadObjectSets() noexcept {
oxRequireM(os, readObj<WorldObjectSet>(kctx, set.path));
oxLogError(addDependency(os->tilesheet));
for (auto const&pal : os->palettes) {
oxLogError(addDependency(pal.palette));
oxLogError(addDependency(pal));
}
m_objSets.emplace_back(ox::String(set.path), set.id, std::move(os));
}

View File

@ -5,7 +5,6 @@ target_sources(
commands/editobject.cpp
commands/addpalette.cpp
commands/rmpalette.cpp
commands/editpalette.cpp
commands/changetilesheet.cpp
collisionmapview.cpp
worldobjectseteditor-imgui.cpp

View File

@ -15,19 +15,19 @@ AddPalette::AddPalette(WorldObjectSet &doc, ox::FileAddress palAddr) noexcept:
}
ox::Error AddPalette::redo() noexcept {
m_doc.palettes.emplace_back(PaletteCycle{
.palette = m_palAddr
});
std::sort(m_doc.palettes.begin(), m_doc.palettes.end(), [](PaletteCycle const&a, PaletteCycle const&b) {
return a.palette.getPath().or_value("") < b.palette.getPath().or_value("");
});
m_doc.palettes.emplace_back(m_palAddr);
std::sort(m_doc.palettes.begin(), m_doc.palettes.end(),
[](ox::FileAddress const&a, ox::FileAddress const&b) {
return a.getPath().or_value("") < b.getPath().or_value("");
});
return {};
}
ox::Error AddPalette::undo() noexcept {
auto const idx = std::find_if(m_doc.palettes.begin(), m_doc.palettes.end(), [this](PaletteCycle const&v) {
return v.palette == m_palAddr;
});
auto const idx = std::find_if(m_doc.palettes.begin(), m_doc.palettes.end(),
[this](ox::FileAddress const&v) {
return v == m_palAddr;
});
return m_doc.palettes.erase(idx).error;
}

View File

@ -11,12 +11,12 @@ enum class WorldObjCommand {
AddObject,
RmObject,
EditObjectName,
EditObjectInterval,
EditObjectPalette,
EditObjectSubSheet,
EditObjectCollisionMap,
AddPalette,
RmPalette,
EditPalette,
ChangeTileSheet,
};

View File

@ -43,6 +43,38 @@ bool EditObjectName::mergeWith(UndoCommand const&cmd) noexcept {
}
EditObjectInterval::EditObjectInterval(WorldObjectSet &doc, size_t objIdx, uint16_t newInterval) noexcept:
m_doc(doc),
m_objIdx(objIdx),
m_oldVal(m_doc.objects[objIdx].intervalMs),
m_newVal(newInterval) {}
ox::Error EditObjectInterval::redo() noexcept {
auto &obj = m_doc.objects[m_objIdx];
obj.intervalMs = m_newVal;
return {};
}
ox::Error EditObjectInterval::undo() noexcept {
auto &obj = m_doc.objects[m_objIdx];
obj.intervalMs = m_oldVal;
return {};
}
int EditObjectInterval::commandId() const noexcept {
return static_cast<int>(WorldObjCommand::EditObjectInterval);
}
bool EditObjectInterval::mergeWith(UndoCommand const&cmd) noexcept {
auto const en = dynamic_cast<EditObjectInterval const*>(&cmd);
if (en && m_objIdx == en->m_objIdx) {
m_newVal = en->m_newVal;
return true;
}
return false;
}
EditObjectSubSheet::EditObjectSubSheet(
WorldObjectSet &doc,
size_t objIdx,

View File

@ -27,6 +27,21 @@ class EditObjectName: public studio::UndoCommand {
bool mergeWith(UndoCommand const&cmd) noexcept override;
};
class EditObjectInterval: public studio::UndoCommand {
private:
WorldObjectSet &m_doc;
size_t const m_objIdx{};
uint16_t const m_oldVal{};
uint16_t m_newVal{};
public:
EditObjectInterval(WorldObjectSet &doc, size_t objIdx, uint16_t newName) noexcept;
ox::Error redo() noexcept override;
ox::Error undo() noexcept override;
[[nodiscard]]
int commandId() const noexcept override;
bool mergeWith(UndoCommand const&cmd) noexcept override;
};
class EditObjectSubSheet: public studio::UndoCommand {
private:
WorldObjectSet &m_doc;

View File

@ -1,30 +0,0 @@
/*
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include "commands.hpp"
#include "editpalette.hpp"
namespace jasper::world {
EditPalette::EditPalette(PaletteCycle &doc, uint16_t interval) noexcept:
m_doc(doc),
m_oldVal(doc.intervalMs),
m_newVal(interval) {
}
ox::Error EditPalette::redo() noexcept {
m_doc.intervalMs = m_newVal;
return {};
}
ox::Error EditPalette::undo() noexcept {
m_doc.intervalMs = m_oldVal;
return {};
}
int EditPalette::commandId() const noexcept {
return static_cast<int>(WorldObjCommand::EditPalette);
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/fs/fs.hpp>
#include <studio/undostack.hpp>
#include <jasper/world/worldobject.hpp>
namespace jasper::world {
class EditPalette: public studio::UndoCommand {
private:
PaletteCycle &m_doc;
uint16_t const m_oldVal{};
uint16_t const m_newVal{};
public:
EditPalette(PaletteCycle &doc, uint16_t interval) noexcept;
ox::Error redo() noexcept override;
ox::Error undo() noexcept override;
[[nodiscard]]
int commandId() const noexcept override;
};
}

View File

@ -22,9 +22,10 @@ ox::Error RmPalette::redo() noexcept {
ox::Error RmPalette::undo() noexcept {
m_doc.palettes.emplace_back(std::move(m_pal));
std::sort(m_doc.palettes.begin(), m_doc.palettes.end(), [](PaletteCycle const&a, PaletteCycle const&b) {
return a.palette.getPath().or_value("") < b.palette.getPath().or_value("");
});
std::sort(m_doc.palettes.begin(), m_doc.palettes.end(),
[](ox::FileAddress const&a, ox::FileAddress const&b) {
return a.getPath().or_value("") < b.getPath().or_value("");
});
return {};
}

View File

@ -15,7 +15,7 @@ namespace jasper::world {
class RmPalette: public studio::UndoCommand {
private:
WorldObjectSet &m_doc;
PaletteCycle m_pal;
ox::FileAddress m_pal;
size_t const m_rmIdx = 0;
public:
RmPalette(WorldObjectSet &doc, size_t rmIdx) noexcept;

View File

@ -9,7 +9,6 @@
#include "commands/editobject.hpp"
#include "commands/addpalette.hpp"
#include "commands/rmpalette.hpp"
#include "commands/editpalette.hpp"
#include "commands/changetilesheet.hpp"
#include "worldobjectseteditor-imgui.hpp"
@ -26,12 +25,12 @@ WorldObjectSetEditorImGui::WorldObjectSetEditorImGui(
Editor(path),
m_sctx(ctx),
m_itemPath(path),
m_doc(*readObj<WorldObjectSet>(keelCtx(ctx.tctx), path).unwrapThrow()),
m_tileSheet(readObj<ncore::TileSheet>(keelCtx(m_sctx.tctx), m_doc.tilesheet).unwrapThrow()) {
m_doc(*readObj<WorldObjectSet>(keelCtx(m_sctx), path).unwrapThrow()),
m_tileSheet(readObj<ncore::TileSheet>(keelCtx(m_sctx), m_doc.tilesheet).unwrapThrow()) {
auto const&tilesheetList = m_sctx.project->fileList(ncore::FileExt_ng);
auto &kctx = keelCtx(m_sctx.tctx);
auto &kctx = keelCtx(m_sctx);
auto const [tsPath, err] = getPath(kctx, m_doc.tilesheet);
if (err) {
if (!err) {
m_selectedTilesheetIdx = std::find(tilesheetList.begin(), tilesheetList.end(), tsPath).offset();
}
loadObj();
@ -67,7 +66,6 @@ void WorldObjectSetEditorImGui::draw(studio::StudioContext&) noexcept {
}
ImGui::EndChild();
drawAddPalettePopup();
drawEditPalettePopup();
}
void WorldObjectSetEditorImGui::onActivated() noexcept {
@ -84,8 +82,8 @@ WorldObject &WorldObjectSetEditorImGui::activeObj() noexcept {
void WorldObjectSetEditorImGui::buildPaletteDisplayNameList() noexcept {
m_paletteDisplayNames.clear();
for (auto i = 1u; auto const&pal : m_doc.palettes) {
auto const path = keel::getPath(keelCtx(m_sctx.tctx), pal.palette).or_value("Invalid path");
m_paletteDisplayNames.emplace_back(ox::sfmt("{}: {} - {} ms", i, path, pal.intervalMs));
auto const path = keel::getPath(keelCtx(m_sctx.tctx), pal).or_value("Invalid path");
m_paletteDisplayNames.emplace_back(ox::sfmt("{}: {}", i, path));
++i;
}
}
@ -95,11 +93,11 @@ void WorldObjectSetEditorImGui::drawTileSheetSelector() noexcept {
auto sel = m_selectedTilesheetIdx;
if (ig::ComboBox("Tile Sheet", tilesheetList, sel)) {
auto const [uuid, err] = keel::pathToUuid(
keelCtx(m_sctx.tctx), tilesheetList[m_addPalPopup.selectedIdx]);
keelCtx(m_sctx.tctx), tilesheetList[sel]);
if (!err) {
auto const uuidUrl = ox::sfmt("uuid://{}", uuid.toString());
std::ignore = undoStack()->push(ox::make_unique<ChangeTileSheet>
(m_doc, ox::FileAddress(uuidUrl), sel, m_selectedTilesheetIdx));
std::ignore = pushCommand<ChangeTileSheet>
(m_doc, ox::FileAddress(uuidUrl), sel, m_selectedTilesheetIdx);
loadObj();
}
}
@ -115,7 +113,7 @@ void WorldObjectSetEditorImGui::drawObjSelector() noexcept {
}
ImGui::SameLine();
if (ig::PushButton("-", btnSize)) {
std::ignore = undoStack()->push(ox::make_unique<RmObject>(m_doc, m_selectedObj));
std::ignore = pushCommand<RmObject>(m_doc, m_selectedObj);
}
if (ig::ListBox("Objects", [this](size_t i) -> ox::CStringView {
return m_doc.objects[i].name;
@ -132,6 +130,7 @@ void WorldObjectSetEditorImGui::loadObj() noexcept {
auto &nameBuff = m_objEditor.nameBuff;
ox::strncpy(nameBuff.data(), obj.name.data(), nameBuff.size());
m_objEditor.palette = obj.palBank;
m_objEditor.interval = obj.intervalMs;
m_subsheet = getSubsheet(*m_tileSheet, obj.subsheetId);
int w = 0;
int h = 0;
@ -142,7 +141,7 @@ void WorldObjectSetEditorImGui::loadObj() noexcept {
auto const idx = getTileIdx(*m_tileSheet, obj.subsheetId);
oxLogError(m_colView.setup(
m_doc.tilesheet,
m_doc.palettes[obj.palBank].palette,
m_doc.palettes[obj.palBank],
w,
h,
static_cast<uint_t>(idx),
@ -164,17 +163,22 @@ void WorldObjectSetEditorImGui::drawObjEditor() noexcept {
ImGui::NewLine();
auto &nameBuff = m_objEditor.nameBuff;
if (ImGui::InputText("Name", nameBuff.data(), nameBuff.size())) {
std::ignore = undoStack()->push(ox::make_unique<EditObjectName>(
std::ignore = pushCommand<EditObjectName>(
m_doc,
m_selectedObj,
ox::String(nameBuff.data(), ox::strnlen(nameBuff.data(), nameBuff.size()))));
ox::String(nameBuff.data(), ox::strnlen(nameBuff.data(), nameBuff.size())));
}
// SubSheet Selector
{
ig::IDStackItem const subsheetSelectorStackItem("SubsheetSelector");
if (ig::ComboBox("Palette", m_paletteDisplayNames, m_objEditor.palette)) {
std::ignore = undoStack()->push(ox::make_unique<EditObjectPalette>(
m_doc, m_selectedObj, static_cast<uint16_t>(m_objEditor.palette)));
std::ignore = pushCommand<EditObjectPalette>(
m_doc, m_selectedObj, static_cast<uint16_t>(m_objEditor.palette));
}
if (ImGui::InputInt("Interval (ms)", &m_objEditor.interval, 50, 1000)) {
m_objEditor.interval = ox::clamp(m_objEditor.interval, 50, 65535);
std::ignore = pushCommand<EditObjectInterval>(
m_doc, m_selectedObj, static_cast<uint16_t>(m_objEditor.interval));
}
ImGui::Separator();
ImGui::Text("Subsheet:");
@ -213,8 +217,7 @@ void WorldObjectSetEditorImGui::drawObjEditor() noexcept {
auto &obj = activeObj();
auto intermediate = obj.collisionMap;
if (m_colView.click(mousePos, intermediate)) {
std::ignore = undoStack()->push(ox::make_unique<EditObjectCollisionMap>(
m_doc, m_selectedObj, intermediate));
std::ignore = pushCommand<EditObjectCollisionMap>(m_doc, m_selectedObj, intermediate);
}
}
}
@ -234,7 +237,7 @@ void WorldObjectSetEditorImGui::drawSubSheetNode(ncore::TileSheet::SubSheet cons
}
} else if (ImGui::TreeNodeEx(ss.name.c_str(), ImGuiTreeNodeFlags_Leaf | selected)) {
if (ImGui::IsItemClicked()) {
std::ignore = undoStack()->push(ox::make_unique<EditObjectSubSheet>(m_doc, m_selectedObj, ss.id));
std::ignore = pushCommand<EditObjectSubSheet>(m_doc, m_selectedObj, ss.id);
}
ImGui::TreePop();
}
@ -249,14 +252,9 @@ void WorldObjectSetEditorImGui::drawPaletteList() noexcept {
if (ig::PushButton("-", btnSize)) {
rmPalette();
}
ImGui::SameLine();
if (ig::PushButton("Edit")) {
editPalette();
}
constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
if (ImGui::BeginTable("Subsheets", 2, flags)) {
if (ImGui::BeginTable("Subsheets", 1, flags)) {
ImGui::TableSetupColumn("Palette", ImGuiTableColumnFlags_NoHide);
ImGui::TableSetupColumn("Interval", ImGuiTableColumnFlags_WidthFixed, 100);
ImGui::TableHeadersRow();
drawPaletteListItems();
ImGui::EndTable();
@ -269,17 +267,12 @@ void WorldObjectSetEditorImGui::drawPaletteListItems() noexcept {
ImGui::TableNextRow();
ImGui::TableNextColumn();
auto const path
= keel::getPath(keelCtx(m_sctx.tctx), pal.palette).or_value("Invalid path");
= keel::getPath(keelCtx(m_sctx.tctx), pal).or_value("Invalid path");
ImGui::Text("%s", path.c_str());
ImGui::TableNextColumn();
ImGui::Text("%d ms", pal.intervalMs);
ImGui::SameLine();
if (ImGui::Selectable("##PaletteSelection", i == m_selectedPal, ImGuiSelectableFlags_SpanAllColumns)) {
m_selectedPal = i;
}
if (ImGui::IsMouseDoubleClicked(0) && ImGui::IsItemHovered()) {
editPalette();
}
++i;
}
}
@ -299,48 +292,20 @@ void WorldObjectSetEditorImGui::drawAddPalettePopup() noexcept {
keelCtx(m_sctx.tctx), palettes[m_addPalPopup.selectedIdx]);
if (!err) {
auto const uuidUrl = ox::sfmt("uuid://{}", uuid.toString());
std::ignore = undoStack()->push(ox::make_unique<AddPalette>(
m_doc, ox::FileAddress(uuidUrl)));
std::ignore = pushCommand<AddPalette>(m_doc, ox::FileAddress(uuidUrl));
}
}
ImGui::EndPopup();
}
}
void WorldObjectSetEditorImGui::drawEditPalettePopup() noexcept {
if (!m_editPalPopup.show) {
return;
}
auto constexpr popupName = ox::CStringView("Edit Palette");
auto constexpr popupSz = ImVec2{300.f, 0};
ig::IDStackItem const idStackItem("EditPalette");
if (ig::BeginPopup(m_sctx.tctx, popupName, m_editPalPopup.show, popupSz)) {
auto &pal = m_doc.palettes[m_selectedPal];
ImGui::InputInt("Interval (ms)", &m_editPalPopup.intervalInputVal, 1000);
m_editPalPopup.intervalInputVal =
static_cast<uint16_t>(ox::clamp(m_editPalPopup.intervalInputVal, 0, 60000));
if (ig::PopupControlsOkCancel(popupSz.x, m_editPalPopup.show) == ig::PopupResponse::OK) {
std::ignore = undoStack()->push(ox::make_unique<EditPalette>(
pal, static_cast<uint16_t>(m_editPalPopup.intervalInputVal)));
}
ImGui::EndPopup();
}
}
void WorldObjectSetEditorImGui::addPalette() noexcept {
m_addPalPopup.show = true;
m_addPalPopup.selectedIdx = 0;
}
void WorldObjectSetEditorImGui::rmPalette() noexcept {
std::ignore = undoStack()->push(ox::make_unique<RmPalette>(
m_doc, m_selectedPal));
}
void WorldObjectSetEditorImGui::editPalette() noexcept {
auto &pal = m_doc.palettes[m_selectedPal];
m_editPalPopup.show = true;
m_editPalPopup.intervalInputVal = pal.intervalMs;
std::ignore = pushCommand<RmPalette>(m_doc, m_selectedPal);
}
ox::Error WorldObjectSetEditorImGui::handleCmd(studio::UndoCommand const*cmd) noexcept {
@ -349,8 +314,7 @@ ox::Error WorldObjectSetEditorImGui::handleCmd(studio::UndoCommand const*cmd) no
oxLogError(readObj<ncore::TileSheet>(kctx, m_doc.tilesheet).moveTo(m_tileSheet));
} else if (
dynamic_cast<AddPalette const*>(cmd) ||
dynamic_cast<RmPalette const*>(cmd) ||
dynamic_cast<EditPalette const*>(cmd)) {
dynamic_cast<RmPalette const*>(cmd)) {
buildPaletteDisplayNameList();
} else if (dynamic_cast<EditObjectPalette const*>(cmd)) {
auto const&obj = activeObj();

View File

@ -29,13 +29,10 @@ class WorldObjectSetEditorImGui: public studio::Editor {
bool show{};
size_t selectedIdx{};
} m_addPalPopup;
struct {
bool show{};
int intervalInputVal{};
} m_editPalPopup;
CollisionView m_colView{m_sctx};
struct {
ox::Buffer nameBuff = ox::Buffer(256);
int interval{};
size_t palette{};
} m_objEditor;
@ -69,14 +66,10 @@ class WorldObjectSetEditorImGui: public studio::Editor {
void drawAddPalettePopup() noexcept;
void drawEditPalettePopup() noexcept;
void addPalette() noexcept;
void rmPalette() noexcept;
void editPalette() noexcept;
ox::Error handleCmd(studio::UndoCommand const*cmd) noexcept;
ox::Error saveItem() noexcept final;

View File

@ -18,11 +18,9 @@ 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) {
auto &palRef = m_palettes.emplace_back();
oxReturnError(readObj<ncore::CompactPalette>(keelCtx(m_nctx), pal.palette).moveTo(palRef.pal));
oxReturnError(ncore::loadBgPalette(m_nctx, i, *palRef.pal));
for (auto i = 0u; auto const&palAddr : m_worldStatic.palettes) {
oxRequire(pal, readObj<ncore::CompactPalette>(keelCtx(m_nctx), palAddr));
oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal));
++i;
}
oxReturnError(ncore::loadBgTileSheet(m_nctx, 0, m_worldStatic.tilesheets));
@ -68,15 +66,7 @@ void World::setupLayer(
}
ox::Result<int> World::update() noexcept {
auto const time = ticksMs(turbineCtx(m_nctx));
int expiresIn = 60'000;
for (size_t i = 0; auto const&pal : m_palettes) {
auto const interval = m_worldStatic.palettes[i].intervalMs;
auto const page = (time / interval) % pal.pal->pages.size();
expiresIn = ox::min(expiresIn, static_cast<int>(time % interval));
oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal.pal, static_cast<size_t>(page)));
++i;
}
return expiresIn;
}
@ -85,22 +75,6 @@ ox::Result<int> World::editorModeUpdate() noexcept {
auto const time = ticksMs(turbineCtx(m_nctx));
if (time >= m_nextUpdateTime) {
turbine::TimeMs expiresIn = 60'000;
bool updated = false;
auto const elapsedSincePrev = time - m_prevUpdateTime;
for (size_t i = 0; auto &pal: m_palettes) {
auto const interval = m_worldStatic.palettes[i].intervalMs;
auto &page = pal.page;
auto const update = (elapsedSincePrev >= interval);
page += update * 1;
page %= static_cast<int>(pal.pal->pages.size());
oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal.pal, static_cast<size_t>(page)));
updated = updated || update;
expiresIn = ox::min<turbine::TimeMs>(expiresIn, interval);
++i;
}
if (updated) {
m_prevUpdateTime = time;
}
m_nextUpdateTime = time + expiresIn;
}
return static_cast<int>(m_nextUpdateTime - time);