diff --git a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp index 1eaa080..cf7998c 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp @@ -238,7 +238,7 @@ ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz * @return a valid version of idx */ [[nodiscard]] -TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept; +TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept; [[nodiscard]] TileSheet::SubSheet const&getSubSheet( diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp index a822cc7..8aa99f1 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/addsubsheetcommand.cpp @@ -46,9 +46,11 @@ ox::Error AddSubSheetCommand::undo() noexcept { parent.columns = s.columns; parent.pixels = std::move(s.pixels); parent.subsheets.clear(); + --m_img.idIt; } else { for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) { oxReturnError(rmSubSheet(m_img, *idx)); + --m_img.idIt; } } return {}; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp index c5d16c1..da406f0 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp @@ -212,8 +212,8 @@ void TileSheetEditorImGui::draw(studio::StudioContext&) noexcept { } } auto const paneSize = ImGui::GetContentRegionAvail(); - auto const tileSheetParentSize = ImVec2(paneSize.x - m_palViewWidth, paneSize.y); - auto const fbSize = ox::Vec2(tileSheetParentSize.x - 16, tileSheetParentSize.y - 16); + auto const tileSheetParentSize = ImVec2{paneSize.x - m_palViewWidth, paneSize.y}; + auto const fbSize = ox::Vec2{tileSheetParentSize.x - 16, tileSheetParentSize.y - 16}; ImGui::BeginChild("TileSheetView", tileSheetParentSize, true); { drawTileSheet(fbSize); @@ -225,7 +225,7 @@ void TileSheetEditorImGui::draw(studio::StudioContext&) noexcept { auto const controlsSize = ImGui::GetContentRegionAvail(); ImGui::BeginChild("ToolBox", {m_palViewWidth - 24, 30}, true); { - auto const btnSz = ImVec2(45, 14); + auto const btnSz = ImVec2{45, 14}; if (ImGui::Selectable("Select", m_tool == TileSheetTool::Select, 0, btnSz)) { m_tool = TileSheetTool::Select; } @@ -388,7 +388,7 @@ ox::Error TileSheetEditorImGui::exportSubhseetToPng(int scale) noexcept { void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { auto const winPos = ImGui::GetWindowPos(); - auto const fbSizei = ox::Size(static_cast(fbSize.x), static_cast(fbSize.y)); + auto const fbSizei = ox::Size{static_cast(fbSize.x), static_cast(fbSize.y)}; if (m_framebuffer.width != fbSizei.width || m_framebuffer.height != fbSizei.height) { glutils::resizeInitFrameBuffer(m_framebuffer, fbSizei.width, fbSizei.height); m_view.resizeView(fbSize); @@ -404,11 +404,11 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { ImGui::Image( ig::toImTextureID(m_framebuffer.color.id), static_cast(fbSize), - ImVec2(0, 1), - ImVec2(1, 0)); + {0, 1}, + {1, 0}); // handle input, this must come after drawing auto const&io = ImGui::GetIO(); - auto const mousePos = ox::Vec2(ImGui::GetMousePos()); + auto const mousePos = ox::Vec2{ImGui::GetMousePos()}; if (ImGui::IsItemHovered()) { auto const wheel = io.MouseWheel; auto const wheelh = io.MouseWheelH; @@ -436,7 +436,7 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { } } if (ImGui::BeginPopupContextItem("TileMenu", ImGuiPopupFlags_MouseButtonRight)) { - auto const popupPos = ox::Vec2(ImGui::GetWindowPos()); + auto const popupPos = ox::Vec2{ImGui::GetWindowPos()}; if (ImGui::MenuItem("Insert Tile")) { m_view.insertTile(fbSize, clickPos(winPos, popupPos)); } @@ -504,8 +504,8 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1)); ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic); ImGui::TableNextColumn(); - auto const&name = pal.colorInfo[i].name; - ImGui::Text("%s", name.c_str()); + auto const&name = i < pal.colorInfo.size() ? pal.colorInfo[i].name.c_str() : ""; + ImGui::Text("%s", name); ImGui::TableNextColumn(); ImGui::Text("(%02d, %02d, %02d)", red16(c), green16(c), blue16(c)); ImGui::TableNextRow(); @@ -556,7 +556,7 @@ void TileSheetEditorImGui::SubSheetEditor::draw(turbine::Context &tctx) noexcept auto const modSize = m_cols > 0; auto constexpr popupWidth = 235.f; auto const popupHeight = modSize ? 130.f : 85.f; - auto const popupSz = ImVec2(popupWidth, popupHeight); + auto const popupSz = ImVec2{popupWidth, popupHeight}; if (ig::BeginPopup(tctx, popupName, m_show, popupSz)) { ImGui::InputText("Name", m_name.data(), m_name.cap()); if (modSize) { @@ -581,7 +581,7 @@ void TileSheetEditorImGui::ExportMenu::draw(turbine::Context &tctx) noexcept { } constexpr auto popupWidth = 235.f; constexpr auto popupHeight = 85.f; - constexpr auto popupSz = ImVec2(popupWidth, popupHeight); + constexpr auto popupSz = ImVec2{popupWidth, popupHeight}; if (ig::BeginPopup(tctx, popupName, m_show, popupSz)) { ImGui::InputInt("Scale", &m_scale); m_scale = ox::clamp(m_scale, 1, 50); diff --git a/src/nostalgia/modules/core/src/tilesheet.cpp b/src/nostalgia/modules/core/src/tilesheet.cpp index 9f622ad..18b62d0 100644 --- a/src/nostalgia/modules/core/src/tilesheet.cpp +++ b/src/nostalgia/modules/core/src/tilesheet.cpp @@ -191,27 +191,28 @@ ox::Result getNameFor(TileSheet::SubSheet const&ss, SubSheetId p TileSheet::SubSheetIdx validateSubSheetIdx( - TileSheet::SubSheetIdx const&pIdx, + TileSheet::SubSheetIdx &&pIdx, std::size_t pIdxIt, TileSheet::SubSheet const&pSubsheet) noexcept { - if (pIdxIt == pIdx.size()) { - return pIdx; + if (pIdxIt >= pIdx.size()) { + return std::move(pIdx); } - const auto currentIdx = pIdx[pIdxIt]; + auto ¤tIdx = pIdx[pIdxIt]; if (pSubsheet.subsheets.size() <= currentIdx) { - auto out = pIdx; - if (!pSubsheet.subsheets.empty()) { - *out.back().value = pSubsheet.subsheets.size() - 1; + if (pSubsheet.subsheets.empty()) { + // currentIdx could not be repaired, remove + // this and all succeeding idxs and return + pIdx.resize(pIdxIt); + return std::move(pIdx); } else { - out.pop_back(); + currentIdx = pSubsheet.subsheets.size() - 1; } - return out; } - return validateSubSheetIdx(pIdx, pIdxIt + 1, pSubsheet.subsheets[pIdx[pIdxIt]]); + return validateSubSheetIdx(std::move(pIdx), pIdxIt + 1, pSubsheet.subsheets[currentIdx]); } -TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept { - return validateSubSheetIdx(idx, 0, ts.subsheet); +TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept { + return validateSubSheetIdx(std::move(idx), 0, ts.subsheet); } const TileSheet::SubSheet &getSubSheet( diff --git a/src/olympic/keel/include/keel/assetmanager.hpp b/src/olympic/keel/include/keel/assetmanager.hpp index 3daefc6..99f8d6b 100644 --- a/src/olympic/keel/include/keel/assetmanager.hpp +++ b/src/olympic/keel/include/keel/assetmanager.hpp @@ -302,7 +302,7 @@ class AssetManager { template class AssetRef { private: - T const*const m_obj = nullptr; + T const* m_obj = nullptr; public: constexpr AssetRef() noexcept = default; diff --git a/src/olympic/studio/applib/src/main.cpp b/src/olympic/studio/applib/src/main.cpp index b38ec36..324cebc 100644 --- a/src/olympic/studio/applib/src/main.cpp +++ b/src/olympic/studio/applib/src/main.cpp @@ -28,12 +28,6 @@ class StudioUIDrawer: public turbine::gl::Drawer { } }; -static int updateHandler(turbine::Context &ctx) noexcept { - auto sctx = turbine::applicationData(ctx); - sctx->ui.update(); - return 16; -} - static void keyEventHandler(turbine::Context &ctx, turbine::Key key, bool down) noexcept { auto sctx = turbine::applicationData(ctx); sctx->ui.handleKeyEvent(key, down); @@ -45,9 +39,8 @@ static ox::Error runApp( ox::UPtr &&fs) noexcept { oxRequireM(ctx, turbine::init(std::move(fs), appName)); turbine::setWindowTitle(*ctx, keelCtx(*ctx).appName); - turbine::setUpdateHandler(*ctx, updateHandler); turbine::setKeyEventHandler(*ctx, keyEventHandler); - turbine::setConstantRefresh(*ctx, false); + turbine::setRefreshWithin(*ctx, 0); StudioUI ui(*ctx, projectDataDir); StudioUIDrawer drawer(ui); turbine::gl::addDrawer(*ctx, &drawer); @@ -68,7 +61,7 @@ static ox::Error run( static_cast(time << 1) }); // run app - auto const err = runApp(appName, projectDataDir, ox::UPtr(nullptr)); + auto const err = runApp(appName, projectDataDir, ox::UPtr{}); oxAssert(err, "Something went wrong..."); return err; } diff --git a/src/olympic/studio/applib/src/studioapp.cpp b/src/olympic/studio/applib/src/studioapp.cpp index 4fc9206..dc74dd4 100644 --- a/src/olympic/studio/applib/src/studioapp.cpp +++ b/src/olympic/studio/applib/src/studioapp.cpp @@ -78,10 +78,6 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcep } } -void StudioUI::update() noexcept { - m_taskRunner.update(m_ctx); -} - void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept { for (auto p : m_popups) { if (p->isOpen()) { @@ -124,6 +120,7 @@ void StudioUI::draw() noexcept { } ImGui::End(); handleKeyInput(); + m_taskRunner.update(m_ctx); } void StudioUI::drawMenu() noexcept { @@ -212,7 +209,6 @@ void StudioUI::drawTabs() noexcept { } if (m_activeEditorOnLastDraw != e.get()) [[unlikely]] { m_activeEditor->onActivated(); - turbine::setConstantRefresh(m_ctx, m_activeEditor->requiresConstantRefresh()); } e->draw(m_sctx); m_activeEditorOnLastDraw = e.get(); diff --git a/src/olympic/studio/applib/src/studioapp.hpp b/src/olympic/studio/applib/src/studioapp.hpp index 5a32c7b..30ae799 100644 --- a/src/olympic/studio/applib/src/studioapp.hpp +++ b/src/olympic/studio/applib/src/studioapp.hpp @@ -50,8 +50,6 @@ class StudioUI: public ox::SignalHandler { public: explicit StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcept; - void update() noexcept; - void handleKeyEvent(turbine::Key, bool down) noexcept; [[nodiscard]] diff --git a/src/olympic/turbine/include/turbine/gfx.hpp b/src/olympic/turbine/include/turbine/gfx.hpp index 0d2b135..7e863cb 100644 --- a/src/olympic/turbine/include/turbine/gfx.hpp +++ b/src/olympic/turbine/include/turbine/gfx.hpp @@ -43,6 +43,12 @@ ox::Bounds getWindowBounds(Context &ctx) noexcept; ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept; -void setConstantRefresh(Context &ctx, bool r) noexcept; +/** + * Tells Turbine to refresh the screen within the specified period of time. + * If the requested value is greater than the current value, the call has no effect. + * @param ctx - Context + * @param ms - milliseconds + */ +void setRefreshWithin(Context &ctx, int ms) noexcept; } diff --git a/src/olympic/turbine/src/gba/turbine.cpp b/src/olympic/turbine/src/gba/turbine.cpp index d67e9d4..aed5fb5 100644 --- a/src/olympic/turbine/src/gba/turbine.cpp +++ b/src/olympic/turbine/src/gba/turbine.cpp @@ -71,7 +71,7 @@ ox::Result init( void shutdown(Context&) noexcept { } -uint64_t ticksMs(Context&) noexcept { +uint64_t ticksMs(Context const&) noexcept { return g_timerMs; } diff --git a/src/olympic/turbine/src/glfw/context.hpp b/src/olympic/turbine/src/glfw/context.hpp index 6a08a7d..6a6cd1d 100644 --- a/src/olympic/turbine/src/glfw/context.hpp +++ b/src/olympic/turbine/src/glfw/context.hpp @@ -22,8 +22,7 @@ class Context { int uninterruptedRefreshes = 3; ox::UPtr clipboard; struct GLFWwindow *window = nullptr; - // sets screen refresh to constant instead of only on event - bool constantRefresh = true; + int refreshWithinMs = 0; ox::Vector drawers; int64_t startTime = 0; uint64_t wakeupTime = 0; diff --git a/src/olympic/turbine/src/glfw/gfx.cpp b/src/olympic/turbine/src/glfw/gfx.cpp index e3883f2..9eeef90 100644 --- a/src/olympic/turbine/src/glfw/gfx.cpp +++ b/src/olympic/turbine/src/glfw/gfx.cpp @@ -260,8 +260,8 @@ ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept { return {}; } -void setConstantRefresh(Context &ctx, bool r) noexcept { - ctx.constantRefresh = r; +void setRefreshWithin(Context &ctx, int ms) noexcept { + ctx.refreshWithinMs = ox::min(ms, ctx.refreshWithinMs); } } diff --git a/src/olympic/turbine/src/glfw/turbine.cpp b/src/olympic/turbine/src/glfw/turbine.cpp index 7003e86..2865423 100644 --- a/src/olympic/turbine/src/glfw/turbine.cpp +++ b/src/olympic/turbine/src/glfw/turbine.cpp @@ -69,6 +69,7 @@ static void tickFps(Context &ctx, uint64_t nowMs) noexcept { ox::Error run(Context &ctx) noexcept { int sleepTime = 0; while (!glfwWindowShouldClose(ctx.window)) { + ctx.refreshWithinMs = 10 * 1000; // refresh within 10 seconds glfwPollEvents(); auto const ticks = ticksMs(ctx); if (ctx.wakeupTime <= ticks) { @@ -79,15 +80,16 @@ ox::Error run(Context &ctx) noexcept { ctx.wakeupTime = ~uint64_t(0); } } else { - sleepTime = 10; + sleepTime = static_cast(ctx.wakeupTime - ticks); } tickFps(ctx, ticks); draw(ctx); - if (!ctx.constantRefresh) { + auto const realSleepTime = ox::min(ctx.refreshWithinMs, sleepTime); + if (realSleepTime) { if (ctx.uninterruptedRefreshes) { --ctx.uninterruptedRefreshes; } else { - glfwWaitEventsTimeout(sleepTime); + glfwWaitEventsTimeout(static_cast(realSleepTime) / 1000); } } }