From 51510a2650af3b2a1fdf297b0dd0ceba67674381 Mon Sep 17 00:00:00 2001 From: narknon <73571427+narknon@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:36:11 -0500 Subject: [PATCH 1/4] Change ModInt32 to use int in ctor; add ModSliderInt32 --- src/Mod.hpp | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Mod.hpp b/src/Mod.hpp index c4d09a15..e8147496 100644 --- a/src/Mod.hpp +++ b/src/Mod.hpp @@ -177,12 +177,12 @@ class ModInt32 : public ModValue { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, uint32_t default_value = 0) { + static auto create(std::string_view config_name, int32_t default_value = 0) { return std::make_unique(config_name, default_value); } - ModInt32(std::string_view config_name, uint32_t default_value = 0) - : ModValue{ config_name, static_cast(default_value) } + ModInt32(std::string_view config_name, int32_t default_value = 0) + : ModValue{ config_name, default_value } { } @@ -199,6 +199,43 @@ class ModInt32 : public ModValue { } }; +class ModSliderInt32 : public ModInt32 { +public: + using Ptr = std::unique_ptr; + + static auto create(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0) { + return std::make_unique(config_name, mn, mx, default_value); + } + + ModSliderInt32(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0) + : ModInt32{ config_name, default_value }, + m_int_range{ mn, mx } + { + } + + bool draw(std::string_view name) override { + ImGui::PushID(this); + auto ret = ImGui::SliderInt(name.data(), &m_value, m_int_range.min, m_int_range.max); + ImGui::PopID(); + + return ret; + } + + void draw_value(std::string_view name) override { + ImGui::Text("%s: %i [%i, %i]", name.data(), m_value, m_int_range.min, m_int_range.max); + } + + auto& range() { + return m_int_range; + } + +protected: + struct SliderIntRange { + int min; + int max; + }m_int_range; +}; + class ModCombo : public ModValue { public: using Ptr = std::unique_ptr; From 8c7e2011d9d52215d49e4dcc9a0af14af52e1fdb Mon Sep 17 00:00:00 2001 From: narknon <73571427+narknon@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:35:10 -0500 Subject: [PATCH 2/4] Add API for advanced view settings options, including for sidebar entries --- src/Framework.cpp | 37 +++--- src/Framework.hpp | 30 ++++- src/Mod.hpp | 249 ++++++++++++++++++++++---------------- src/mods/PluginLoader.hpp | 1 + src/mods/UObjectHook.hpp | 1 + src/mods/VR.hpp | 42 +++---- 6 files changed, 220 insertions(+), 140 deletions(-) diff --git a/src/Framework.cpp b/src/Framework.cpp index e33b4585..b9c189db 100644 --- a/src/Framework.cpp +++ b/src/Framework.cpp @@ -1158,6 +1158,11 @@ void Framework::draw_ui() { ImGui::Text("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Allows mouse and keyboard inputs to register to the game while the UI is focused."); + ImGui::Checkbox("Show Advanced Options", &m_advanced_view_enabled); + ImGui::SameLine(); + ImGui::Text("(?)"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Show additional options for greater control over various settings."); if (m_mods_fully_initialized) { if (ImGui::Button("Reset to Default Settings")) { @@ -1180,7 +1185,7 @@ void Framework::draw_ui() { ImGui::Columns(1); // Mods: - std::vector sidebar_entries{"About"}; + sidebar_entries.insert(sidebar_entries.begin(), {"About", false}); if (ImGui::BeginTable("UEVRTable", 2, ImGuiTableFlags_::ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_::ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_::ImGuiTableFlags_SizingFixedFit)) { ImGui::TableSetupColumn("UEVRLeftPaneColumn", ImGuiTableColumnFlags_WidthFixed, 150.0f); @@ -1221,25 +1226,27 @@ void Framework::draw_ui() { sidebar_entries.insert(sidebar_entries.end(), entries.begin(), entries.end()); } else { mod_sidebar_ranges.push_back(Info{sidebar_entries.size(), sidebar_entries.size() + 1, mod, false}); - sidebar_entries.push_back(mod->get_name().data()); + sidebar_entries.push_back({mod->get_name().data(), mod->is_advanced_mod()} ); } } for (size_t i = 1; i < sidebar_entries.size(); ++i) { - for (const auto& range : mod_sidebar_ranges) { - if (i == range.mn) { - // Set first entry as default ("Runtime" entry of VR mod) - if (range.has_sidebar_entries && !m_sidebar_state.initialized) { - m_sidebar_state.selected_entry = i; - m_sidebar_state.initialized = true; - ImGui::SetWindowFocus("UEVRRightPane"); - } + if (m_advanced_view_enabled || !sidebar_entries[i].m_advanced_entry) { + for (const auto& range : mod_sidebar_ranges) { + if (i == range.mn) { + // Set first entry as default ("Runtime" entry of VR mod) + if (range.has_sidebar_entries && !m_sidebar_state.initialized) { + m_sidebar_state.selected_entry = i; + m_sidebar_state.initialized = true; + ImGui::SetWindowFocus("UEVRRightPane"); + } - ImGui::Text(range.mod->get_name().data()); + ImGui::Text(range.mod->get_name().data()); + } } - } - dcs(sidebar_entries[i].c_str(), i); + dcs(sidebar_entries[i].m_label.c_str(), i); + } } bool wants_focus_right = false; @@ -1276,7 +1283,7 @@ void Framework::draw_ui() { for (const auto& range : mod_sidebar_ranges) { if (m_sidebar_state.selected_entry >= range.mn && m_sidebar_state.selected_entry < range.mx) { if (range.has_sidebar_entries) { - range.mod->on_draw_sidebar_entry(sidebar_entries[m_sidebar_state.selected_entry]); + range.mod->on_draw_sidebar_entry(sidebar_entries[m_sidebar_state.selected_entry].m_label); } else { range.mod->on_draw_ui(); } @@ -1341,6 +1348,8 @@ void Framework::draw_ui() { if (m_last_draw_ui && !m_draw_ui) { m_windows_message_hook->window_toggle_cursor(m_cursor_state); } + + sidebar_entries.clear(); } void Framework::draw_about() { diff --git a/src/Framework.hpp b/src/Framework.hpp index 155e9bdd..460e2fbe 100644 --- a/src/Framework.hpp +++ b/src/Framework.hpp @@ -57,6 +57,12 @@ class UEVRSharedMemory { Data* m_data{}; }; + +struct SidebarEntryInfo { + std::string m_label{}; + bool m_advanced_entry{false}; +}; + // Global facilitator class Framework { private: @@ -190,7 +196,13 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - ++m_sidebar_state.selected_entry; + int32_t selected_entry_local = m_sidebar_state.selected_entry + 1; + if (!m_advanced_view_enabled) { + while (sidebar_entries[selected_entry_local].m_advanced_entry) { + ++selected_entry_local; + } + } + m_sidebar_state.selected_entry = selected_entry_local; m_last_page_inc_time = now; } @@ -201,7 +213,13 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - --m_sidebar_state.selected_entry; + int32_t selected_entry_local = m_sidebar_state.selected_entry - 1; + if (!m_advanced_view_enabled) { + while (sidebar_entries[selected_entry_local].m_advanced_entry) { + --selected_entry_local; + } + } + m_sidebar_state.selected_entry = selected_entry_local; m_last_page_dec_time = now; } @@ -211,6 +229,12 @@ class Framework { void update_fonts(); void invalidate_device_objects(); +public: + bool is_advanced_view_enabled() { + return m_advanced_view_enabled; + } + +private: void draw_ui(); void draw_about(); @@ -241,6 +265,7 @@ class Framework { // UI bool m_has_frame{false}; bool m_wants_device_object_cleanup{false}; + bool m_advanced_view_enabled{false}; bool m_draw_ui{true}; bool m_last_draw_ui{m_draw_ui}; bool m_is_ui_focused{false}; @@ -248,6 +273,7 @@ class Framework { bool m_cursor_state_changed{true}; bool m_ui_option_transparent{true}; bool m_ui_passthrough{false}; + std::vector sidebar_entries{}; ImVec2 m_last_window_pos{}; ImVec2 m_last_window_size{}; diff --git a/src/Mod.hpp b/src/Mod.hpp index e8147496..9f40ec73 100644 --- a/src/Mod.hpp +++ b/src/Mod.hpp @@ -33,14 +33,15 @@ class ModValue : public IModValue { public: using Ptr = std::unique_ptr>; - static auto create(std::string_view config_name, T default_value = T{}) { - return std::make_unique>(config_name, default_value); + static auto create(std::string_view config_name, T default_value = T{}, bool advanced_option = false) { + return std::make_unique>(config_name, default_value, advanced_option); } - ModValue(std::string_view config_name, T default_value) + ModValue(std::string_view config_name, T default_value, bool advanced_option = false) : m_config_name{ config_name }, m_value{ default_value }, - m_default_value{ default_value } + m_default_value{ default_value }, + m_advanced_option{ advanced_option } { } @@ -79,35 +80,49 @@ class ModValue : public IModValue { return m_config_name; } + const auto& is_advanced_option() const { + return m_advanced_option; + } + + auto should_draw_option() -> bool { + return g_framework->is_advanced_view_enabled() || !this->m_advanced_option; + } + protected: T m_value{}; - T m_default_value{}; - std::string m_config_name{ "Default_ModValue" }; + const T m_default_value{}; + const std::string m_config_name{ "Default_ModValue" }; + const bool m_advanced_option{false}; }; class ModToggle : public ModValue { public: using Ptr = std::unique_ptr; - ModToggle(std::string_view config_name, bool default_value) - : ModValue{ config_name, default_value } + ModToggle(std::string_view config_name, bool default_value, bool advanced_option = false) + : ModValue{ config_name, default_value, advanced_option } { } - static auto create(std::string_view config_name, bool default_value = false) { - return std::make_unique(config_name, default_value); + static auto create(std::string_view config_name, bool default_value = false, bool advanced_option = false) { + return std::make_unique(config_name, default_value, advanced_option); } - + bool draw(std::string_view name) override { - ImGui::PushID(this); - auto ret = ImGui::Checkbox(name.data(), &m_value); - ImGui::PopID(); + if (should_draw_option()) { + ImGui::PushID(this); + auto ret = ImGui::Checkbox(name.data(), &m_value); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { - ImGui::Text("%s: %i", name.data(), m_value); + if (should_draw_option()) { + ImGui::Text("%s: %i", name.data(), m_value); + } } bool toggle() { @@ -119,23 +134,29 @@ class ModFloat : public ModValue { public: using Ptr = std::unique_ptr; - ModFloat(std::string_view config_name, float default_value) - : ModValue{ config_name, default_value } { } + ModFloat(std::string_view config_name, float default_value, bool advanced_option = false) + : ModValue{ config_name, default_value, advanced_option } { } - static auto create(std::string_view config_name, float default_value = 0.0f) { - return std::make_unique(config_name, default_value); + static auto create(std::string_view config_name, float default_value = 0.0f, bool advanced_option = false) { + return std::make_unique(config_name, default_value, advanced_option); } bool draw(std::string_view name) override { - ImGui::PushID(this); - auto ret = ImGui::InputFloat(name.data(), &m_value); - ImGui::PopID(); + if (should_draw_option()) { + ImGui::PushID(this); + auto ret = ImGui::InputFloat(name.data(), &m_value); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { - ImGui::Text("%s: %f", name.data(), m_value); + if (should_draw_option()) { + ImGui::Text("%s: %f", name.data(), m_value); + } + } }; @@ -143,26 +164,31 @@ class ModSlider : public ModFloat { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, float mn = 0.0f, float mx = 1.0f, float default_value = 0.0f) { - return std::make_unique(config_name, mn, mx, default_value); + static auto create(std::string_view config_name, float mn = 0.0f, float mx = 1.0f, float default_value = 0.0f, bool advanced_option = false) { + return std::make_unique(config_name, mn, mx, default_value, advanced_option); } - ModSlider(std::string_view config_name, float mn = 0.0f, float mx = 1.0f, float default_value = 0.0f) - : ModFloat{ config_name, default_value }, + ModSlider(std::string_view config_name, float mn = 0.0f, float mx = 1.0f, float default_value = 0.0f, bool advanced_option = false) + : ModFloat{ config_name, default_value, advanced_option }, m_range{ mn, mx } { } bool draw(std::string_view name) override { - ImGui::PushID(this); - auto ret = ImGui::SliderFloat(name.data(), &m_value, m_range.x, m_range.y); - ImGui::PopID(); + if (should_draw_option()) { + ImGui::PushID(this); + auto ret = ImGui::SliderFloat(name.data(), &m_value, m_range.x, m_range.y); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { - ImGui::Text("%s: %f [%f, %f]", name.data(), m_value, m_range.x, m_range.y); + if (should_draw_option()) { + ImGui::Text("%s: %f [%f, %f]", name.data(), m_value, m_range.x, m_range.y); + } } auto& range() { @@ -177,25 +203,30 @@ class ModInt32 : public ModValue { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, int32_t default_value = 0) { - return std::make_unique(config_name, default_value); + static auto create(std::string_view config_name, int32_t default_value = 0, bool advanced_option = false) { + return std::make_unique(config_name, default_value, advanced_option); } - ModInt32(std::string_view config_name, int32_t default_value = 0) - : ModValue{ config_name, default_value } + ModInt32(std::string_view config_name, int32_t default_value = 0, bool advanced_option = false) + : ModValue{ config_name, default_value, advanced_option } { } bool draw(std::string_view name) override { - ImGui::PushID(this); - auto ret = ImGui::InputInt(name.data(), &m_value); - ImGui::PopID(); + if (should_draw_option()) { + ImGui::PushID(this); + auto ret = ImGui::InputInt(name.data(), &m_value); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { - ImGui::Text("%s: %i", name.data(), m_value); + if (should_draw_option()) { + ImGui::Text("%s: %i", name.data(), m_value); + } } }; @@ -203,22 +234,25 @@ class ModSliderInt32 : public ModInt32 { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0) { - return std::make_unique(config_name, mn, mx, default_value); + static auto create(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0, bool advanced_option = false) { + return std::make_unique(config_name, mn, mx, default_value, advanced_option); } - ModSliderInt32(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0) - : ModInt32{ config_name, default_value }, + ModSliderInt32(std::string_view config_name, int32_t mn = -100, int32_t mx = 100, int32_t default_value = 0, bool advanced_option = false) + : ModInt32{ config_name, default_value, advanced_option }, m_int_range{ mn, mx } { } bool draw(std::string_view name) override { - ImGui::PushID(this); - auto ret = ImGui::SliderInt(name.data(), &m_value, m_int_range.min, m_int_range.max); - ImGui::PopID(); + if (should_draw_option()) { + ImGui::PushID(this); + auto ret = ImGui::SliderInt(name.data(), &m_value, m_int_range.min, m_int_range.max); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { @@ -240,12 +274,12 @@ class ModCombo : public ModValue { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, std::vector options, int32_t default_value = 0) { - return std::make_unique(config_name, options, default_value); + static auto create(std::string_view config_name, std::vector options, int32_t default_value = 0, bool advanced_option = false) { + return std::make_unique(config_name, options, default_value, advanced_option); } - ModCombo(std::string_view config_name, const std::vector& options, int32_t default_value = 0) - : ModValue{ config_name, default_value }, + ModCombo(std::string_view config_name, const std::vector& options, int32_t default_value = 0, bool advanced_option = false) + : ModValue{ config_name, default_value, advanced_option }, m_options_stdstr{ options } { for (auto& o : m_options_stdstr) { @@ -254,20 +288,25 @@ class ModCombo : public ModValue { } bool draw(std::string_view name) override { - // clamp m_value to valid range - m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); + if (should_draw_option()) { + // clamp m_value to valid range + m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); - ImGui::PushID(this); - auto ret = ImGui::Combo(name.data(), &m_value, m_options.data(), static_cast(m_options.size())); - ImGui::PopID(); + ImGui::PushID(this); + auto ret = ImGui::Combo(name.data(), &m_value, m_options.data(), static_cast(m_options.size())); + ImGui::PopID(); - return ret; + return ret; + } + return false; } void draw_value(std::string_view name) override { - m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); + if (should_draw_option()) { + m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); - ImGui::Text("%s: %s", name.data(), m_options[m_value]); + ImGui::Text("%s: %s", name.data(), m_options[m_value]); + } } void config_load(const utility::Config& cfg, bool set_defaults) override { @@ -275,7 +314,7 @@ class ModCombo : public ModValue { if (m_value >= (int32_t)m_options.size()) { if (!m_options.empty()) { - m_value = m_options.size() - 1; + m_value = (int32_t)m_options.size() - 1; } else { m_value = 0; } @@ -299,63 +338,66 @@ class ModKey: public ModInt32 { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, int32_t default_value = UNBOUND_KEY) { + static auto create(std::string_view config_name, int32_t default_value = UNBOUND_KEY, bool advanced_option = false) { return std::make_unique(config_name, default_value); } - ModKey(std::string_view config_name, int32_t default_value = UNBOUND_KEY) - : ModInt32{ config_name, static_cast(default_value) } + ModKey(std::string_view config_name, int32_t default_value = UNBOUND_KEY, bool advanced_option = false) + : ModInt32{ config_name, default_value, advanced_option } { } bool draw(std::string_view name) override { - if (name.empty()) { - return false; - } + if (should_draw_option()) { + if (name.empty()) { + return false; + } - ImGui::PushID(this); - ImGui::Button(name.data()); + ImGui::PushID(this); + ImGui::Button(name.data()); - if (ImGui::IsItemHovered() && ImGui::GetIO().MouseDown[0]) { - m_waiting_for_new_key = true; - } + if (ImGui::IsItemHovered() && ImGui::GetIO().MouseDown[0]) { + m_waiting_for_new_key = true; + } - if (m_waiting_for_new_key) { - const auto &keys = g_framework->get_keyboard_state(); - for (int32_t k{ 0 }; k < keys.size(); ++k) { - if (k == VK_LBUTTON || k == VK_RBUTTON) { - continue; + if (m_waiting_for_new_key) { + const auto &keys = g_framework->get_keyboard_state(); + for (int32_t k{ 0 }; k < keys.size(); ++k) { + if (k == VK_LBUTTON || k == VK_RBUTTON) { + continue; + } + + if (keys[k]) { + m_value = is_erase_key(k) ? UNBOUND_KEY : k; + m_waiting_for_new_key = false; + break; + } } - if (keys[k]) { - m_value = is_erase_key(k) ? UNBOUND_KEY : k; - m_waiting_for_new_key = false; - break; - } + ImGui::SameLine(); + ImGui::Text("Press any key..."); } - - ImGui::SameLine(); - ImGui::Text("Press any key..."); - } - else { - ImGui::SameLine(); - - if (m_value >= 0 && m_value <= 255) { - if (keycodes.contains(m_value)) { - ImGui::Text("%s", keycodes[m_value].c_str()); + else { + ImGui::SameLine(); + + if (m_value >= 0 && m_value <= 255) { + if (keycodes.contains(m_value)) { + ImGui::Text("%s", keycodes[m_value].c_str()); + } + else { + ImGui::Text("%i (Unknown)", m_value); + } } else { - ImGui::Text("%i (Unknown)", m_value); + ImGui::Text("Not bound"); } } - else { - ImGui::Text("Not bound"); - } - } - ImGui::PopID(); + ImGui::PopID(); - return true; + return true; + } + return false; } bool is_key_down() const { @@ -410,6 +452,7 @@ class Mod { virtual ~Mod() {}; virtual std::string_view get_name() const { return "UnknownMod"; }; + virtual bool is_advanced_mod() const { return false; }; // can be used for ModValues, like Mod_ValueName virtual std::string generate_name(std::string_view name) { return std::string{ get_name() } + "_" + name.data(); } @@ -417,7 +460,7 @@ class Mod { virtual std::optional on_initialize() { return std::nullopt; }; virtual std::optional on_initialize_d3d_thread() { return std::nullopt; }; - virtual std::vector get_sidebar_entries() { return {}; }; + virtual std::vector get_sidebar_entries() { return {}; }; // This gets called after updating stuff like keyboard/mouse input to imgui // can be used to override these inputs e.g. with a custom input system diff --git a/src/mods/PluginLoader.hpp b/src/mods/PluginLoader.hpp index 6c4f5deb..1115df21 100644 --- a/src/mods/PluginLoader.hpp +++ b/src/mods/PluginLoader.hpp @@ -22,6 +22,7 @@ class PluginLoader : public Mod { void early_init(); std::string_view get_name() const override { return "PluginLoader"; } + bool is_advanced_mod() const override { return true; } std::optional on_initialize_d3d_thread() override; void on_draw_ui() override; diff --git a/src/mods/UObjectHook.hpp b/src/mods/UObjectHook.hpp index 63c3549d..9622a457 100644 --- a/src/mods/UObjectHook.hpp +++ b/src/mods/UObjectHook.hpp @@ -47,6 +47,7 @@ class UObjectHook : public Mod { protected: std::string_view get_name() const override { return "UObjectHook"; }; + bool is_advanced_mod() const override { return true; } void on_pre_engine_tick(sdk::UGameEngine* engine, float delta) override; void on_draw_ui() override; diff --git a/src/mods/VR.hpp b/src/mods/VR.hpp index 6b64bdce..64018c3a 100644 --- a/src/mods/VR.hpp +++ b/src/mods/VR.hpp @@ -87,15 +87,15 @@ class VR : public Mod { return clean_initialize(); } - std::vector get_sidebar_entries() override { + std::vector get_sidebar_entries() override { return { - "Runtime", - "Unreal", - "Input", - "Camera", - "Console/CVars", - "Compatibility", - "Debug" + {"Runtime", false}, + {"Unreal", false}, + {"Input", false}, + {"Camera", false}, + {"Console/CVars", true}, + {"Compatibility", true}, + {"Debug", true}, }; } @@ -715,18 +715,18 @@ class VR : public Mod { const ModCombo::Ptr m_rendering_method{ ModCombo::create(generate_name("RenderingMethod"), s_rendering_method_names) }; const ModCombo::Ptr m_synced_afr_method{ ModCombo::create(generate_name("SyncedSequentialMethod"), s_synced_afr_method_names, 1) }; - const ModToggle::Ptr m_extreme_compat_mode{ ModToggle::create(generate_name("ExtremeCompatibilityMode"), false) }; + const ModToggle::Ptr m_extreme_compat_mode{ ModToggle::create(generate_name("ExtremeCompatibilityMode"), false, true) }; const ModToggle::Ptr m_uncap_framerate{ ModToggle::create(generate_name("UncapFramerate"), true) }; const ModToggle::Ptr m_disable_blur_widgets{ ModToggle::create(generate_name("DisableBlurWidgets"), true) }; - const ModToggle::Ptr m_disable_hdr_compositing{ ModToggle::create(generate_name("DisableHDRCompositing"), true) }; - const ModToggle::Ptr m_disable_hzbocclusion{ ModToggle::create(generate_name("DisableHZBOcclusion"), true) }; - const ModToggle::Ptr m_disable_instance_culling{ ModToggle::create(generate_name("DisableInstanceCulling"), true) }; + const ModToggle::Ptr m_disable_hdr_compositing{ ModToggle::create(generate_name("DisableHDRCompositing"), true, true) }; + const ModToggle::Ptr m_disable_hzbocclusion{ ModToggle::create(generate_name("DisableHZBOcclusion"), true, true) }; + const ModToggle::Ptr m_disable_instance_culling{ ModToggle::create(generate_name("DisableInstanceCulling"), true, true) }; const ModToggle::Ptr m_desktop_fix{ ModToggle::create(generate_name("DesktopRecordingFix_V2"), true) }; const ModToggle::Ptr m_enable_gui{ ModToggle::create(generate_name("EnableGUI"), true) }; const ModToggle::Ptr m_enable_depth{ ModToggle::create(generate_name("EnableDepth"), false) }; const ModToggle::Ptr m_decoupled_pitch{ ModToggle::create(generate_name("DecoupledPitch"), false) }; const ModToggle::Ptr m_decoupled_pitch_ui_adjust{ ModToggle::create(generate_name("DecoupledPitchUIAdjust"), true) }; - const ModToggle::Ptr m_load_blueprint_code{ ModToggle::create(generate_name("LoadBlueprintCode"), false) }; + const ModToggle::Ptr m_load_blueprint_code{ ModToggle::create(generate_name("LoadBlueprintCode"), false, true) }; const ModToggle::Ptr m_2d_screen_mode{ ModToggle::create(generate_name("2DScreenMode"), false) }; const ModToggle::Ptr m_roomscale_movement{ ModToggle::create(generate_name("RoomscaleMovement"), false) }; const ModToggle::Ptr m_roomscale_movement_actor_rotation{ ModToggle::create(generate_name("RoomscaleMovementActorRotation"), false) }; @@ -735,7 +735,7 @@ class VR : public Mod { const ModCombo::Ptr m_aim_method{ ModCombo::create(generate_name("AimMethod"), s_aim_method_names, AimMethod::GAME) }; const ModCombo::Ptr m_movement_orientation{ ModCombo::create(generate_name("MovementOrientation"), s_aim_method_names, AimMethod::GAME) }; AimMethod m_previous_aim_method{ AimMethod::GAME }; - const ModToggle::Ptr m_aim_interp{ ModToggle::create(generate_name("AimInterp"), true) }; + const ModToggle::Ptr m_aim_interp{ ModToggle::create(generate_name("AimInterp"), true, true) }; const ModSlider::Ptr m_aim_speed{ ModSlider::create(generate_name("AimSpeed"), 0.01f, 25.0f, 15.0f) }; const ModToggle::Ptr m_dpad_shifting{ ModToggle::create(generate_name("DPadShifting"), true) }; const ModCombo::Ptr m_dpad_shifting_method{ ModCombo::create(generate_name("DPadShiftingMethod"), s_dpad_method_names, DPadMethod::RIGHT_TOUCH) }; @@ -753,16 +753,16 @@ class VR : public Mod { const ModToggle::Ptr m_ghosting_fix{ ModToggle::create(generate_name("GhostingFix"), false) }; - const ModSlider::Ptr m_custom_z_near{ ModSlider::create(generate_name("CustomZNear"), 0.001f, 100.0f, 0.01f) }; - const ModToggle::Ptr m_custom_z_near_enabled{ ModToggle::create(generate_name("EnableCustomZNear"), false) }; + const ModSlider::Ptr m_custom_z_near{ ModSlider::create(generate_name("CustomZNear"), 0.001f, 100.0f, 0.01f, true) }; + const ModToggle::Ptr m_custom_z_near_enabled{ ModToggle::create(generate_name("EnableCustomZNear"), false, true) }; - const ModToggle::Ptr m_splitscreen_compatibility_mode{ ModToggle::create(generate_name("Compatibility_SplitScreen"), false) }; - const ModInt32::Ptr m_splitscreen_view_index{ ModInt32::create(generate_name("SplitscreenViewIndex"), 0) }; + const ModToggle::Ptr m_splitscreen_compatibility_mode{ ModToggle::create(generate_name("Compatibility_SplitScreen"), false, true) }; + const ModInt32::Ptr m_splitscreen_view_index{ ModInt32::create(generate_name("SplitscreenViewIndex"), 0, true) }; - const ModToggle::Ptr m_sceneview_compatibility_mode{ ModToggle::create(generate_name("Compatibility_SceneView"), false) }; + const ModToggle::Ptr m_sceneview_compatibility_mode{ ModToggle::create(generate_name("Compatibility_SceneView"), false, true) }; - const ModToggle::Ptr m_compatibility_skip_pip{ ModToggle::create(generate_name("Compatibility_SkipPostInitProperties"), false) }; - const ModToggle::Ptr m_compatibility_skip_uobjectarray_init{ ModToggle::create(generate_name("Compatibility_SkipUObjectArrayInit"), false) }; + const ModToggle::Ptr m_compatibility_skip_pip{ ModToggle::create(generate_name("Compatibility_SkipPostInitProperties"), false, true) }; + const ModToggle::Ptr m_compatibility_skip_uobjectarray_init{ ModToggle::create(generate_name("Compatibility_SkipUObjectArrayInit"), false, true) }; struct DecoupledPitchData { mutable std::shared_mutex mtx{}; From abf6460cc97e52cfae9676d7f4b197ce70c5fec8 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 11 Dec 2023 09:49:52 -0800 Subject: [PATCH 3/4] Adv: Style fixes, logic simplification --- src/Framework.cpp | 27 ++++-- src/Framework.hpp | 31 +++---- src/Mod.hpp | 211 +++++++++++++++++++++++++--------------------- 3 files changed, 145 insertions(+), 124 deletions(-) diff --git a/src/Framework.cpp b/src/Framework.cpp index b9c189db..7bc70180 100644 --- a/src/Framework.cpp +++ b/src/Framework.cpp @@ -1185,7 +1185,9 @@ void Framework::draw_ui() { ImGui::Columns(1); // Mods: - sidebar_entries.insert(sidebar_entries.begin(), {"About", false}); + auto& sidebar_entries = m_sidebar_state.entries; + sidebar_entries.clear(); + sidebar_entries.emplace_back("About", false); if (ImGui::BeginTable("UEVRTable", 2, ImGuiTableFlags_::ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_::ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_::ImGuiTableFlags_SizingFixedFit)) { ImGui::TableSetupColumn("UEVRLeftPaneColumn", ImGuiTableColumnFlags_WidthFixed, 150.0f); @@ -1219,14 +1221,29 @@ void Framework::draw_ui() { std::vector mod_sidebar_ranges{}; for (auto& mod : m_mods->get_mods()) { + if (mod->is_advanced_mod() && !m_advanced_view_enabled) { + continue; + } + auto entries = mod->get_sidebar_entries(); if (!entries.empty()) { - mod_sidebar_ranges.push_back(Info{sidebar_entries.size(), sidebar_entries.size() + entries.size(), mod, true}); - sidebar_entries.insert(sidebar_entries.end(), entries.begin(), entries.end()); + size_t displayed_entries = 0; + for (auto& entry : entries) { + if (entry.m_advanced_entry && !m_advanced_view_enabled) { + continue; + } + + sidebar_entries.emplace_back(entry.m_label.c_str(), entry.m_advanced_entry); + ++displayed_entries; + } + + if (displayed_entries > 0) { + mod_sidebar_ranges.push_back(Info{sidebar_entries.size() - displayed_entries, sidebar_entries.size(), mod, true}); + } } else { mod_sidebar_ranges.push_back(Info{sidebar_entries.size(), sidebar_entries.size() + 1, mod, false}); - sidebar_entries.push_back({mod->get_name().data(), mod->is_advanced_mod()} ); + sidebar_entries.emplace_back(mod->get_name().data(), mod->is_advanced_mod()); } } @@ -1348,8 +1365,6 @@ void Framework::draw_ui() { if (m_last_draw_ui && !m_draw_ui) { m_windows_message_hook->window_toggle_cursor(m_cursor_state); } - - sidebar_entries.clear(); } void Framework::draw_about() { diff --git a/src/Framework.hpp b/src/Framework.hpp index 460e2fbe..8b321f94 100644 --- a/src/Framework.hpp +++ b/src/Framework.hpp @@ -57,8 +57,9 @@ class UEVRSharedMemory { Data* m_data{}; }; - struct SidebarEntryInfo { + SidebarEntryInfo(std::string_view label, bool advanced) : m_label(label), m_advanced_entry(advanced) {} + std::string m_label{}; bool m_advanced_entry{false}; }; @@ -196,14 +197,8 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - int32_t selected_entry_local = m_sidebar_state.selected_entry + 1; - if (!m_advanced_view_enabled) { - while (sidebar_entries[selected_entry_local].m_advanced_entry) { - ++selected_entry_local; - } - } - m_sidebar_state.selected_entry = selected_entry_local; + ++m_sidebar_state.selected_entry; m_last_page_inc_time = now; } @@ -213,27 +208,20 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - int32_t selected_entry_local = m_sidebar_state.selected_entry - 1; - if (!m_advanced_view_enabled) { - while (sidebar_entries[selected_entry_local].m_advanced_entry) { - --selected_entry_local; - } - } - m_sidebar_state.selected_entry = selected_entry_local; + --m_sidebar_state.selected_entry; m_last_page_dec_time = now; } + bool is_advanced_view_enabled() const { + return m_advanced_view_enabled; + } + private: void consume_input(); void update_fonts(); void invalidate_device_objects(); -public: - bool is_advanced_view_enabled() { - return m_advanced_view_enabled; - } - private: void draw_ui(); void draw_about(); @@ -273,7 +261,6 @@ class Framework { bool m_cursor_state_changed{true}; bool m_ui_option_transparent{true}; bool m_ui_passthrough{false}; - std::vector sidebar_entries{}; ImVec2 m_last_window_pos{}; ImVec2 m_last_window_size{}; @@ -339,6 +326,8 @@ class Framework { struct { int32_t selected_entry{0}; bool initialized{false}; + + std::vector entries{}; } m_sidebar_state{}; template using ComPtr = Microsoft::WRL::ComPtr; diff --git a/src/Mod.hpp b/src/Mod.hpp index 9f40ec73..097f2c9c 100644 --- a/src/Mod.hpp +++ b/src/Mod.hpp @@ -80,11 +80,11 @@ class ModValue : public IModValue { return m_config_name; } - const auto& is_advanced_option() const { + bool is_advanced_option() const { return m_advanced_option; } - auto should_draw_option() -> bool { + bool should_draw_option() const { return g_framework->is_advanced_view_enabled() || !this->m_advanced_option; } @@ -109,20 +109,23 @@ class ModToggle : public ModValue { } bool draw(std::string_view name) override { - if (should_draw_option()) { - ImGui::PushID(this); - auto ret = ImGui::Checkbox(name.data(), &m_value); - ImGui::PopID(); - - return ret; + if (!should_draw_option()) { + return false; } - return false; + + ImGui::PushID(this); + auto ret = ImGui::Checkbox(name.data(), &m_value); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { - if (should_draw_option()) { - ImGui::Text("%s: %i", name.data(), m_value); + if (!should_draw_option()) { + return; } + + ImGui::Text("%s: %i", name.data(), m_value); } bool toggle() { @@ -142,21 +145,23 @@ class ModFloat : public ModValue { } bool draw(std::string_view name) override { - if (should_draw_option()) { - ImGui::PushID(this); - auto ret = ImGui::InputFloat(name.data(), &m_value); - ImGui::PopID(); - - return ret; + if (!should_draw_option()) { + return false; } - return false; + + ImGui::PushID(this); + auto ret = ImGui::InputFloat(name.data(), &m_value); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { - if (should_draw_option()) { - ImGui::Text("%s: %f", name.data(), m_value); + if (!should_draw_option()) { + return; } - + + ImGui::Text("%s: %f", name.data(), m_value); } }; @@ -175,20 +180,24 @@ class ModSlider : public ModFloat { } bool draw(std::string_view name) override { - if (should_draw_option()) { - ImGui::PushID(this); - auto ret = ImGui::SliderFloat(name.data(), &m_value, m_range.x, m_range.y); - ImGui::PopID(); - - return ret; + if (!should_draw_option()) { + return false; } - return false; + + + ImGui::PushID(this); + auto ret = ImGui::SliderFloat(name.data(), &m_value, m_range.x, m_range.y); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { - if (should_draw_option()) { - ImGui::Text("%s: %f [%f, %f]", name.data(), m_value, m_range.x, m_range.y); + if (!should_draw_option()) { + return; } + + ImGui::Text("%s: %f [%f, %f]", name.data(), m_value, m_range.x, m_range.y); } auto& range() { @@ -213,20 +222,23 @@ class ModInt32 : public ModValue { } bool draw(std::string_view name) override { - if (should_draw_option()) { - ImGui::PushID(this); - auto ret = ImGui::InputInt(name.data(), &m_value); - ImGui::PopID(); - - return ret; + if (!should_draw_option()) { + return false; } - return false; + + ImGui::PushID(this); + auto ret = ImGui::InputInt(name.data(), &m_value); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { - if (should_draw_option()) { - ImGui::Text("%s: %i", name.data(), m_value); + if (!should_draw_option()) { + return; } + + ImGui::Text("%s: %i", name.data(), m_value); } }; @@ -245,14 +257,15 @@ class ModSliderInt32 : public ModInt32 { } bool draw(std::string_view name) override { - if (should_draw_option()) { - ImGui::PushID(this); - auto ret = ImGui::SliderInt(name.data(), &m_value, m_int_range.min, m_int_range.max); - ImGui::PopID(); - - return ret; + if (!should_draw_option()) { + return false; } - return false; + + ImGui::PushID(this); + auto ret = ImGui::SliderInt(name.data(), &m_value, m_int_range.min, m_int_range.max); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { @@ -288,25 +301,28 @@ class ModCombo : public ModValue { } bool draw(std::string_view name) override { - if (should_draw_option()) { - // clamp m_value to valid range - m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); + if (!should_draw_option()) { + return false; + } - ImGui::PushID(this); - auto ret = ImGui::Combo(name.data(), &m_value, m_options.data(), static_cast(m_options.size())); - ImGui::PopID(); + // clamp m_value to valid range + m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); - return ret; - } - return false; + ImGui::PushID(this); + auto ret = ImGui::Combo(name.data(), &m_value, m_options.data(), static_cast(m_options.size())); + ImGui::PopID(); + + return ret; } void draw_value(std::string_view name) override { - if (should_draw_option()) { - m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); - - ImGui::Text("%s: %s", name.data(), m_options[m_value]); + if (!should_draw_option()) { + return; } + + m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); + + ImGui::Text("%s: %s", name.data(), m_options[m_value]); } void config_load(const utility::Config& cfg, bool set_defaults) override { @@ -348,56 +364,57 @@ class ModKey: public ModInt32 { } bool draw(std::string_view name) override { - if (should_draw_option()) { - if (name.empty()) { - return false; - } + if (!should_draw_option()) { + return false; + } - ImGui::PushID(this); - ImGui::Button(name.data()); + if (name.empty()) { + return false; + } - if (ImGui::IsItemHovered() && ImGui::GetIO().MouseDown[0]) { - m_waiting_for_new_key = true; - } + ImGui::PushID(this); + ImGui::Button(name.data()); + + if (ImGui::IsItemHovered() && ImGui::GetIO().MouseDown[0]) { + m_waiting_for_new_key = true; + } - if (m_waiting_for_new_key) { - const auto &keys = g_framework->get_keyboard_state(); - for (int32_t k{ 0 }; k < keys.size(); ++k) { - if (k == VK_LBUTTON || k == VK_RBUTTON) { - continue; - } - - if (keys[k]) { - m_value = is_erase_key(k) ? UNBOUND_KEY : k; - m_waiting_for_new_key = false; - break; - } + if (m_waiting_for_new_key) { + const auto &keys = g_framework->get_keyboard_state(); + for (int32_t k{ 0 }; k < keys.size(); ++k) { + if (k == VK_LBUTTON || k == VK_RBUTTON) { + continue; } - ImGui::SameLine(); - ImGui::Text("Press any key..."); + if (keys[k]) { + m_value = is_erase_key(k) ? UNBOUND_KEY : k; + m_waiting_for_new_key = false; + break; + } } - else { - ImGui::SameLine(); - - if (m_value >= 0 && m_value <= 255) { - if (keycodes.contains(m_value)) { - ImGui::Text("%s", keycodes[m_value].c_str()); - } - else { - ImGui::Text("%i (Unknown)", m_value); - } + + ImGui::SameLine(); + ImGui::Text("Press any key..."); + } + else { + ImGui::SameLine(); + + if (m_value >= 0 && m_value <= 255) { + if (keycodes.contains(m_value)) { + ImGui::Text("%s", keycodes[m_value].c_str()); } else { - ImGui::Text("Not bound"); + ImGui::Text("%i (Unknown)", m_value); } } + else { + ImGui::Text("Not bound"); + } + } - ImGui::PopID(); + ImGui::PopID(); - return true; - } - return false; + return true; } bool is_key_down() const { From 4c422474819b1d1863440ff1cb87c22a5e5feda3 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 11 Dec 2023 16:14:16 -0800 Subject: [PATCH 4/4] Adv: Make advanced view persistent --- src/Framework.cpp | 25 ++++++++++++++++++------- src/Framework.hpp | 5 +---- src/mods/FrameworkConfig.hpp | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Framework.cpp b/src/Framework.cpp index 7bc70180..c5977884 100644 --- a/src/Framework.cpp +++ b/src/Framework.cpp @@ -1151,18 +1151,23 @@ void Framework::draw_ui() { ImGui::Checkbox("Transparency", &m_ui_option_transparent); ImGui::SameLine(); ImGui::Text("(?)"); - if (ImGui::IsItemHovered()) + if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Makes the UI transparent when not focused."); + } ImGui::Checkbox("Input Passthrough", &m_ui_passthrough); ImGui::SameLine(); ImGui::Text("(?)"); - if (ImGui::IsItemHovered()) + if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Allows mouse and keyboard inputs to register to the game while the UI is focused."); - ImGui::Checkbox("Show Advanced Options", &m_advanced_view_enabled); + } + + FrameworkConfig::get()->get_advanced_mode()->draw("Show Advanced Options"); + ImGui::SameLine(); ImGui::Text("(?)"); - if (ImGui::IsItemHovered()) + if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Show additional options for greater control over various settings."); + } if (m_mods_fully_initialized) { if (ImGui::Button("Reset to Default Settings")) { @@ -1220,8 +1225,10 @@ void Framework::draw_ui() { std::vector mod_sidebar_ranges{}; + const auto is_advanced_mode = is_advanced_view_enabled(); + for (auto& mod : m_mods->get_mods()) { - if (mod->is_advanced_mod() && !m_advanced_view_enabled) { + if (mod->is_advanced_mod() && !is_advanced_mode) { continue; } @@ -1230,7 +1237,7 @@ void Framework::draw_ui() { if (!entries.empty()) { size_t displayed_entries = 0; for (auto& entry : entries) { - if (entry.m_advanced_entry && !m_advanced_view_enabled) { + if (entry.m_advanced_entry && !is_advanced_mode) { continue; } @@ -1248,7 +1255,7 @@ void Framework::draw_ui() { } for (size_t i = 1; i < sidebar_entries.size(); ++i) { - if (m_advanced_view_enabled || !sidebar_entries[i].m_advanced_entry) { + if (is_advanced_mode || !sidebar_entries[i].m_advanced_entry) { for (const auto& range : mod_sidebar_ranges) { if (i == range.mn) { // Set first entry as default ("Runtime" entry of VR mod) @@ -1995,3 +2002,7 @@ void Framework::deinit_d3d12() { ImGui::GetIO().BackendRendererUserData = nullptr; m_d3d12 = {}; } + +bool Framework::is_advanced_view_enabled() const { + return FrameworkConfig::get()->is_advanced_mode(); +} \ No newline at end of file diff --git a/src/Framework.hpp b/src/Framework.hpp index 8b321f94..671de3bc 100644 --- a/src/Framework.hpp +++ b/src/Framework.hpp @@ -213,9 +213,7 @@ class Framework { m_last_page_dec_time = now; } - bool is_advanced_view_enabled() const { - return m_advanced_view_enabled; - } + bool is_advanced_view_enabled() const; private: void consume_input(); @@ -253,7 +251,6 @@ class Framework { // UI bool m_has_frame{false}; bool m_wants_device_object_cleanup{false}; - bool m_advanced_view_enabled{false}; bool m_draw_ui{true}; bool m_last_draw_ui{m_draw_ui}; bool m_is_ui_focused{false}; diff --git a/src/mods/FrameworkConfig.hpp b/src/mods/FrameworkConfig.hpp index 5a62be2b..ee6a0400 100644 --- a/src/mods/FrameworkConfig.hpp +++ b/src/mods/FrameworkConfig.hpp @@ -37,6 +37,18 @@ class FrameworkConfig : public Mod { return m_always_show_cursor->value(); } + bool is_advanced_mode() const { + return m_advanced_mode->value(); + } + + void toggle_advanced_mode() { + m_advanced_mode->toggle(); + } + + auto& get_advanced_mode() { + return m_advanced_mode; + } + int32_t get_font_size() { return m_font_size->value(); } @@ -47,6 +59,7 @@ class FrameworkConfig : public Mod { ModToggle::Ptr m_remember_menu_state{ ModToggle::create(generate_name("RememberMenuState"), false) }; ModToggle::Ptr m_enable_l3_r3_toggle{ ModToggle::create(generate_name("EnableL3R3Toggle"), true) }; ModToggle::Ptr m_always_show_cursor{ ModToggle::create(generate_name("AlwaysShowCursor"), false) }; + ModToggle::Ptr m_advanced_mode{ ModToggle::create(generate_name("AdvancedMode"), false) }; ModKey::Ptr m_show_cursor_key{ ModKey::create(generate_name("ShowCursorKey")) }; ModInt32::Ptr m_font_size{ModInt32::create(generate_name("FontSize"), 16)}; @@ -56,6 +69,7 @@ class FrameworkConfig : public Mod { *m_menu_open, *m_remember_menu_state, *m_enable_l3_r3_toggle, + *m_advanced_mode, *m_always_show_cursor, *m_font_size, };