summaryrefslogtreecommitdiff
path: root/src/input_common/drivers
diff options
context:
space:
mode:
authorGravatar german772021-09-20 17:19:55 -0500
committerGravatar Narr the Reg2021-11-24 20:30:22 -0600
commit00834b84dd954f6aea2354e07de2054a99f53fa4 (patch)
treea6eede83ae8253759d860ef08f9bce9bebd8dd29 /src/input_common/drivers
parentinput_common: Rewrite keyboard (diff)
downloadyuzu-00834b84dd954f6aea2354e07de2054a99f53fa4.tar.gz
yuzu-00834b84dd954f6aea2354e07de2054a99f53fa4.tar.xz
yuzu-00834b84dd954f6aea2354e07de2054a99f53fa4.zip
input_common: Rewrite mouse
Diffstat (limited to '')
-rw-r--r--src/input_common/drivers/mouse.cpp138
-rw-r--r--src/input_common/drivers/mouse.h77
2 files changed, 215 insertions, 0 deletions
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