From 2c5ff531a14b5068b9d0039e6799312139596c00 Mon Sep 17 00:00:00 2001 From: narknon <73571427+narknon@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:48:20 -0500 Subject: [PATCH] Add API for advanced view settings options in UEVR GUI, including for sidebar entries (#5) * Change ModInt32 to use int in ctor; add ModSliderInt32 * Add API for advanced view settings options, including for sidebar entries * Adv: Style fixes, logic simplification * Adv: Make advanced view persistent --------- Co-authored-by: praydog --- src/Framework.cpp | 71 +++++++++++---- src/Framework.hpp | 16 +++- src/Mod.hpp | 161 ++++++++++++++++++++++++++++------- src/mods/FrameworkConfig.hpp | 14 +++ src/mods/PluginLoader.hpp | 1 + src/mods/UObjectHook.hpp | 1 + src/mods/VR.hpp | 42 ++++----- 7 files changed, 233 insertions(+), 73 deletions(-) diff --git a/src/Framework.cpp b/src/Framework.cpp index e33b4585..c5977884 100644 --- a/src/Framework.cpp +++ b/src/Framework.cpp @@ -1151,13 +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."); + } + + FrameworkConfig::get()->get_advanced_mode()->draw("Show Advanced Options"); + + 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 +1190,9 @@ void Framework::draw_ui() { ImGui::Columns(1); // Mods: - std::vector sidebar_entries{"About"}; + 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); @@ -1213,33 +1225,52 @@ 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() && !is_advanced_mode) { + 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 && !is_advanced_mode) { + 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()); + sidebar_entries.emplace_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 (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) + 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 +1307,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(); } @@ -1971,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 155e9bdd..671de3bc 100644 --- a/src/Framework.hpp +++ b/src/Framework.hpp @@ -57,6 +57,13 @@ 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}; +}; + // Global facilitator class Framework { private: @@ -190,8 +197,8 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - ++m_sidebar_state.selected_entry; + ++m_sidebar_state.selected_entry; m_last_page_inc_time = now; } @@ -201,16 +208,19 @@ class Framework { if (delta < std::chrono::milliseconds(100)) { return; } - --m_sidebar_state.selected_entry; + --m_sidebar_state.selected_entry; m_last_page_dec_time = now; } + bool is_advanced_view_enabled() const; + private: void consume_input(); void update_fonts(); void invalidate_device_objects(); +private: void draw_ui(); void draw_about(); @@ -313,6 +323,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 c4d09a15..097f2c9c 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,26 +80,39 @@ class ModValue : public IModValue { return m_config_name; } + bool is_advanced_option() const { + return m_advanced_option; + } + + bool should_draw_option() const { + 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 { + if (!should_draw_option()) { + return false; + } + ImGui::PushID(this); auto ret = ImGui::Checkbox(name.data(), &m_value); ImGui::PopID(); @@ -107,6 +121,10 @@ class ModToggle : public ModValue { } void draw_value(std::string_view name) override { + if (!should_draw_option()) { + return; + } + ImGui::Text("%s: %i", name.data(), m_value); } @@ -119,14 +137,18 @@ 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 { + if (!should_draw_option()) { + return false; + } + ImGui::PushID(this); auto ret = ImGui::InputFloat(name.data(), &m_value); ImGui::PopID(); @@ -135,6 +157,10 @@ class ModFloat : public ModValue { } void draw_value(std::string_view name) override { + if (!should_draw_option()) { + return; + } + ImGui::Text("%s: %f", name.data(), m_value); } }; @@ -143,17 +169,22 @@ 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 { + if (!should_draw_option()) { + return false; + } + + ImGui::PushID(this); auto ret = ImGui::SliderFloat(name.data(), &m_value, m_range.x, m_range.y); ImGui::PopID(); @@ -162,6 +193,10 @@ class ModSlider : public ModFloat { } void draw_value(std::string_view name) override { + if (!should_draw_option()) { + return; + } + ImGui::Text("%s: %f [%f, %f]", name.data(), m_value, m_range.x, m_range.y); } @@ -177,16 +212,20 @@ class ModInt32 : public ModValue { public: using Ptr = std::unique_ptr; - static auto create(std::string_view config_name, uint32_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, uint32_t default_value = 0) - : ModValue{ config_name, static_cast(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 { + if (!should_draw_option()) { + return false; + } + ImGui::PushID(this); auto ret = ImGui::InputInt(name.data(), &m_value); ImGui::PopID(); @@ -195,20 +234,65 @@ class ModInt32 : public ModValue { } void draw_value(std::string_view name) override { + if (!should_draw_option()) { + return; + } + ImGui::Text("%s: %i", name.data(), m_value); } }; +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, 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, bool advanced_option = false) + : ModInt32{ config_name, default_value, advanced_option }, + m_int_range{ mn, mx } + { + } + + bool draw(std::string_view name) override { + if (!should_draw_option()) { + 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 { + 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; - 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) { @@ -217,6 +301,10 @@ class ModCombo : public ModValue { } bool draw(std::string_view name) override { + if (!should_draw_option()) { + return false; + } + // clamp m_value to valid range m_value = std::clamp(m_value, 0, static_cast(m_options.size()) - 1); @@ -228,6 +316,10 @@ class ModCombo : public ModValue { } void draw_value(std::string_view name) override { + 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]); @@ -238,7 +330,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; } @@ -262,16 +354,20 @@ 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 (!should_draw_option()) { + return false; + } + if (name.empty()) { return false; } @@ -373,6 +469,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(); } @@ -380,7 +477,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/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, }; 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{};