diff --git a/src/mods/VR.cpp b/src/mods/VR.cpp index 43802d57..f5d33000 100644 --- a/src/mods/VR.cpp +++ b/src/mods/VR.cpp @@ -830,28 +830,62 @@ void VR::on_xinput_get_state(uint32_t* retval, uint32_t user_index, XINPUT_STATE state->Gamepad.sThumbRX = (int16_t)(right_joystick_axis.x * 32767.0f); state->Gamepad.sThumbRY = (int16_t)(right_joystick_axis.y * 32767.0f); - // Touching the thumbrest allows us to use the thumbstick as a dpad - if (m_thumbrest_shifting->value()) { - const auto a_b_touch_inactive = !is_action_active_any_joystick(m_action_a_button_touch_right) && !is_action_active_any_joystick(m_action_b_button_touch_right); - const auto thumbrest_active = a_b_touch_inactive && is_action_active_any_joystick(m_action_thumbrest_touch_right); - - if (thumbrest_active) { - if (state->Gamepad.sThumbLY >= 16383) { + // Touching the thumbrest allows us to use the thumbstick as a dpad. Additional options are for controllers without capacitives/games that rely solely on DPad + if (m_dpad_shifting->value()) { + bool button_touch_inactive{true}; + bool thumbrest_check{false}; + + DPadMethod dpad_method = get_dpad_method(); + if (dpad_method == DPadMethod::RIGHT_TOUCH) { + thumbrest_check = is_action_active_any_joystick(m_action_thumbrest_touch_right); + button_touch_inactive = !is_action_active_any_joystick(m_action_a_button_touch_right) && !is_action_active_any_joystick(m_action_b_button_touch_right); + } + if (dpad_method == DPadMethod::LEFT_TOUCH) { + thumbrest_check = is_action_active_any_joystick(m_action_thumbrest_touch_left); + button_touch_inactive = !is_action_active_any_joystick(m_action_a_button_touch_left) && !is_action_active_any_joystick(m_action_b_button_touch_left); + } + + const auto dpad_active = (button_touch_inactive && thumbrest_check) || dpad_method == DPadMethod::LEFT_JOYSTICK || dpad_method == DPadMethod::RIGHT_JOYSTICK; + + if (dpad_active) { + SHORT ThumbY{0}; + SHORT ThumbX{0}; + // If someone is accidentally touching both thumbrests while also moving a joystick, this will default to left joystick. + if (dpad_method == DPadMethod::RIGHT_TOUCH || dpad_method == DPadMethod::LEFT_JOYSTICK) { + ThumbY = state->Gamepad.sThumbLY; + ThumbX = state->Gamepad.sThumbLX; + } + else if (dpad_method == DPadMethod::LEFT_TOUCH || dpad_method == DPadMethod::RIGHT_JOYSTICK) { + ThumbY = state->Gamepad.sThumbRY; + ThumbX = state->Gamepad.sThumbRX; + } + + if (ThumbY >= 16383) { state->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP; } - if (state->Gamepad.sThumbLY <= -16383) { + if (ThumbY <= -16383) { state->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN; } - if (state->Gamepad.sThumbLX >= 16383) { + if (ThumbX >= 16383) { state->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT; } - if (state->Gamepad.sThumbLX <= -16383) { + if (ThumbX <= -16383) { state->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT; } + if (dpad_method == DPadMethod::RIGHT_TOUCH || dpad_method == DPadMethod::LEFT_JOYSTICK) { + state->Gamepad.sThumbLY = 0; + state->Gamepad.sThumbLX = 0; + } + else if (dpad_method == DPadMethod::LEFT_TOUCH || dpad_method == DPadMethod::RIGHT_JOYSTICK) { + state->Gamepad.sThumbRY = 0; + state->Gamepad.sThumbRX = 0; + } + } + } state->Gamepad.sThumbLY = 0; state->Gamepad.sThumbLX = 0; } @@ -2010,7 +2044,9 @@ void VR::on_draw_sidebar_entry(std::string_view name) { ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once); if (ImGui::TreeNode("Controller")) { m_joystick_deadzone->draw("VR Joystick Deadzone"); - m_thumbrest_shifting->draw("Thumbrest DPad Shifting"); + m_dpad_shifting->draw("DPad Shifting"); + m_dpad_shifting_method->draw("DPad Shifting Method"); + ImGui::TreePop(); } diff --git a/src/mods/VR.hpp b/src/mods/VR.hpp index 67b91ef3..6b64bdce 100644 --- a/src/mods/VR.hpp +++ b/src/mods/VR.hpp @@ -45,6 +45,13 @@ class VR : public Mod { TWO_HANDED_LEFT, }; + enum DPadMethod : int32_t { + RIGHT_TOUCH, + LEFT_TOUCH, + LEFT_JOYSTICK, + RIGHT_JOYSTICK, + }; + static const inline std::string s_action_pose = "/actions/default/in/Pose"; static const inline std::string s_action_grip_pose = "/actions/default/in/GripPose"; static const inline std::string s_action_trigger = "/actions/default/in/Trigger"; @@ -482,6 +489,14 @@ class VR : public Mod { return m_roomscale_movement_actor_rotation->value() && !m_aim_temp_disabled; } + bool is_dpad_shifting_enabled() const { + return m_dpad_shifting->value(); + } + + DPadMethod get_dpad_method() const { + return (DPadMethod)m_dpad_shifting_method->value(); + } + bool should_skip_post_init_properties() const { return m_compatibility_skip_pip->value(); } @@ -691,6 +706,13 @@ class VR : public Mod { "Two Handed (Left)", }; + static const inline std::vector s_dpad_method_names { + "Right Thumbrest + Left Joystick", + "Left Thumbrest + Right Joystick", + "Left Joystick (Disables Standard Joystick Input)", + "Right Joystick (Disables Standard Joystick Input)" + }; + 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) }; @@ -715,7 +737,8 @@ class VR : public Mod { AimMethod m_previous_aim_method{ AimMethod::GAME }; const ModToggle::Ptr m_aim_interp{ ModToggle::create(generate_name("AimInterp"), true) }; const ModSlider::Ptr m_aim_speed{ ModSlider::create(generate_name("AimSpeed"), 0.01f, 25.0f, 15.0f) }; - const ModToggle::Ptr m_thumbrest_shifting{ ModToggle::create(generate_name("ThumbrestShifting"), true) }; + 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) }; //const ModToggle::Ptr m_headlocked_aim{ ModToggle::create(generate_name("HeadLockedAim"), false) }; //const ModToggle::Ptr m_headlocked_aim_controller_based{ ModToggle::create(generate_name("HeadLockedAimControllerBased"), false) }; @@ -784,7 +807,8 @@ class VR : public Mod { *m_movement_orientation, *m_aim_speed, *m_aim_interp, - *m_thumbrest_shifting, + *m_dpad_shifting, + *m_dpad_shifting_method, *m_motion_controls_inactivity_timer, *m_joystick_deadzone, *m_camera_forward_offset,