summaryrefslogtreecommitdiff
path: root/src/input_common/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/mouse')
-rw-r--r--src/input_common/mouse/mouse_input.cpp95
-rw-r--r--src/input_common/mouse/mouse_input.h24
-rw-r--r--src/input_common/mouse/mouse_poller.cpp33
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
7namespace MouseInput { 8namespace 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
53void Mouse::PressButton(int x, int y, int button_) { 62void 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
68void Mouse::MouseMove(int x, int y) { 77void 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
87void 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
86void Mouse::ReleaseButton(int button_) { 132void 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
107void Mouse::EndConfiguration() { 153void 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
165bool 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
188bool 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
114Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { 201Common::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
19enum class MouseButton { 19enum 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:
74private: 81private:
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
14class MouseButton final : public Input::ButtonDevice { 15class MouseButton final : public Input::ButtonDevice {
15public: 16public:
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
23private: 32private:
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
28MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) 38MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
@@ -31,8 +41,9 @@ MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_
31std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( 41std::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
38Common::ParamPackage MouseButtonFactory::GetNextInput() const { 49Common::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
109private: 130private:
110 const u32 button; 131 const u32 button;
111 const u32 axis_x; 132 const u32 axis_x;