diff --git a/project/.DS_Store b/project/.DS_Store index af7cc67..0f5e8c2 100644 Binary files a/project/.DS_Store and b/project/.DS_Store differ diff --git a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObject;1 b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObject;1 index adc3f40..411259e 100644 --- a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObject;1 +++ b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObject;1 @@ -9,6 +9,10 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{ "fieldName" : "name", "typeId" : "net.drinkingtea.ox.BasicString#8#;1" }, + { + "fieldName" : "intervalMs", + "typeId" : "B.uint16;0" + }, { "fieldName" : "pal_bank", "typeId" : "B.uint16;0" diff --git a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObjectSet;1 b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObjectSet;1 index ec51374..5568091 100644 --- a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObjectSet;1 +++ b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldObjectSet;1 @@ -18,7 +18,7 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{ "subscriptType" : 4 } ], - "typeId" : "net.drinkingtea.jasper.world.PaletteCycle;1" + "typeId" : "net.drinkingtea.ox.FileAddress;1" }, { "fieldName" : "objects", diff --git a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldStatic;1 b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldStatic;1 index 3a73fd9..db9ceef 100644 --- a/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldStatic;1 +++ b/project/.jasper/type_descriptors/net.drinkingtea.jasper.world.WorldStatic;1 @@ -14,7 +14,7 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{ "subscriptType" : 4 } ], - "typeId" : "net.drinkingtea.jasper.world.PaletteCycle;1" + "typeId" : "net.drinkingtea.ox.FileAddress;1" }, { "fieldName" : "columns", diff --git a/project/Palettes/Terrain.npal b/project/Palettes/Terrain.npal index 1db4c24..1bc127f 100644 Binary files a/project/Palettes/Terrain.npal and b/project/Palettes/Terrain.npal differ diff --git a/project/TileSheets/Terrain.ng b/project/TileSheets/Terrain.ng index 7b5e6ac..081a35c 100644 Binary files a/project/TileSheets/Terrain.ng and b/project/TileSheets/Terrain.ng differ diff --git a/project/WorldObjectSets/TerrainObjects.jwob b/project/WorldObjectSets/TerrainObjects.jwob index 0e952d8..63da9c9 100644 Binary files a/project/WorldObjectSets/TerrainObjects.jwob and b/project/WorldObjectSets/TerrainObjects.jwob differ diff --git a/src/jasper/modules/world/include/jasper/world/objectcache.hpp b/src/jasper/modules/world/include/jasper/world/objectcache.hpp index 0bb9423..05a1ce8 100644 --- a/src/jasper/modules/world/include/jasper/world/objectcache.hpp +++ b/src/jasper/modules/world/include/jasper/world/objectcache.hpp @@ -26,7 +26,7 @@ class ObjectCache { ox::Vector objects; }; ox::Vector m_tilesheets; - ox::Vector m_palettes; + ox::Vector m_palettes; size_t m_tileIdx{}; size_t m_palBank{}; ox::Vector m_objSets; @@ -42,7 +42,7 @@ class ObjectCache { [[nodiscard]] ncore::TileSheetSet const&tilesheets() const noexcept; [[nodiscard]] - ox::Vector const&palettes() const noexcept; + ox::Vector const&palettes() const noexcept; private: void addTileSheet(ox::FileAddress path, int32_t tiles) noexcept; }; diff --git a/src/jasper/modules/world/include/jasper/world/world.hpp b/src/jasper/modules/world/include/jasper/world/world.hpp index 4fd59f6..09f879d 100644 --- a/src/jasper/modules/world/include/jasper/world/world.hpp +++ b/src/jasper/modules/world/include/jasper/world/world.hpp @@ -16,15 +16,10 @@ namespace ncore = nostalgia::core; class World { private: - struct PaletteTracker { - keel::AssetRef pal; - int page{}; - }; - ox::Vector 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 diff --git a/src/jasper/modules/world/include/jasper/world/worldobject.hpp b/src/jasper/modules/world/include/jasper/world/worldobject.hpp index 0148d02..4b3e8eb 100644 --- a/src/jasper/modules/world/include/jasper/world/worldobject.hpp +++ b/src/jasper/modules/world/include/jasper/world/worldobject.hpp @@ -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 palettes; + ox::Vector palettes; ox::Vector objects; }; diff --git a/src/jasper/modules/world/include/jasper/world/worldstatic.hpp b/src/jasper/modules/world/include/jasper/world/worldstatic.hpp index 8ac6e66..40ffdf6 100644 --- a/src/jasper/modules/world/include/jasper/world/worldstatic.hpp +++ b/src/jasper/modules/world/include/jasper/world/worldstatic.hpp @@ -91,7 +91,7 @@ struct WorldStatic { constexpr static auto TypeVersion = 1; constexpr static auto Preloadable = true; ncore::TileSheetSet tilesheets; - ox::Vector palettes; + ox::Vector palettes; int16_t columns{}; int16_t rows{}; ox::Array map; diff --git a/src/jasper/modules/world/src/keel/keelmodule.cpp b/src/jasper/modules/world/src/keel/keelmodule.cpp index f76c46f..eb9e1e8 100644 --- a/src/jasper/modules/world/src/keel/keelmodule.cpp +++ b/src/jasper/modules/world/src/keel/keelmodule.cpp @@ -24,7 +24,6 @@ static class: public keel::Module { [[nodiscard]] ox::Vector types() const noexcept override { return { - keel::generateTypeDesc, keel::generateTypeDesc, keel::generateTypeDesc, keel::generateTypeDesc, diff --git a/src/jasper/modules/world/src/objectcache.cpp b/src/jasper/modules/world/src/objectcache.cpp index 01ec54a..17b6532 100644 --- a/src/jasper/modules/world/src/objectcache.cpp +++ b/src/jasper/modules/world/src/objectcache.cpp @@ -41,7 +41,7 @@ ox::Error ObjectCache::indexSet( addTileSheet(objSet.tilesheet, static_cast(tileCnt)); for (auto const&pal : objSet.palettes) { m_palettes.emplace_back(pal); - oxRequire(p, readObj(kctx, pal.palette)); + oxRequire(p, readObj(kctx, pal)); m_palBank += largestPage(*p); } return {}; @@ -65,7 +65,7 @@ ncore::TileSheetSet const&ObjectCache::tilesheets() const noexcept { return m_tilesheetSet; } -ox::Vector const&ObjectCache::palettes() const noexcept { +ox::Vector const&ObjectCache::palettes() const noexcept { return m_palettes; } 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 7906dce..e2a37bb 100644 --- a/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp +++ b/src/jasper/modules/world/src/studio/worldeditor/worldeditor-imgui.cpp @@ -431,7 +431,7 @@ ox::Error WorldEditorImGui::loadObjectSets() noexcept { oxRequireM(os, readObj(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)); } diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/CMakeLists.txt b/src/jasper/modules/world/src/studio/worldobjectseteditor/CMakeLists.txt index 51945f2..141a2e7 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/CMakeLists.txt +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/CMakeLists.txt @@ -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 diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/addpalette.cpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/addpalette.cpp index a9277c0..7ce03a5 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/addpalette.cpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/addpalette.cpp @@ -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; } diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/commands.hpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/commands.hpp index 9daadb2..34adab4 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/commands.hpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/commands.hpp @@ -11,12 +11,12 @@ enum class WorldObjCommand { AddObject, RmObject, EditObjectName, + EditObjectInterval, EditObjectPalette, EditObjectSubSheet, EditObjectCollisionMap, AddPalette, RmPalette, - EditPalette, ChangeTileSheet, }; diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.cpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.cpp index e140601..20dc822 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.cpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.cpp @@ -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(WorldObjCommand::EditObjectInterval); +} + +bool EditObjectInterval::mergeWith(UndoCommand const&cmd) noexcept { + auto const en = dynamic_cast(&cmd); + if (en && m_objIdx == en->m_objIdx) { + m_newVal = en->m_newVal; + return true; + } + return false; +} + + EditObjectSubSheet::EditObjectSubSheet( WorldObjectSet &doc, size_t objIdx, diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.hpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.hpp index 76db776..b659580 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.hpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editobject.hpp @@ -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; diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.cpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.cpp deleted file mode 100644 index 2a7c3b3..0000000 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.cpp +++ /dev/null @@ -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(WorldObjCommand::EditPalette); -} - -} diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.hpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.hpp deleted file mode 100644 index abf7154..0000000 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/editpalette.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. - */ - -#pragma once - -#include - -#include - -#include - -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; -}; - -} diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.cpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.cpp index 71112a0..f6f583e 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.cpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.cpp @@ -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 {}; } diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.hpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.hpp index f58de9f..b62a15a 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.hpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/commands/rmpalette.hpp @@ -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; diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.cpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.cpp index a31e7e8..5246ba0 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.cpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.cpp @@ -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(keelCtx(ctx.tctx), path).unwrapThrow()), - m_tileSheet(readObj(keelCtx(m_sctx.tctx), m_doc.tilesheet).unwrapThrow()) { + m_doc(*readObj(keelCtx(m_sctx), path).unwrapThrow()), + m_tileSheet(readObj(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 - (m_doc, ox::FileAddress(uuidUrl), sel, m_selectedTilesheetIdx)); + std::ignore = pushCommand + (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(m_doc, m_selectedObj)); + std::ignore = pushCommand(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(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( + std::ignore = pushCommand( 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( - m_doc, m_selectedObj, static_cast(m_objEditor.palette))); + std::ignore = pushCommand( + m_doc, m_selectedObj, static_cast(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( + m_doc, m_selectedObj, static_cast(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( - m_doc, m_selectedObj, intermediate)); + std::ignore = pushCommand(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(m_doc, m_selectedObj, ss.id)); + std::ignore = pushCommand(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( - m_doc, ox::FileAddress(uuidUrl))); + std::ignore = pushCommand(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(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( - pal, static_cast(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( - 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(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(kctx, m_doc.tilesheet).moveTo(m_tileSheet)); } else if ( dynamic_cast(cmd) || - dynamic_cast(cmd) || - dynamic_cast(cmd)) { + dynamic_cast(cmd)) { buildPaletteDisplayNameList(); } else if (dynamic_cast(cmd)) { auto const&obj = activeObj(); diff --git a/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.hpp b/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.hpp index c6eab01..4bd74c1 100644 --- a/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.hpp +++ b/src/jasper/modules/world/src/studio/worldobjectseteditor/worldobjectseteditor-imgui.hpp @@ -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; diff --git a/src/jasper/modules/world/src/world.cpp b/src/jasper/modules/world/src/world.cpp index 16ed7b3..3b19f09 100644 --- a/src/jasper/modules/world/src/world.cpp +++ b/src/jasper/modules/world/src/world.cpp @@ -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(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(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 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(time % interval)); - oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal.pal, static_cast(page))); - ++i; - } return expiresIn; } @@ -85,22 +75,6 @@ ox::Result 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(pal.pal->pages.size()); - oxReturnError(ncore::loadBgPalette(m_nctx, i, *pal.pal, static_cast(page))); - updated = updated || update; - expiresIn = ox::min(expiresIn, interval); - ++i; - } - if (updated) { - m_prevUpdateTime = time; - } m_nextUpdateTime = time + expiresIn; } return static_cast(m_nextUpdateTime - time);