diff --git a/src/mods/VR.cpp b/src/mods/VR.cpp index 2b7efabe..eb4b8690 100644 --- a/src/mods/VR.cpp +++ b/src/mods/VR.cpp @@ -2062,29 +2062,37 @@ void VR::on_draw_ui() { m_fake_stereo_hook->on_draw_ui(); } - ImGui::Separator(); - ImGui::Text("Debug info"); - - ImGui::Combo("Sync Mode", (int*)&get_runtime()->custom_stage, "Early\0Late\0Very Late\0"); - ImGui::DragFloat4("Right Bounds", (float*)&m_right_bounds, 0.005f, -2.0f, 2.0f); - ImGui::DragFloat4("Left Bounds", (float*)&m_left_bounds, 0.005f, -2.0f, 2.0f); - ImGui::Checkbox("Disable Projection Matrix Override", &m_disable_projection_matrix_override); - ImGui::Checkbox("Disable View Matrix Override", &m_disable_view_matrix_override); - ImGui::Checkbox("Disable Backbuffer Size Override", &m_disable_backbuffer_size_override); - ImGui::Checkbox("Disable VR Overlay", &m_disable_overlay); - ImGui::Checkbox("Stereo Emulation Mode", &m_stereo_emulation_mode); - ImGui::Checkbox("Wait for Present", &m_wait_for_present); - ImGui::Checkbox("Controllers allowed", &m_controllers_allowed); - ImGui::Checkbox("Controller test mode", &m_controller_test_mode); - - const double min_ = 0.0; - const double max_ = 25.0; - ImGui::SliderScalar("Prediction Scale", ImGuiDataType_Double, &m_openxr->prediction_scale, &min_, &max_); - - ImGui::DragFloat4("Raw Left", (float*)&m_raw_projections[0], 0.01f, -100.0f, 100.0f); - ImGui::DragFloat4("Raw Right", (float*)&m_raw_projections[1], 0.01f, -100.0f, 100.0f); - - ImGui::TextWrapped("Hardware scheduling: %s", m_has_hw_scheduling ? "Enabled" : "Disabled"); + ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once); + if (ImGui::TreeNode("Compatibility Options")) { + m_compatibility_skip_pip->draw("Skip PostInitProperties"); + ImGui::TreePop(); + } + + ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once); + if (ImGui::TreeNode("Debug Info")) { + ImGui::Combo("Sync Mode", (int*)&get_runtime()->custom_stage, "Early\0Late\0Very Late\0"); + ImGui::DragFloat4("Right Bounds", (float*)&m_right_bounds, 0.005f, -2.0f, 2.0f); + ImGui::DragFloat4("Left Bounds", (float*)&m_left_bounds, 0.005f, -2.0f, 2.0f); + ImGui::Checkbox("Disable Projection Matrix Override", &m_disable_projection_matrix_override); + ImGui::Checkbox("Disable View Matrix Override", &m_disable_view_matrix_override); + ImGui::Checkbox("Disable Backbuffer Size Override", &m_disable_backbuffer_size_override); + ImGui::Checkbox("Disable VR Overlay", &m_disable_overlay); + ImGui::Checkbox("Stereo Emulation Mode", &m_stereo_emulation_mode); + ImGui::Checkbox("Wait for Present", &m_wait_for_present); + ImGui::Checkbox("Controllers allowed", &m_controllers_allowed); + ImGui::Checkbox("Controller test mode", &m_controller_test_mode); + + const double min_ = 0.0; + const double max_ = 25.0; + ImGui::SliderScalar("Prediction Scale", ImGuiDataType_Double, &m_openxr->prediction_scale, &min_, &max_); + + ImGui::DragFloat4("Raw Left", (float*)&m_raw_projections[0], 0.01f, -100.0f, 100.0f); + ImGui::DragFloat4("Raw Right", (float*)&m_raw_projections[1], 0.01f, -100.0f, 100.0f); + + ImGui::TextWrapped("Hardware scheduling: %s", m_has_hw_scheduling ? "Enabled" : "Disabled"); + + ImGui::TreePop(); + } } Vector4f VR::get_position(uint32_t index, bool grip) const { diff --git a/src/mods/VR.hpp b/src/mods/VR.hpp index 6f2b0b32..35033544 100644 --- a/src/mods/VR.hpp +++ b/src/mods/VR.hpp @@ -455,6 +455,10 @@ class VR : public Mod { return m_roomscale_movement_actor_rotation->value(); } + bool should_skip_post_init_properties() const { + return m_compatibility_skip_pip->value(); + } + private: Vector4f get_position_unsafe(uint32_t index) const; Vector4f get_velocity_unsafe(uint32_t index) const; @@ -695,6 +699,8 @@ class VR : public Mod { const ModToggle::Ptr m_splitscreen_compatibility_mode{ ModToggle::create(generate_name("SplitscreenCompatibilityMode"), false) }; const ModInt32::Ptr m_splitscreen_view_index{ ModInt32::create(generate_name("SplitscreenViewIndex"), 0) }; + const ModToggle::Ptr m_compatibility_skip_pip{ ModToggle::create(generate_name("Compatibility_SkipPostInitProperties"), false) }; + struct DecoupledPitchData { mutable std::shared_mutex mtx{}; glm::quat pre_flattened_rotation{}; @@ -749,6 +755,7 @@ class VR : public Mod { *m_ghosting_fix, *m_splitscreen_compatibility_mode, *m_splitscreen_view_index, + *m_compatibility_skip_pip }; diff --git a/src/mods/vr/FFakeStereoRenderingHook.cpp b/src/mods/vr/FFakeStereoRenderingHook.cpp index 567b040a..5008db0a 100644 --- a/src/mods/vr/FFakeStereoRenderingHook.cpp +++ b/src/mods/vr/FFakeStereoRenderingHook.cpp @@ -4111,31 +4111,38 @@ __forceinline Matrix4x4f* FFakeStereoRenderingHook::calculate_stereo_projection_ SPDLOG_INFO_ONCE("calculate stereo projection matrix called! {} from {:x}", view_index, (uintptr_t)_ReturnAddress() - (uintptr_t)utility::get_module_within((uintptr_t)_ReturnAddress()).value_or(nullptr)); #endif - if (!g_hook->m_fixed_localplayer_view_count) { - if (!g_hook->m_calculate_stereo_projection_matrix_post_hook) { - const auto return_address = (uintptr_t)_ReturnAddress(); - SPDLOG_INFO("Inserting midhook after CalculateStereoProjectionMatrix... @ {:x}", return_address); + auto& vr = VR::get(); - constexpr auto max_stack_depth = 100; - uintptr_t stack[max_stack_depth]{}; + // Only call PostInitProperties if ghosting fix enabled or native stereo is being used. + // Also, if we don't have a hook on GetDesiredNumberOfViews, we need to call PostInitProperties + //if (!vr->is_using_afr() || vr->is_ghosting_fix_enabled() || !g_hook->m_get_desired_number_of_views_hook) { + if (!vr->should_skip_post_init_properties()) { + if (!g_hook->m_fixed_localplayer_view_count) { + if (!g_hook->m_calculate_stereo_projection_matrix_post_hook) { + const auto return_address = (uintptr_t)_ReturnAddress(); + SPDLOG_INFO("Inserting midhook after CalculateStereoProjectionMatrix... @ {:x}", return_address); - const auto depth = RtlCaptureStackBackTrace(0, max_stack_depth, (void**)&stack, nullptr); + constexpr auto max_stack_depth = 100; + uintptr_t stack[max_stack_depth]{}; - for (int i = 0; i < depth; i++) { - g_hook->m_projection_matrix_stack.push_back(stack[i]); - SPDLOG_INFO(" {:x}", (uintptr_t)stack[i]); - } + const auto depth = RtlCaptureStackBackTrace(0, max_stack_depth, (void**)&stack, nullptr); - g_hook->m_calculate_stereo_projection_matrix_post_hook = safetyhook::create_mid((void*)return_address, &FFakeStereoRenderingHook::post_calculate_stereo_projection_matrix); + for (int i = 0; i < depth; i++) { + g_hook->m_projection_matrix_stack.push_back(stack[i]); + SPDLOG_INFO(" {:x}", (uintptr_t)stack[i]); + } - if (!g_hook->m_calculate_stereo_projection_matrix_post_hook) { - SPDLOG_ERROR("Failed to insert midhook after CalculateStereoProjectionMatrix!"); + g_hook->m_calculate_stereo_projection_matrix_post_hook = safetyhook::create_mid((void*)return_address, &FFakeStereoRenderingHook::post_calculate_stereo_projection_matrix); + + if (!g_hook->m_calculate_stereo_projection_matrix_post_hook) { + SPDLOG_ERROR("Failed to insert midhook after CalculateStereoProjectionMatrix!"); + } } - } - } else if (g_hook->m_calculate_stereo_projection_matrix_post_hook) { - SPDLOG_INFO("Removing midhook after CalculateStereoProjectionMatrix, job is done..."); - g_hook->m_calculate_stereo_projection_matrix_post_hook = {}; - g_hook->m_get_projection_data_pre_hook = {}; + } else if (g_hook->m_calculate_stereo_projection_matrix_post_hook) { + SPDLOG_INFO("Removing midhook after CalculateStereoProjectionMatrix, job is done..."); + g_hook->m_calculate_stereo_projection_matrix_post_hook = {}; + g_hook->m_get_projection_data_pre_hook = {}; + } } if (!g_framework->is_game_data_intialized()) { @@ -4208,7 +4215,6 @@ __forceinline Matrix4x4f* FFakeStereoRenderingHook::calculate_stereo_projection_ if (out != nullptr) { auto true_index = index_starts_from_one ? ((view_index + 1) % 2) : (view_index % 2); - auto& vr = VR::get(); if (vr->is_using_afr()) { true_index = g_frame_count % 2; }