diff --git a/src/jasper/modules/world/include/jasper/world/world.hpp b/src/jasper/modules/world/include/jasper/world/world.hpp index 46181c1..be60892 100644 --- a/src/jasper/modules/world/include/jasper/world/world.hpp +++ b/src/jasper/modules/world/include/jasper/world/world.hpp @@ -33,6 +33,10 @@ class World { ox::Result editorModeUpdate() noexcept; #endif + void setupTiles() noexcept; + + void setupTile(uint32_t lyr, uint32_t x, uint32_t y) const noexcept; + private: void setupLayer(uint_t lyr, uint_t cbb) const noexcept; diff --git a/src/jasper/modules/world/include/jasper/world/worldstatic.hpp b/src/jasper/modules/world/include/jasper/world/worldstatic.hpp index 5c9f315..12289d5 100644 --- a/src/jasper/modules/world/include/jasper/world/worldstatic.hpp +++ b/src/jasper/modules/world/include/jasper/world/worldstatic.hpp @@ -166,6 +166,9 @@ auto &cbb(ox::CommonRefWith auto&ws, size_t const lyr) noexcept { class WorldStaticLoader { + public: + ox::Signal tileUpdated; + ox::Signal resourcesUpdated; private: keel::Context &m_kctx; WorldStatic &m_worldStatic; @@ -177,7 +180,8 @@ class WorldStaticLoader { ox::SmallMap m_cache; ox::SmallMap m_objSets; uint16_t m_cbbIt{4}; - bool m_loaded = false; + bool m_resourcesChanged{}; + bool m_loaded{}; public: WorldStaticLoader(keel::Context &kctx, WorldStatic &worldStatic, WorldDoc const&doc); diff --git a/src/jasper/modules/world/src/studio/worldeditor/commands/addrmobjectset.hpp b/src/jasper/modules/world/src/studio/worldeditor/commands/addrmobjectset.hpp index ea58954..ec960cd 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/commands/addrmobjectset.hpp +++ b/src/jasper/modules/world/src/studio/worldeditor/commands/addrmobjectset.hpp @@ -23,10 +23,6 @@ class AddObjectSet: public studio::UndoCommand { ox::Error undo() noexcept override; [[nodiscard]] int commandId() const noexcept override; - [[nodiscard]] - inline size_t insertIdx() const noexcept { - return m_insertIdx; - } }; class RmObjectSet: public studio::UndoCommand { diff --git a/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.cpp b/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.cpp index b41dedd..4ae08c8 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.cpp +++ b/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.cpp @@ -8,22 +8,24 @@ namespace jasper::world { EditWorldSizeCommand::EditWorldSizeCommand( + WorldStaticLoader &loader, WorldDoc &doc, ox::Size const&size): - m_doc(doc), - m_oldSize(m_doc.columns, m_doc.rows), - m_newSize(size) {} + m_loader{loader}, + m_doc{doc}, + m_oldSize{m_doc.columns, m_doc.rows}, + m_newSize{size} {} ox::Error EditWorldSizeCommand::redo() noexcept { m_oldMap = m_doc.tiles; resize(m_doc, m_newSize); - return {}; + return m_loader.loadWorldStatic(); } ox::Error EditWorldSizeCommand::undo() noexcept { resize(m_doc, m_oldSize); m_doc.tiles = std::move(m_oldMap); - return {}; + return m_loader.loadWorldStatic(); } int EditWorldSizeCommand::commandId() const noexcept { diff --git a/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.hpp b/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.hpp index 951a6a2..dc85093 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.hpp +++ b/src/jasper/modules/world/src/studio/worldeditor/commands/editsize.hpp @@ -4,8 +4,6 @@ #pragma once -#include - #include #include @@ -14,23 +12,20 @@ namespace jasper::world { class EditWorldSizeCommand: public studio::UndoCommand { private: + WorldStaticLoader &m_loader; WorldDoc &m_doc; - size_t m_insertIdx{}; ox::Size const m_oldSize; WorldDoc::TileMap m_oldMap; - ox::Size m_newSize; + ox::Size const m_newSize; public: EditWorldSizeCommand( + WorldStaticLoader &loader, WorldDoc &doc, ox::Size const&size); ox::Error redo() noexcept override; ox::Error undo() noexcept override; [[nodiscard]] int commandId() const noexcept override; - [[nodiscard]] - inline size_t insertIdx() const noexcept { - return m_insertIdx; - } private: enum class Dimension { X, Y, Both, Neither, diff --git a/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp b/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp index 6046af8..e6d6021 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp +++ b/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp @@ -77,10 +77,13 @@ WorldEditorImGui::WorldEditorImGui(studio::StudioContext &sctx, ox::StringParam m_sctx{sctx}, m_doc{*keel::readObj(keelCtx(m_sctx), itemPath()).unwrapThrow()} { OX_THROW_ERROR(m_loader.loadWorldStatic()); + OX_THROW_ERROR(m_view.setupWorld()); OX_THROW_ERROR(loadObjectSets()); m_objSetPicker.filePicked.connect(this, &WorldEditorImGui::addObjSet); m_sctx.project->fileUpdated.connect(this, &WorldEditorImGui::handleDepUpdate); - studio::Editor::undoStack()->changeTriggered.connect(this, &WorldEditorImGui::undoStackChanged); + m_loader.resourcesUpdated.connect(&m_view, &WorldEditorView::setupWorld); + m_loader.tileUpdated.connect(&m_view, &WorldEditorView::setupTile); + Editor::undoStack()->changeTriggered.connect(this, &WorldEditorImGui::undoStackChanged); studio::openConfig( keelCtx(m_sctx), itemPath(), [this](WorldEditorConfig const&config) { m_view.setAnimate(config.animateBg); @@ -106,7 +109,6 @@ void WorldEditorImGui::draw(studio::StudioContext&) noexcept { } void WorldEditorImGui::onActivated() noexcept { - oxLogError(m_view.setupWorld()); } void WorldEditorImGui::copy() { @@ -240,7 +242,7 @@ void WorldEditorImGui::drawPropEditor() noexcept { if (ig::PopupControlsOkCancel(popupSz.x, m_sizeEditor.show) == ig::PopupResponse::OK) { if (changed) { std::ignore = pushCommand( - m_doc, ox::Size{m_sizeEditor.columns, m_sizeEditor.rows}); + m_loader, m_doc, ox::Size{m_sizeEditor.columns, m_sizeEditor.rows}); } } ImGui::EndPopup(); @@ -379,7 +381,6 @@ ox::Error WorldEditorImGui::handleDrop(float const fbPaneScale) noexcept { m_doc, std::move(mods)); } - OX_RETURN_ERROR(m_loader.loadWorldStatic()); return {}; } @@ -430,7 +431,6 @@ ox::Error WorldEditorImGui::undoStackChanged(studio::UndoCommand const*cmd) { if (dynamic_cast(cmd)) { OX_RETURN_ERROR(m_loader.loadWorldStatic()); } - OX_RETURN_ERROR(m_view.setupWorld()); return {}; } diff --git a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp index bff7ce5..1ac1dca 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp +++ b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.cpp @@ -9,10 +9,21 @@ namespace jasper::world { WorldEditorView::WorldEditorView(studio::StudioContext &sctx, WorldStatic const&worldStatic): - m_sctx(sctx), - m_cctx(ncore::init(m_sctx.tctx, {.glInstallDrawer = false}).unwrapThrow()), - m_worldStatic(worldStatic), - m_world(*m_cctx, m_worldStatic) { + m_sctx{sctx}, + m_cctx{ncore::init(m_sctx.tctx, {.glInstallDrawer = false}).unwrapThrow()}, + m_worldStatic{worldStatic}, + m_world{*m_cctx, m_worldStatic} {} + +ox::Error WorldEditorView::setupTile( + uint32_t const lyr, + uint32_t const x, + uint32_t const y) const noexcept { + m_world.setupTile(lyr, x, y); + return {}; +} + +void WorldEditorView::setupTiles() noexcept { + m_world.setupTiles(); } ox::Error WorldEditorView::setupWorld() noexcept { diff --git a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.hpp b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.hpp index a65e6f7..665f49b 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.hpp +++ b/src/jasper/modules/world/src/studio/worldeditor/worldeditorview.hpp @@ -19,7 +19,7 @@ namespace jasper::world { namespace ncore = nostalgia::core; -class WorldEditorView { +class WorldEditorView: public ox::SignalHandler { private: studio::StudioContext &m_sctx; @@ -37,6 +37,10 @@ class WorldEditorView { public: WorldEditorView(studio::StudioContext &ctx, WorldStatic const&worldStatic); + ox::Error setupTile(uint32_t lyr, uint32_t x, uint32_t y) const noexcept; + + void setupTiles() noexcept; + ox::Error setupWorld() noexcept; void 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 3ebe5f5..f6043f0 100644 --- a/src/jasper/modules/world/src/world.cpp +++ b/src/jasper/modules/world/src/world.cpp @@ -42,12 +42,42 @@ ox::Error World::setupDisplay() noexcept { rs.tilesheetIdx, rs.tileCnt)); } + setupTiles(); + return {}; +} + +void World::setupTiles() noexcept { ncore::setBgStatus(m_nctx, 0); // disable all backgrounds for (auto layerNo = 0u; auto const&layer : m_worldStatic.map) { setupLayer(layerNo, layer.cbb); ++layerNo; } - return {}; +} + +void World::setupTile( + uint32_t const lyr, + uint32_t const x, + uint32_t const y) const noexcept { + auto &t = tile(m_worldStatic, lyr, x, y); + auto const tx = static_cast(x) * 2; + auto const ty = static_cast(y) * 2; + auto const &obj = m_worldStatic.objTileRefSets[t.objIdxRefSet];; + ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 0, { + .tileIdx = static_cast(obj.cbbIdx + 0), + .palBank = obj.palBank, + }); + ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 0, { + .tileIdx = static_cast(obj.cbbIdx + 1), + .palBank = obj.palBank, + }); + ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 1, { + .tileIdx = static_cast(obj.cbbIdx + 2), + .palBank = obj.palBank, + }); + ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 1, { + .tileIdx = static_cast(obj.cbbIdx + 3), + .palBank = obj.palBank, + }); } void World::setupLayer( @@ -60,26 +90,7 @@ void World::setupLayer( 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; - auto const &obj = m_worldStatic.objTileRefSets[t.objIdxRefSet];; - ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 0, { - .tileIdx = static_cast(obj.cbbIdx + 0), - .palBank = obj.palBank, - }); - ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 0, { - .tileIdx = static_cast(obj.cbbIdx + 1), - .palBank = obj.palBank, - }); - ncore::setBgTile(m_nctx, lyr, tx + 0, ty + 1, { - .tileIdx = static_cast(obj.cbbIdx + 2), - .palBank = obj.palBank, - }); - ncore::setBgTile(m_nctx, lyr, tx + 1, ty + 1, { - .tileIdx = static_cast(obj.cbbIdx + 3), - .palBank = obj.palBank, - }); + setupTile(lyr, static_cast(x), static_cast(y)); } } } diff --git a/src/jasper/modules/world/src/worldstatic.cpp b/src/jasper/modules/world/src/worldstatic.cpp index a668a95..232afbc 100644 --- a/src/jasper/modules/world/src/worldstatic.cpp +++ b/src/jasper/modules/world/src/worldstatic.cpp @@ -56,7 +56,9 @@ ox::Error WorldStaticLoader::loadWorldStatic() noexcept { } } m_loaded = true; - return keel::ensureValid(m_worldStatic); + OX_RETURN_ERROR(keel::ensureValid(m_worldStatic)); + resourcesUpdated.emit(); + return {}; } ox::Error WorldStaticLoader::updateTile( @@ -79,6 +81,12 @@ ox::Error WorldStaticLoader::updateTile( } } loadTile(dst, newSrc); + if (m_resourcesChanged) { + m_resourcesChanged = false; + resourcesUpdated.emit(); + } else { + tileUpdated.emit(layer, col, row); + } return {}; } @@ -150,6 +158,7 @@ ox::Result WorldStaticLoader::setupTileResrc(DocObjRef const&docObjRef) .tileCnt = static_cast(subsheet->size()), }); m_cbbIt += refSet.tileCnt; + m_resourcesChanged = true; if (!docObjRef.unique) { m_cache[docObjRef] = {.value = out, .refCnt = 1}; } @@ -180,6 +189,7 @@ void WorldStaticLoader::deleteRefSet(uint8_t const refIdx, DocObjRef const&oldOb } std::ignore = m_worldStatic.objTileRefSets.erase(refIdx); m_cache.erase(oldObjRef); + m_resourcesChanged = true; } }