summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input_common/CMakeLists.txt6
-rw-r--r--src/input_common/drivers/mouse.cpp138
-rw-r--r--src/input_common/drivers/mouse.h77
-rw-r--r--src/input_common/mouse/mouse_input.cpp223
-rw-r--r--src/input_common/mouse/mouse_input.h116
-rw-r--r--src/input_common/mouse/mouse_poller.cpp299
-rw-r--r--src/input_common/mouse/mouse_poller.h109
7 files changed, 217 insertions, 751 deletions
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 0fcf7a9d7..34b41ce01 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -1,6 +1,8 @@
1add_library(input_common STATIC 1add_library(input_common STATIC
2 drivers/keyboard.cpp 2 drivers/keyboard.cpp
3 drivers/keyboard.h 3 drivers/keyboard.h
4 drivers/mouse.cpp
5 drivers/mouse.h
4 helpers/stick_from_buttons.cpp 6 helpers/stick_from_buttons.cpp
5 helpers/stick_from_buttons.h 7 helpers/stick_from_buttons.h
6 helpers/touch_from_buttons.cpp 8 helpers/touch_from_buttons.cpp
@@ -23,10 +25,6 @@ add_library(input_common STATIC
23 gcadapter/gc_adapter.h 25 gcadapter/gc_adapter.h
24 gcadapter/gc_poller.cpp 26 gcadapter/gc_poller.cpp
25 gcadapter/gc_poller.h 27 gcadapter/gc_poller.h
26 mouse/mouse_input.cpp
27 mouse/mouse_input.h
28 mouse/mouse_poller.cpp
29 mouse/mouse_poller.h
30 sdl/sdl.cpp 28 sdl/sdl.cpp
31 sdl/sdl.h 29 sdl/sdl.h
32 tas/tas_input.cpp 30 tas/tas_input.cpp
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
new file mode 100644
index 000000000..2c2432fb7
--- /dev/null
+++ b/src/input_common/drivers/mouse.cpp
@@ -0,0 +1,138 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included
4
5#include <stop_token>
6#include <thread>
7#include <fmt/format.h>
8
9#include "common/param_package.h"
10#include "common/settings.h"
11#include "common/thread.h"
12#include "input_common/drivers/mouse.h"
13
14namespace InputCommon {
15constexpr int touch_axis_x = 10;
16constexpr int touch_axis_y = 11;
17
18Mouse::Mouse(const std::string input_engine_) : InputEngine(input_engine_) {
19 PreSetController(identifier);
20 update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
21}
22
23void Mouse::UpdateThread(std::stop_token stop_token) {
24 Common::SetCurrentThreadName("yuzu:input:Mouse");
25 constexpr int update_time = 10;
26 while (!stop_token.stop_requested()) {
27 if (Settings::values.mouse_panning) {
28 // Slow movement by 4%
29 last_mouse_change *= 0.96f;
30 const float sensitivity =
31 Settings::values.mouse_panning_sensitivity.GetValue() * 0.022f;
32 SetAxis(identifier, 0, last_mouse_change.x * sensitivity);
33 SetAxis(identifier, 1, -last_mouse_change.y * sensitivity);
34 }
35
36 if (mouse_panning_timout++ > 20) {
37 StopPanning();
38 }
39 std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
40 }
41}
42
43void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) {
44 SetAxis(identifier, touch_axis_x, touch_x);
45 SetAxis(identifier, touch_axis_y, touch_y);
46
47 if (Settings::values.mouse_panning) {
48 auto mouse_change =
49 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
50 mouse_panning_timout = 0;
51
52 const auto move_distance = mouse_change.Length();
53 if (move_distance == 0) {
54 return;
55 }
56
57 // Make slow movements at least 3 units on lenght
58 if (move_distance < 3.0f) {
59 // Normalize value
60 mouse_change /= move_distance;
61 mouse_change *= 3.0f;
62 }
63
64 // Average mouse movements
65 last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f);
66
67 const auto last_move_distance = last_mouse_change.Length();
68
69 // Make fast movements clamp to 8 units on lenght
70 if (last_move_distance > 8.0f) {
71 // Normalize value
72 last_mouse_change /= last_move_distance;
73 last_mouse_change *= 8.0f;
74 }
75
76 // Ignore average if it's less than 1 unit and use current movement value
77 if (last_move_distance < 1.0f) {
78 last_mouse_change = mouse_change / mouse_change.Length();
79 }
80
81 return;
82 }
83
84 if (button_pressed) {
85 const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin;
86 const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.0012f;
87 SetAxis(identifier, 0, static_cast<float>(mouse_move.x) * sensitivity);
88 SetAxis(identifier, 1, static_cast<float>(-mouse_move.y) * sensitivity);
89 }
90}
91
92void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button) {
93 SetAxis(identifier, touch_axis_x, touch_x);
94 SetAxis(identifier, touch_axis_y, touch_y);
95 SetButton(identifier, static_cast<int>(button), true);
96 // Set initial analog parameters
97 mouse_origin = {x, y};
98 last_mouse_position = {x, y};
99 button_pressed = true;
100}
101
102void Mouse::ReleaseButton(MouseButton button) {
103 SetButton(identifier, static_cast<int>(button), false);
104
105 if (!Settings::values.mouse_panning) {
106 SetAxis(identifier, 0, 0);
107 SetAxis(identifier, 1, 0);
108 }
109 button_pressed = false;
110}
111
112void Mouse::ReleaseAllButtons() {
113 ResetButtonState();
114 button_pressed = false;
115}
116
117void Mouse::StopPanning() {
118 last_mouse_change = {};
119}
120
121std::vector<Common::ParamPackage> Mouse::GetInputDevices() const {
122 std::vector<Common::ParamPackage> devices;
123 devices.emplace_back(Common::ParamPackage{
124 {"engine", "keyboard"},
125 {"display", "Keyboard/Mouse"},
126 });
127 return devices;
128}
129
130std::string Mouse::GetUIName(const Common::ParamPackage& params) const {
131 if (params.Has("button")) {
132 return fmt::format("Mouse {}", params.Get("button", 0));
133 }
134
135 return "Bad Mouse";
136}
137
138} // namespace InputCommon
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h
new file mode 100644
index 000000000..e8355751a
--- /dev/null
+++ b/src/input_common/drivers/mouse.h
@@ -0,0 +1,77 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included
4
5#pragma once
6
7#include <stop_token>
8#include <thread>
9
10#include "common/vector_math.h"
11#include "input_common/input_engine.h"
12
13namespace InputCommon {
14
15enum class MouseButton {
16 Left,
17 Right,
18 Wheel,
19 Backward,
20 Forward,
21 Task,
22 Extra,
23 Undefined,
24};
25
26/**
27 * A button device factory representing a keyboard. It receives keyboard events and forward them
28 * to all button devices it created.
29 */
30class Mouse final : public InputCommon::InputEngine {
31public:
32 explicit Mouse(const std::string input_engine_);
33
34 /**
35 * Signals that mouse has moved.
36 * @param x the x-coordinate of the cursor
37 * @param y the y-coordinate of the cursor
38 * @param center_x the x-coordinate of the middle of the screen
39 * @param center_y the y-coordinate of the middle of the screen
40 */
41 void MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y);
42
43 /**
44 * Sets the status of all buttons bound with the key to pressed
45 * @param key_code the code of the key to press
46 */
47 void PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button);
48
49 /**
50 * Sets the status of all buttons bound with the key to released
51 * @param key_code the code of the key to release
52 */
53 void ReleaseButton(MouseButton button);
54
55 void ReleaseAllButtons();
56
57 std::vector<Common::ParamPackage> GetInputDevices() const override;
58 std::string GetUIName(const Common::ParamPackage& params) const override;
59
60private:
61 void UpdateThread(std::stop_token stop_token);
62 void StopPanning();
63
64 const PadIdentifier identifier = {
65 .guid = Common::UUID{""},
66 .port = 0,
67 .pad = 0,
68 };
69 Common::Vec2<int> mouse_origin;
70 Common::Vec2<int> last_mouse_position;
71 Common::Vec2<float> last_mouse_change;
72 bool button_pressed;
73 int mouse_panning_timout{};
74 std::jthread update_thread;
75};
76
77} // namespace InputCommon
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
deleted file mode 100644
index 3b052ffb2..000000000
--- a/src/input_common/mouse/mouse_input.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#include <stop_token>
6#include <thread>
7
8#include "common/settings.h"
9#include "input_common/mouse/mouse_input.h"
10
11namespace MouseInput {
12
13Mouse::Mouse() {
14 update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
15}
16
17Mouse::~Mouse() = default;
18
19void Mouse::UpdateThread(std::stop_token stop_token) {
20 constexpr int update_time = 10;
21 while (!stop_token.stop_requested()) {
22 for (MouseInfo& info : mouse_info) {
23 const Common::Vec3f angular_direction{
24 -info.tilt_direction.y,
25 0.0f,
26 -info.tilt_direction.x,
27 };
28
29 info.motion.SetGyroscope(angular_direction * info.tilt_speed);
30 info.motion.UpdateRotation(update_time * 1000);
31 info.motion.UpdateOrientation(update_time * 1000);
32 info.tilt_speed = 0;
33 info.data.motion = info.motion.GetMotion();
34 if (Settings::values.mouse_panning) {
35 info.last_mouse_change *= 0.96f;
36 info.data.axis = {static_cast<int>(16 * info.last_mouse_change.x),
37 static_cast<int>(16 * -info.last_mouse_change.y)};
38 }
39 }
40 if (configuring) {
41 UpdateYuzuSettings();
42 }
43 if (mouse_panning_timout++ > 20) {
44 StopPanning();
45 }
46 std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
47 }
48}
49
50void Mouse::UpdateYuzuSettings() {
51 if (buttons == 0) {
52 return;
53 }
54
55 mouse_queue.Push(MouseStatus{
56 .button = last_button,
57 });
58}
59
60void Mouse::PressButton(int x, int y, MouseButton button_) {
61 const auto button_index = static_cast<std::size_t>(button_);
62 if (button_index >= mouse_info.size()) {
63 return;
64 }
65
66 const auto button = 1U << button_index;
67 buttons |= static_cast<u16>(button);
68 last_button = button_;
69
70 mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
71 mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
72 mouse_info[button_index].data.pressed = true;
73}
74
75void Mouse::StopPanning() {
76 for (MouseInfo& info : mouse_info) {
77 if (Settings::values.mouse_panning) {
78 info.data.axis = {};
79 info.tilt_speed = 0;
80 info.last_mouse_change = {};
81 }
82 }
83}
84
85void Mouse::MouseMove(int x, int y, int center_x, int center_y) {
86 for (MouseInfo& info : mouse_info) {
87 if (Settings::values.mouse_panning) {
88 auto mouse_change =
89 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
90 mouse_panning_timout = 0;
91
92 if (mouse_change.y == 0 && mouse_change.x == 0) {
93 continue;
94 }
95 const auto mouse_change_length = mouse_change.Length();
96 if (mouse_change_length < 3.0f) {
97 mouse_change /= mouse_change_length / 3.0f;
98 }
99
100 info.last_mouse_change = (info.last_mouse_change * 0.91f) + (mouse_change * 0.09f);
101
102 const auto last_mouse_change_length = info.last_mouse_change.Length();
103 if (last_mouse_change_length > 8.0f) {
104 info.last_mouse_change /= last_mouse_change_length / 8.0f;
105 } else if (last_mouse_change_length < 1.0f) {
106 info.last_mouse_change = mouse_change / mouse_change.Length();
107 }
108
109 info.tilt_direction = info.last_mouse_change;
110 info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
111 continue;
112 }
113
114 if (info.data.pressed) {
115 const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin;
116 const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position;
117 info.last_mouse_position = Common::MakeVec(x, y);
118 info.data.axis = {mouse_move.x, -mouse_move.y};
119
120 if (mouse_change.x == 0 && mouse_change.y == 0) {
121 info.tilt_speed = 0;
122 } else {
123 info.tilt_direction = mouse_change.Cast<float>();
124 info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
125 }
126 }
127 }
128}
129
130void Mouse::ReleaseButton(MouseButton button_) {
131 const auto button_index = static_cast<std::size_t>(button_);
132 if (button_index >= mouse_info.size()) {
133 return;
134 }
135
136 const auto button = 1U << button_index;
137 buttons &= static_cast<u16>(0xFF - button);
138
139 mouse_info[button_index].tilt_speed = 0;
140 mouse_info[button_index].data.pressed = false;
141 mouse_info[button_index].data.axis = {0, 0};
142}
143
144void Mouse::ReleaseAllButtons() {
145 buttons = 0;
146 for (auto& info : mouse_info) {
147 info.tilt_speed = 0;
148 info.data.pressed = false;
149 info.data.axis = {0, 0};
150 }
151}
152
153void Mouse::BeginConfiguration() {
154 buttons = 0;
155 last_button = MouseButton::Undefined;
156 mouse_queue.Clear();
157 configuring = true;
158}
159
160void Mouse::EndConfiguration() {
161 buttons = 0;
162 for (MouseInfo& info : mouse_info) {
163 info.tilt_speed = 0;
164 info.data.pressed = false;
165 info.data.axis = {0, 0};
166 }
167 last_button = MouseButton::Undefined;
168 mouse_queue.Clear();
169 configuring = false;
170}
171
172bool Mouse::ToggleButton(std::size_t button_) {
173 if (button_ >= mouse_info.size()) {
174 return false;
175 }
176 const auto button = 1U << button_;
177 const bool button_state = (toggle_buttons & button) != 0;
178 const bool button_lock = (lock_buttons & button) != 0;
179
180 if (button_lock) {
181 return button_state;
182 }
183
184 lock_buttons |= static_cast<u16>(button);
185
186 if (button_state) {
187 toggle_buttons &= static_cast<u16>(0xFF - button);
188 } else {
189 toggle_buttons |= static_cast<u16>(button);
190 }
191
192 return !button_state;
193}
194
195bool Mouse::UnlockButton(std::size_t button_) {
196 if (button_ >= mouse_info.size()) {
197 return false;
198 }
199
200 const auto button = 1U << button_;
201 const bool button_state = (toggle_buttons & button) != 0;
202
203 lock_buttons &= static_cast<u16>(0xFF - button);
204
205 return button_state;
206}
207
208Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
209 return mouse_queue;
210}
211
212const Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() const {
213 return mouse_queue;
214}
215
216MouseData& Mouse::GetMouseState(std::size_t button) {
217 return mouse_info[button].data;
218}
219
220const MouseData& Mouse::GetMouseState(std::size_t button) const {
221 return mouse_info[button].data;
222}
223} // namespace MouseInput
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h
deleted file mode 100644
index c8bae99c1..000000000
--- a/src/input_common/mouse/mouse_input.h
+++ /dev/null
@@ -1,116 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <mutex>
9#include <stop_token>
10#include <thread>
11
12#include "common/common_types.h"
13#include "common/threadsafe_queue.h"
14#include "common/vector_math.h"
15#include "core/frontend/input.h"
16#include "input_common/motion_input.h"
17
18namespace MouseInput {
19
20enum class MouseButton {
21 Left,
22 Right,
23 Wheel,
24 Backward,
25 Forward,
26 Task,
27 Extra,
28 Undefined,
29};
30
31struct MouseStatus {
32 MouseButton button{MouseButton::Undefined};
33};
34
35struct MouseData {
36 bool pressed{};
37 std::array<int, 2> axis{};
38 Input::MotionStatus motion{};
39 Input::TouchStatus touch{};
40};
41
42class Mouse {
43public:
44 Mouse();
45 ~Mouse();
46
47 /// Used for polling
48 void BeginConfiguration();
49 void EndConfiguration();
50
51 /**
52 * Signals that a button is pressed.
53 * @param x the x-coordinate of the cursor
54 * @param y the y-coordinate of the cursor
55 * @param button_ the button pressed
56 */
57 void PressButton(int x, int y, MouseButton button_);
58
59 /**
60 * Signals that mouse has moved.
61 * @param x the x-coordinate of the cursor
62 * @param y the y-coordinate of the cursor
63 * @param center_x the x-coordinate of the middle of the screen
64 * @param center_y the y-coordinate of the middle of the screen
65 */
66 void MouseMove(int x, int y, int center_x, int center_y);
67
68 /**
69 * Signals that a button is released.
70 * @param button_ the button pressed
71 */
72 void ReleaseButton(MouseButton button_);
73
74 /**
75 * Signals that all buttons are released
76 */
77 void ReleaseAllButtons();
78
79 [[nodiscard]] bool ToggleButton(std::size_t button_);
80 [[nodiscard]] bool UnlockButton(std::size_t button_);
81
82 [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
83 [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
84
85 [[nodiscard]] MouseData& GetMouseState(std::size_t button);
86 [[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
87
88private:
89 void UpdateThread(std::stop_token stop_token);
90 void UpdateYuzuSettings();
91 void StopPanning();
92
93 struct MouseInfo {
94 InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f};
95 Common::Vec2<int> mouse_origin;
96 Common::Vec2<int> last_mouse_position;
97 Common::Vec2<float> last_mouse_change;
98 bool is_tilting = false;
99 float sensitivity{0.120f};
100
101 float tilt_speed = 0;
102 Common::Vec2<float> tilt_direction;
103 MouseData data;
104 };
105
106 u16 buttons{};
107 u16 toggle_buttons{};
108 u16 lock_buttons{};
109 std::jthread update_thread;
110 MouseButton last_button{MouseButton::Undefined};
111 std::array<MouseInfo, 7> mouse_info;
112 Common::SPSCQueue<MouseStatus> mouse_queue;
113 bool configuring{false};
114 int mouse_panning_timout{};
115};
116} // namespace MouseInput
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
deleted file mode 100644
index 090b26972..000000000
--- a/src/input_common/mouse/mouse_poller.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <memory>
7#include <mutex>
8#include <utility>
9
10#include "common/settings.h"
11#include "common/threadsafe_queue.h"
12#include "input_common/mouse/mouse_input.h"
13#include "input_common/mouse/mouse_poller.h"
14
15namespace InputCommon {
16
17class MouseButton final : public Input::ButtonDevice {
18public:
19 explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_)
20 : button(button_), toggle(toggle_), mouse_input(mouse_input_) {}
21
22 bool GetStatus() const override {
23 const bool button_state = mouse_input->GetMouseState(button).pressed;
24 if (!toggle) {
25 return button_state;
26 }
27
28 if (button_state) {
29 return mouse_input->ToggleButton(button);
30 }
31 return mouse_input->UnlockButton(button);
32 }
33
34private:
35 const u32 button;
36 const bool toggle;
37 MouseInput::Mouse* mouse_input;
38};
39
40MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
41 : mouse_input(std::move(mouse_input_)) {}
42
43std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
44 const Common::ParamPackage& params) {
45 const auto button_id = params.Get("button", 0);
46 const auto toggle = params.Get("toggle", false);
47
48 return std::make_unique<MouseButton>(button_id, toggle, mouse_input.get());
49}
50
51Common::ParamPackage MouseButtonFactory::GetNextInput() const {
52 MouseInput::MouseStatus pad;
53 Common::ParamPackage params;
54 auto& queue = mouse_input->GetMouseQueue();
55 while (queue.Pop(pad)) {
56 // This while loop will break on the earliest detected button
57 if (pad.button != MouseInput::MouseButton::Undefined) {
58 params.Set("engine", "mouse");
59 params.Set("button", static_cast<u16>(pad.button));
60 params.Set("toggle", false);
61 return params;
62 }
63 }
64 return params;
65}
66
67void MouseButtonFactory::BeginConfiguration() {
68 polling = true;
69 mouse_input->BeginConfiguration();
70}
71
72void MouseButtonFactory::EndConfiguration() {
73 polling = false;
74 mouse_input->EndConfiguration();
75}
76
77class MouseAnalog final : public Input::AnalogDevice {
78public:
79 explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, bool invert_x_, bool invert_y_,
80 float deadzone_, float range_, const MouseInput::Mouse* mouse_input_)
81 : button(port_), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), invert_y(invert_y_),
82 deadzone(deadzone_), range(range_), mouse_input(mouse_input_) {}
83
84 float GetAxis(u32 axis) const {
85 std::lock_guard lock{mutex};
86 const auto axis_value =
87 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
88 const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.10f;
89 return axis_value * sensitivity / (100.0f * range);
90 }
91
92 std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
93 float x = GetAxis(analog_axis_x);
94 float y = GetAxis(analog_axis_y);
95 if (invert_x) {
96 x = -x;
97 }
98 if (invert_y) {
99 y = -y;
100 }
101
102 // Make sure the coordinates are in the unit circle,
103 // otherwise normalize it.
104 float r = x * x + y * y;
105 if (r > 1.0f) {
106 r = std::sqrt(r);
107 x /= r;
108 y /= r;
109 }
110
111 return {x, y};
112 }
113
114 std::tuple<float, float> GetStatus() const override {
115 const auto [x, y] = GetAnalog(axis_x, axis_y);
116 const float r = std::sqrt((x * x) + (y * y));
117 if (r > deadzone) {
118 return {x / r * (r - deadzone) / (1 - deadzone),
119 y / r * (r - deadzone) / (1 - deadzone)};
120 }
121 return {0.0f, 0.0f};
122 }
123
124 std::tuple<float, float> GetRawStatus() const override {
125 const float x = GetAxis(axis_x);
126 const float y = GetAxis(axis_y);
127 return {x, y};
128 }
129
130 Input::AnalogProperties GetAnalogProperties() const override {
131 return {deadzone, range, 0.5f};
132 }
133
134private:
135 const u32 button;
136 const u32 axis_x;
137 const u32 axis_y;
138 const bool invert_x;
139 const bool invert_y;
140 const float deadzone;
141 const float range;
142 const MouseInput::Mouse* mouse_input;
143 mutable std::mutex mutex;
144};
145
146/// An analog device factory that creates analog devices from GC Adapter
147MouseAnalogFactory::MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
148 : mouse_input(std::move(mouse_input_)) {}
149
150/**
151 * Creates analog device from joystick axes
152 * @param params contains parameters for creating the device:
153 * - "port": the nth gcpad on the adapter
154 * - "axis_x": the index of the axis to be bind as x-axis
155 * - "axis_y": the index of the axis to be bind as y-axis
156 */
157std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create(
158 const Common::ParamPackage& params) {
159 const auto port = static_cast<u32>(params.Get("port", 0));
160 const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
161 const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
162 const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
163 const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
164 const std::string invert_x_value = params.Get("invert_x", "+");
165 const std::string invert_y_value = params.Get("invert_y", "+");
166 const bool invert_x = invert_x_value == "-";
167 const bool invert_y = invert_y_value == "-";
168
169 return std::make_unique<MouseAnalog>(port, axis_x, axis_y, invert_x, invert_y, deadzone, range,
170 mouse_input.get());
171}
172
173void MouseAnalogFactory::BeginConfiguration() {
174 polling = true;
175 mouse_input->BeginConfiguration();
176}
177
178void MouseAnalogFactory::EndConfiguration() {
179 polling = false;
180 mouse_input->EndConfiguration();
181}
182
183Common::ParamPackage MouseAnalogFactory::GetNextInput() const {
184 MouseInput::MouseStatus pad;
185 Common::ParamPackage params;
186 auto& queue = mouse_input->GetMouseQueue();
187 while (queue.Pop(pad)) {
188 // This while loop will break on the earliest detected button
189 if (pad.button != MouseInput::MouseButton::Undefined) {
190 params.Set("engine", "mouse");
191 params.Set("port", static_cast<u16>(pad.button));
192 params.Set("axis_x", 0);
193 params.Set("axis_y", 1);
194 params.Set("invert_x", "+");
195 params.Set("invert_y", "+");
196 return params;
197 }
198 }
199 return params;
200}
201
202class MouseMotion final : public Input::MotionDevice {
203public:
204 explicit MouseMotion(u32 button_, const MouseInput::Mouse* mouse_input_)
205 : button(button_), mouse_input(mouse_input_) {}
206
207 Input::MotionStatus GetStatus() const override {
208 return mouse_input->GetMouseState(button).motion;
209 }
210
211private:
212 const u32 button;
213 const MouseInput::Mouse* mouse_input;
214};
215
216MouseMotionFactory::MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
217 : mouse_input(std::move(mouse_input_)) {}
218
219std::unique_ptr<Input::MotionDevice> MouseMotionFactory::Create(
220 const Common::ParamPackage& params) {
221 const auto button_id = params.Get("button", 0);
222
223 return std::make_unique<MouseMotion>(button_id, mouse_input.get());
224}
225
226Common::ParamPackage MouseMotionFactory::GetNextInput() const {
227 MouseInput::MouseStatus pad;
228 Common::ParamPackage params;
229 auto& queue = mouse_input->GetMouseQueue();
230 while (queue.Pop(pad)) {
231 // This while loop will break on the earliest detected button
232 if (pad.button != MouseInput::MouseButton::Undefined) {
233 params.Set("engine", "mouse");
234 params.Set("button", static_cast<u16>(pad.button));
235 return params;
236 }
237 }
238 return params;
239}
240
241void MouseMotionFactory::BeginConfiguration() {
242 polling = true;
243 mouse_input->BeginConfiguration();
244}
245
246void MouseMotionFactory::EndConfiguration() {
247 polling = false;
248 mouse_input->EndConfiguration();
249}
250
251class MouseTouch final : public Input::TouchDevice {
252public:
253 explicit MouseTouch(u32 button_, const MouseInput::Mouse* mouse_input_)
254 : button(button_), mouse_input(mouse_input_) {}
255
256 Input::TouchStatus GetStatus() const override {
257 return mouse_input->GetMouseState(button).touch;
258 }
259
260private:
261 const u32 button;
262 const MouseInput::Mouse* mouse_input;
263};
264
265MouseTouchFactory::MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
266 : mouse_input(std::move(mouse_input_)) {}
267
268std::unique_ptr<Input::TouchDevice> MouseTouchFactory::Create(const Common::ParamPackage& params) {
269 const auto button_id = params.Get("button", 0);
270
271 return std::make_unique<MouseTouch>(button_id, mouse_input.get());
272}
273
274Common::ParamPackage MouseTouchFactory::GetNextInput() const {
275 MouseInput::MouseStatus pad;
276 Common::ParamPackage params;
277 auto& queue = mouse_input->GetMouseQueue();
278 while (queue.Pop(pad)) {
279 // This while loop will break on the earliest detected button
280 if (pad.button != MouseInput::MouseButton::Undefined) {
281 params.Set("engine", "mouse");
282 params.Set("button", static_cast<u16>(pad.button));
283 return params;
284 }
285 }
286 return params;
287}
288
289void MouseTouchFactory::BeginConfiguration() {
290 polling = true;
291 mouse_input->BeginConfiguration();
292}
293
294void MouseTouchFactory::EndConfiguration() {
295 polling = false;
296 mouse_input->EndConfiguration();
297}
298
299} // namespace InputCommon
diff --git a/src/input_common/mouse/mouse_poller.h b/src/input_common/mouse/mouse_poller.h
deleted file mode 100644
index cf331293b..000000000
--- a/src/input_common/mouse/mouse_poller.h
+++ /dev/null
@@ -1,109 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "core/frontend/input.h"
9#include "input_common/mouse/mouse_input.h"
10
11namespace InputCommon {
12
13/**
14 * A button device factory representing a mouse. It receives mouse events and forward them
15 * to all button devices it created.
16 */
17class MouseButtonFactory final : public Input::Factory<Input::ButtonDevice> {
18public:
19 explicit MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
20
21 /**
22 * Creates a button device from a button press
23 * @param params contains parameters for creating the device:
24 * - "code": the code of the key to bind with the button
25 */
26 std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
27
28 Common::ParamPackage GetNextInput() const;
29
30 /// For device input configuration/polling
31 void BeginConfiguration();
32 void EndConfiguration();
33
34 bool IsPolling() const {
35 return polling;
36 }
37
38private:
39 std::shared_ptr<MouseInput::Mouse> mouse_input;
40 bool polling = false;
41};
42
43/// An analog device factory that creates analog devices from mouse
44class MouseAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
45public:
46 explicit MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
47
48 std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
49
50 Common::ParamPackage GetNextInput() const;
51
52 /// For device input configuration/polling
53 void BeginConfiguration();
54 void EndConfiguration();
55
56 bool IsPolling() const {
57 return polling;
58 }
59
60private:
61 std::shared_ptr<MouseInput::Mouse> mouse_input;
62 bool polling = false;
63};
64
65/// A motion device factory that creates motion devices from mouse
66class MouseMotionFactory final : public Input::Factory<Input::MotionDevice> {
67public:
68 explicit MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
69
70 std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
71
72 Common::ParamPackage GetNextInput() const;
73
74 /// For device input configuration/polling
75 void BeginConfiguration();
76 void EndConfiguration();
77
78 bool IsPolling() const {
79 return polling;
80 }
81
82private:
83 std::shared_ptr<MouseInput::Mouse> mouse_input;
84 bool polling = false;
85};
86
87/// An touch device factory that creates touch devices from mouse
88class MouseTouchFactory final : public Input::Factory<Input::TouchDevice> {
89public:
90 explicit MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
91
92 std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
93
94 Common::ParamPackage GetNextInput() const;
95
96 /// For device input configuration/polling
97 void BeginConfiguration();
98 void EndConfiguration();
99
100 bool IsPolling() const {
101 return polling;
102 }
103
104private:
105 std::shared_ptr<MouseInput::Mouse> mouse_input;
106 bool polling = false;
107};
108
109} // namespace InputCommon