diff options
Diffstat (limited to 'src/input_common/mouse')
| -rw-r--r-- | src/input_common/mouse/mouse_input.cpp | 95 | ||||
| -rw-r--r-- | src/input_common/mouse/mouse_input.h | 24 | ||||
| -rw-r--r-- | src/input_common/mouse/mouse_poller.cpp | 33 |
3 files changed, 136 insertions, 16 deletions
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp index 10786a541..329e416c7 100644 --- a/src/input_common/mouse/mouse_input.cpp +++ b/src/input_common/mouse/mouse_input.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2+ | 2 | // Licensed under GPLv2+ |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/settings.h" | ||
| 5 | #include "input_common/mouse/mouse_input.h" | 6 | #include "input_common/mouse/mouse_input.h" |
| 6 | 7 | ||
| 7 | namespace MouseInput { | 8 | namespace MouseInput { |
| @@ -32,10 +33,18 @@ void Mouse::UpdateThread() { | |||
| 32 | info.motion.UpdateOrientation(update_time * 1000); | 33 | info.motion.UpdateOrientation(update_time * 1000); |
| 33 | info.tilt_speed = 0; | 34 | info.tilt_speed = 0; |
| 34 | info.data.motion = info.motion.GetMotion(); | 35 | info.data.motion = info.motion.GetMotion(); |
| 36 | if (Settings::values.mouse_panning) { | ||
| 37 | info.last_mouse_change *= 0.96f; | ||
| 38 | info.data.axis = {static_cast<int>(16 * info.last_mouse_change.x), | ||
| 39 | static_cast<int>(16 * -info.last_mouse_change.y)}; | ||
| 40 | } | ||
| 35 | } | 41 | } |
| 36 | if (configuring) { | 42 | if (configuring) { |
| 37 | UpdateYuzuSettings(); | 43 | UpdateYuzuSettings(); |
| 38 | } | 44 | } |
| 45 | if (mouse_panning_timout++ > 20) { | ||
| 46 | StopPanning(); | ||
| 47 | } | ||
| 39 | std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); | 48 | std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); |
| 40 | } | 49 | } |
| 41 | } | 50 | } |
| @@ -50,7 +59,7 @@ void Mouse::UpdateYuzuSettings() { | |||
| 50 | }); | 59 | }); |
| 51 | } | 60 | } |
| 52 | 61 | ||
| 53 | void Mouse::PressButton(int x, int y, int button_) { | 62 | void Mouse::PressButton(int x, int y, MouseButton button_) { |
| 54 | const auto button_index = static_cast<std::size_t>(button_); | 63 | const auto button_index = static_cast<std::size_t>(button_); |
| 55 | if (button_index >= mouse_info.size()) { | 64 | if (button_index >= mouse_info.size()) { |
| 56 | return; | 65 | return; |
| @@ -58,15 +67,52 @@ void Mouse::PressButton(int x, int y, int button_) { | |||
| 58 | 67 | ||
| 59 | const auto button = 1U << button_index; | 68 | const auto button = 1U << button_index; |
| 60 | buttons |= static_cast<u16>(button); | 69 | buttons |= static_cast<u16>(button); |
| 61 | last_button = static_cast<MouseButton>(button_index); | 70 | last_button = button_; |
| 62 | 71 | ||
| 63 | mouse_info[button_index].mouse_origin = Common::MakeVec(x, y); | 72 | mouse_info[button_index].mouse_origin = Common::MakeVec(x, y); |
| 64 | mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y); | 73 | mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y); |
| 65 | mouse_info[button_index].data.pressed = true; | 74 | mouse_info[button_index].data.pressed = true; |
| 66 | } | 75 | } |
| 67 | 76 | ||
| 68 | void Mouse::MouseMove(int x, int y) { | 77 | void Mouse::StopPanning() { |
| 69 | for (MouseInfo& info : mouse_info) { | 78 | for (MouseInfo& info : mouse_info) { |
| 79 | if (Settings::values.mouse_panning) { | ||
| 80 | info.data.axis = {}; | ||
| 81 | info.tilt_speed = 0; | ||
| 82 | info.last_mouse_change = {}; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void Mouse::MouseMove(int x, int y, int center_x, int center_y) { | ||
| 88 | for (MouseInfo& info : mouse_info) { | ||
| 89 | if (Settings::values.mouse_panning) { | ||
| 90 | auto mouse_change = | ||
| 91 | (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); | ||
| 92 | mouse_panning_timout = 0; | ||
| 93 | |||
| 94 | if (mouse_change.y == 0 && mouse_change.x == 0) { | ||
| 95 | continue; | ||
| 96 | } | ||
| 97 | const auto mouse_change_length = mouse_change.Length(); | ||
| 98 | if (mouse_change_length < 3.0f) { | ||
| 99 | mouse_change /= mouse_change_length / 3.0f; | ||
| 100 | } | ||
| 101 | |||
| 102 | info.last_mouse_change = (info.last_mouse_change * 0.91f) + (mouse_change * 0.09f); | ||
| 103 | |||
| 104 | const auto last_mouse_change_length = info.last_mouse_change.Length(); | ||
| 105 | if (last_mouse_change_length > 8.0f) { | ||
| 106 | info.last_mouse_change /= last_mouse_change_length / 8.0f; | ||
| 107 | } else if (last_mouse_change_length < 1.0f) { | ||
| 108 | info.last_mouse_change = mouse_change / mouse_change.Length(); | ||
| 109 | } | ||
| 110 | |||
| 111 | info.tilt_direction = info.last_mouse_change; | ||
| 112 | info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity; | ||
| 113 | continue; | ||
| 114 | } | ||
| 115 | |||
| 70 | if (info.data.pressed) { | 116 | if (info.data.pressed) { |
| 71 | const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin; | 117 | const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin; |
| 72 | const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position; | 118 | const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position; |
| @@ -83,7 +129,7 @@ void Mouse::MouseMove(int x, int y) { | |||
| 83 | } | 129 | } |
| 84 | } | 130 | } |
| 85 | 131 | ||
| 86 | void Mouse::ReleaseButton(int button_) { | 132 | void Mouse::ReleaseButton(MouseButton button_) { |
| 87 | const auto button_index = static_cast<std::size_t>(button_); | 133 | const auto button_index = static_cast<std::size_t>(button_); |
| 88 | if (button_index >= mouse_info.size()) { | 134 | if (button_index >= mouse_info.size()) { |
| 89 | return; | 135 | return; |
| @@ -106,11 +152,52 @@ void Mouse::BeginConfiguration() { | |||
| 106 | 152 | ||
| 107 | void Mouse::EndConfiguration() { | 153 | void Mouse::EndConfiguration() { |
| 108 | buttons = 0; | 154 | buttons = 0; |
| 155 | for (MouseInfo& info : mouse_info) { | ||
| 156 | info.tilt_speed = 0; | ||
| 157 | info.data.pressed = false; | ||
| 158 | info.data.axis = {0, 0}; | ||
| 159 | } | ||
| 109 | last_button = MouseButton::Undefined; | 160 | last_button = MouseButton::Undefined; |
| 110 | mouse_queue.Clear(); | 161 | mouse_queue.Clear(); |
| 111 | configuring = false; | 162 | configuring = false; |
| 112 | } | 163 | } |
| 113 | 164 | ||
| 165 | bool Mouse::ToggleButton(std::size_t button_) { | ||
| 166 | if (button_ >= mouse_info.size()) { | ||
| 167 | return false; | ||
| 168 | } | ||
| 169 | const auto button = 1U << button_; | ||
| 170 | const bool button_state = (toggle_buttons & button) != 0; | ||
| 171 | const bool button_lock = (lock_buttons & button) != 0; | ||
| 172 | |||
| 173 | if (button_lock) { | ||
| 174 | return button_state; | ||
| 175 | } | ||
| 176 | |||
| 177 | lock_buttons |= static_cast<u16>(button); | ||
| 178 | |||
| 179 | if (button_state) { | ||
| 180 | toggle_buttons &= static_cast<u16>(0xFF - button); | ||
| 181 | } else { | ||
| 182 | toggle_buttons |= static_cast<u16>(button); | ||
| 183 | } | ||
| 184 | |||
| 185 | return !button_state; | ||
| 186 | } | ||
| 187 | |||
| 188 | bool Mouse::UnlockButton(std::size_t button_) { | ||
| 189 | if (button_ >= mouse_info.size()) { | ||
| 190 | return false; | ||
| 191 | } | ||
| 192 | |||
| 193 | const auto button = 1U << button_; | ||
| 194 | const bool button_state = (toggle_buttons & button) != 0; | ||
| 195 | |||
| 196 | lock_buttons &= static_cast<u16>(0xFF - button); | ||
| 197 | |||
| 198 | return button_state; | ||
| 199 | } | ||
| 200 | |||
| 114 | Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { | 201 | Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { |
| 115 | return mouse_queue; | 202 | return mouse_queue; |
| 116 | } | 203 | } |
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h index 58803c1bf..750d9b011 100644 --- a/src/input_common/mouse/mouse_input.h +++ b/src/input_common/mouse/mouse_input.h | |||
| @@ -18,10 +18,12 @@ namespace MouseInput { | |||
| 18 | 18 | ||
| 19 | enum class MouseButton { | 19 | enum class MouseButton { |
| 20 | Left, | 20 | Left, |
| 21 | Wheel, | ||
| 22 | Right, | 21 | Right, |
| 23 | Forward, | 22 | Wheel, |
| 24 | Backward, | 23 | Backward, |
| 24 | Forward, | ||
| 25 | Task, | ||
| 26 | Extra, | ||
| 25 | Undefined, | 27 | Undefined, |
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| @@ -51,19 +53,24 @@ public: | |||
| 51 | * @param y the y-coordinate of the cursor | 53 | * @param y the y-coordinate of the cursor |
| 52 | * @param button_ the button pressed | 54 | * @param button_ the button pressed |
| 53 | */ | 55 | */ |
| 54 | void PressButton(int x, int y, int button_); | 56 | void PressButton(int x, int y, MouseButton button_); |
| 55 | 57 | ||
| 56 | /** | 58 | /** |
| 57 | * Signals that mouse has moved. | 59 | * Signals that mouse has moved. |
| 58 | * @param x the x-coordinate of the cursor | 60 | * @param x the x-coordinate of the cursor |
| 59 | * @param y the y-coordinate of the cursor | 61 | * @param y the y-coordinate of the cursor |
| 62 | * @param center_x the x-coordinate of the middle of the screen | ||
| 63 | * @param center_y the y-coordinate of the middle of the screen | ||
| 60 | */ | 64 | */ |
| 61 | void MouseMove(int x, int y); | 65 | void MouseMove(int x, int y, int center_x, int center_y); |
| 62 | 66 | ||
| 63 | /** | 67 | /** |
| 64 | * Signals that a motion sensor tilt has ended. | 68 | * Signals that a motion sensor tilt has ended. |
| 65 | */ | 69 | */ |
| 66 | void ReleaseButton(int button_); | 70 | void ReleaseButton(MouseButton button_); |
| 71 | |||
| 72 | [[nodiscard]] bool ToggleButton(std::size_t button_); | ||
| 73 | [[nodiscard]] bool UnlockButton(std::size_t button_); | ||
| 67 | 74 | ||
| 68 | [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); | 75 | [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); |
| 69 | [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; | 76 | [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; |
| @@ -74,11 +81,13 @@ public: | |||
| 74 | private: | 81 | private: |
| 75 | void UpdateThread(); | 82 | void UpdateThread(); |
| 76 | void UpdateYuzuSettings(); | 83 | void UpdateYuzuSettings(); |
| 84 | void StopPanning(); | ||
| 77 | 85 | ||
| 78 | struct MouseInfo { | 86 | struct MouseInfo { |
| 79 | InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; | 87 | InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; |
| 80 | Common::Vec2<int> mouse_origin; | 88 | Common::Vec2<int> mouse_origin; |
| 81 | Common::Vec2<int> last_mouse_position; | 89 | Common::Vec2<int> last_mouse_position; |
| 90 | Common::Vec2<float> last_mouse_change; | ||
| 82 | bool is_tilting = false; | 91 | bool is_tilting = false; |
| 83 | float sensitivity{0.120f}; | 92 | float sensitivity{0.120f}; |
| 84 | 93 | ||
| @@ -88,11 +97,14 @@ private: | |||
| 88 | }; | 97 | }; |
| 89 | 98 | ||
| 90 | u16 buttons{}; | 99 | u16 buttons{}; |
| 100 | u16 toggle_buttons{}; | ||
| 101 | u16 lock_buttons{}; | ||
| 91 | std::thread update_thread; | 102 | std::thread update_thread; |
| 92 | MouseButton last_button{MouseButton::Undefined}; | 103 | MouseButton last_button{MouseButton::Undefined}; |
| 93 | std::array<MouseInfo, 5> mouse_info; | 104 | std::array<MouseInfo, 7> mouse_info; |
| 94 | Common::SPSCQueue<MouseStatus> mouse_queue; | 105 | Common::SPSCQueue<MouseStatus> mouse_queue; |
| 95 | bool configuring{false}; | 106 | bool configuring{false}; |
| 96 | bool update_thread_running{true}; | 107 | bool update_thread_running{true}; |
| 108 | int mouse_panning_timout{}; | ||
| 97 | }; | 109 | }; |
| 98 | } // namespace MouseInput | 110 | } // namespace MouseInput |
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp index 508eb0c7d..0e1db54fb 100644 --- a/src/input_common/mouse/mouse_poller.cpp +++ b/src/input_common/mouse/mouse_poller.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <utility> | 6 | #include <utility> |
| 7 | 7 | ||
| 8 | #include "common/threadsafe_queue.h" | 8 | #include "common/threadsafe_queue.h" |
| 9 | #include "core/settings.h" | ||
| 9 | #include "input_common/mouse/mouse_input.h" | 10 | #include "input_common/mouse/mouse_input.h" |
| 10 | #include "input_common/mouse/mouse_poller.h" | 11 | #include "input_common/mouse/mouse_poller.h" |
| 11 | 12 | ||
| @@ -13,16 +14,25 @@ namespace InputCommon { | |||
| 13 | 14 | ||
| 14 | class MouseButton final : public Input::ButtonDevice { | 15 | class MouseButton final : public Input::ButtonDevice { |
| 15 | public: | 16 | public: |
| 16 | explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_) | 17 | explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_) |
| 17 | : button(button_), mouse_input(mouse_input_) {} | 18 | : button(button_), toggle(toggle_), mouse_input(mouse_input_) {} |
| 18 | 19 | ||
| 19 | bool GetStatus() const override { | 20 | bool GetStatus() const override { |
| 20 | return mouse_input->GetMouseState(button).pressed; | 21 | const bool button_state = mouse_input->GetMouseState(button).pressed; |
| 22 | if (!toggle) { | ||
| 23 | return button_state; | ||
| 24 | } | ||
| 25 | |||
| 26 | if (button_state) { | ||
| 27 | return mouse_input->ToggleButton(button); | ||
| 28 | } | ||
| 29 | return mouse_input->UnlockButton(button); | ||
| 21 | } | 30 | } |
| 22 | 31 | ||
| 23 | private: | 32 | private: |
| 24 | const u32 button; | 33 | const u32 button; |
| 25 | const MouseInput::Mouse* mouse_input; | 34 | const bool toggle; |
| 35 | MouseInput::Mouse* mouse_input; | ||
| 26 | }; | 36 | }; |
| 27 | 37 | ||
| 28 | MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | 38 | MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) |
| @@ -31,8 +41,9 @@ MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_ | |||
| 31 | std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( | 41 | std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( |
| 32 | const Common::ParamPackage& params) { | 42 | const Common::ParamPackage& params) { |
| 33 | const auto button_id = params.Get("button", 0); | 43 | const auto button_id = params.Get("button", 0); |
| 44 | const auto toggle = params.Get("toggle", false); | ||
| 34 | 45 | ||
| 35 | return std::make_unique<MouseButton>(button_id, mouse_input.get()); | 46 | return std::make_unique<MouseButton>(button_id, toggle, mouse_input.get()); |
| 36 | } | 47 | } |
| 37 | 48 | ||
| 38 | Common::ParamPackage MouseButtonFactory::GetNextInput() const { | 49 | Common::ParamPackage MouseButtonFactory::GetNextInput() const { |
| @@ -71,7 +82,7 @@ public: | |||
| 71 | std::lock_guard lock{mutex}; | 82 | std::lock_guard lock{mutex}; |
| 72 | const auto axis_value = | 83 | const auto axis_value = |
| 73 | static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis)); | 84 | static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis)); |
| 74 | return axis_value / (100.0f * range); | 85 | return axis_value * Settings::values.mouse_panning_sensitivity / (100.0f * range); |
| 75 | } | 86 | } |
| 76 | 87 | ||
| 77 | std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { | 88 | std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { |
| @@ -106,6 +117,16 @@ public: | |||
| 106 | return {0.0f, 0.0f}; | 117 | return {0.0f, 0.0f}; |
| 107 | } | 118 | } |
| 108 | 119 | ||
| 120 | std::tuple<float, float> GetRawStatus() const override { | ||
| 121 | const float x = GetAxis(axis_x); | ||
| 122 | const float y = GetAxis(axis_y); | ||
| 123 | return {x, y}; | ||
| 124 | } | ||
| 125 | |||
| 126 | Input::AnalogProperties GetAnalogProperties() const override { | ||
| 127 | return {deadzone, range, 0.5f}; | ||
| 128 | } | ||
| 129 | |||
| 109 | private: | 130 | private: |
| 110 | const u32 button; | 131 | const u32 button; |
| 111 | const u32 axis_x; | 132 | const u32 axis_x; |