From 52f5e8eb0a835ebf80b468874ece8d4ffa8057e2 Mon Sep 17 00:00:00 2001 From: William JCM Date: Wed, 18 Aug 2021 16:53:29 +0200 Subject: [PATCH] SaveTool: add a frame limiter. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FPS slider isn't the most accurate, but it just works™. Closes #10. --- src/SaveTool/SaveTool.cpp | 43 ++++++++++++++++++++++++++ src/SaveTool/SaveTool.h | 7 +++++ src/SaveTool/SaveTool_drawMainMenu.cpp | 42 +++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/src/SaveTool/SaveTool.cpp b/src/SaveTool/SaveTool.cpp index e95aff6..de7f41b 100644 --- a/src/SaveTool/SaveTool.cpp +++ b/src/SaveTool/SaveTool.cpp @@ -136,6 +136,19 @@ SaveTool::SaveTool(const Arguments& arguments): initialiseConfiguration(); + switch(_framelimit) { + case Framelimit::Vsync: + setSwapInterval(1); + break; + case Framelimit::HalfVsync: + setSwapInterval(2); + break; + case Framelimit::FpsCap: + setSwapInterval(0); + setMinimalLoopPeriod(1000/_fpsCap); + break; + } + if(_checkUpdatesOnStartup) { _thread = std::thread{[this]{ checkForUpdates(); }}; _queue.addToast(Toast::Type::Default, "Checking for updates..."); @@ -148,6 +161,19 @@ SaveTool::~SaveTool() { _conf.setValue("cheat_mode", _cheatMode); _conf.setValue("unsafe_mode", _unsafeMode); _conf.setValue("startup_update_check", _checkUpdatesOnStartup); + + switch(_framelimit) { + case Framelimit::Vsync: + _conf.setValue("frame_limit", "vsync"); + break; + case Framelimit::HalfVsync: + _conf.setValue("frame_limit", "half_vsync"); + break; + case Framelimit::FpsCap: + _conf.setValue("frame_limit", _fpsCap); + break; + } + _conf.save(); } @@ -379,6 +405,23 @@ void SaveTool::initialiseConfiguration() { _conf.setValue("startup_update_check", _checkUpdatesOnStartup); } + if(_conf.hasValue("frame_limit")) { + std::string frame_limit = _conf.value("frame_limit"); + if(frame_limit == "vsync") { + _framelimit = Framelimit::Vsync; + } + else if(frame_limit == "half_vsync") { + _framelimit = Framelimit::HalfVsync; + } + else { + _framelimit = Framelimit::FpsCap; + _fpsCap = std::stoul(frame_limit); + } + } + else { + _conf.setValue("frame_limit", "vsync"); + } + _conf.save(); } diff --git a/src/SaveTool/SaveTool.h b/src/SaveTool/SaveTool.h index 7577848..9e727b8 100644 --- a/src/SaveTool/SaveTool.h +++ b/src/SaveTool/SaveTool.h @@ -197,6 +197,13 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener }; Containers::StaticArray<2, efsw::WatchID> _watchIDs; + enum class Framelimit: UnsignedByte { + Vsync, + HalfVsync, + FpsCap + } _framelimit{Framelimit::Vsync}; + UnsignedInt _fpsCap{60}; + bool _checkUpdatesOnStartup{true}; bool _unsafeMode{false}; diff --git a/src/SaveTool/SaveTool_drawMainMenu.cpp b/src/SaveTool/SaveTool_drawMainMenu.cpp index 40513d9..9b36521 100644 --- a/src/SaveTool/SaveTool_drawMainMenu.cpp +++ b/src/SaveTool/SaveTool_drawMainMenu.cpp @@ -55,6 +55,48 @@ void SaveTool::drawMainMenu() { ImGui::Separator(); if(ImGui::BeginMenu(ICON_FA_COG " Settings")) { + ImGui::AlignTextToFramePadding(); + ImGui::TextUnformatted("Frame limiter:"); + ImGui::SameLine(); + + static UnsignedByte selection = static_cast(_framelimit); + static const char* framelimit_labels[3] = { + "V-sync", + "Half V-sync", + "FPS cap, no V-sync" + }; + + ImGui::SetNextItemWidth(150.0f); + if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[selection])) { + if(ImGui::Selectable(framelimit_labels[0], _framelimit == Framelimit::Vsync)) { + selection = 0; + _framelimit = Framelimit::Vsync; + setSwapInterval(1); + } + if(ImGui::Selectable(framelimit_labels[1], _framelimit == Framelimit::HalfVsync)) { + selection = 1; + _framelimit = Framelimit::HalfVsync; + setSwapInterval(2); + } + if(ImGui::Selectable(framelimit_labels[2], _framelimit == Framelimit::FpsCap)) { + selection = 2; + _framelimit = Framelimit::FpsCap; + setSwapInterval(0); + setMinimalLoopPeriod(1000 / _fpsCap); + } + + ImGui::EndCombo(); + } + + if(_framelimit == Framelimit::FpsCap) { + static constexpr UnsignedInt min_fps = 15; + static constexpr UnsignedInt max_fps = 150; + + if(ImGui::SliderScalar("##FpsSlider", ImGuiDataType_U32, &_fpsCap, &min_fps, &max_fps, "%u FPS", ImGuiSliderFlags_AlwaysClamp)) { + setMinimalLoopPeriod(1000 / _fpsCap); + } + } + ImGui::Checkbox("Cheat mode", &_cheatMode); ImGui::SameLine(); ImGui::AlignTextToFramePadding();