summaryrefslogtreecommitdiff
path: root/src/core/hid/emulated_console.cpp
diff options
context:
space:
mode:
authorGravatar Fernando S2021-11-27 11:52:08 +0100
committerGravatar GitHub2021-11-27 11:52:08 +0100
commit564f10527745f870621c08bbb5d16badee0ed861 (patch)
treee8ac8dee60086facf1837393882865f5df18c95e /src/core/hid/emulated_console.cpp
parentMerge pull request #7431 from liushuyu/fix-linux-decoding (diff)
parentconfig: Remove vibration configuration (diff)
downloadyuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.gz
yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.xz
yuzu-564f10527745f870621c08bbb5d16badee0ed861.zip
Merge pull request #7255 from german77/kraken
Project Kraken: Input rewrite
Diffstat (limited to 'src/core/hid/emulated_console.cpp')
-rw-r--r--src/core/hid/emulated_console.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
new file mode 100644
index 000000000..80db8e9c6
--- /dev/null
+++ b/src/core/hid/emulated_console.cpp
@@ -0,0 +1,229 @@
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 "common/settings.h"
6#include "core/hid/emulated_console.h"
7#include "core/hid/input_converter.h"
8
9namespace Core::HID {
10EmulatedConsole::EmulatedConsole() = default;
11
12EmulatedConsole::~EmulatedConsole() = default;
13
14void EmulatedConsole::ReloadFromSettings() {
15 // Using first motion device from player 1. No need to assign any unique config at the moment
16 const auto& player = Settings::values.players.GetValue()[0];
17 motion_params = Common::ParamPackage(player.motions[0]);
18
19 ReloadInput();
20}
21
22void EmulatedConsole::SetTouchParams() {
23 // TODO(german77): Support any number of fingers
24 std::size_t index = 0;
25
26 // Hardcode mouse, touchscreen and cemuhook parameters
27 if (!Settings::values.mouse_enabled) {
28 // We can't use mouse as touch if native mouse is enabled
29 touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
30 }
31 touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"};
32 touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"};
33 touch_params[index++] =
34 Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
35 touch_params[index++] =
36 Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"};
37
38 const auto button_index =
39 static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
40 const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
41
42 // Map the rest of the fingers from touch from button configuration
43 for (const auto& config_entry : touch_buttons) {
44 if (index >= touch_params.size()) {
45 continue;
46 }
47 Common::ParamPackage params{config_entry};
48 Common::ParamPackage touch_button_params;
49 const int x = params.Get("x", 0);
50 const int y = params.Get("y", 0);
51 params.Erase("x");
52 params.Erase("y");
53 touch_button_params.Set("engine", "touch_from_button");
54 touch_button_params.Set("button", params.Serialize());
55 touch_button_params.Set("x", x);
56 touch_button_params.Set("y", y);
57 touch_button_params.Set("touch_id", static_cast<int>(index));
58 touch_params[index] = touch_button_params;
59 index++;
60 }
61}
62
63void EmulatedConsole::ReloadInput() {
64 // If you load any device here add the equivalent to the UnloadInput() function
65 SetTouchParams();
66
67 motion_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(motion_params);
68 if (motion_devices) {
69 Common::Input::InputCallback motion_callback{
70 [this](Common::Input::CallbackStatus callback) { SetMotion(callback); }};
71 motion_devices->SetCallback(motion_callback);
72 }
73
74 // Unique index for identifying touch device source
75 std::size_t index = 0;
76 for (auto& touch_device : touch_devices) {
77 touch_device = Common::Input::CreateDevice<Common::Input::InputDevice>(touch_params[index]);
78 if (!touch_device) {
79 continue;
80 }
81 Common::Input::InputCallback touch_callback{
82 [this, index](Common::Input::CallbackStatus callback) { SetTouch(callback, index); }};
83 touch_device->SetCallback(touch_callback);
84 index++;
85 }
86}
87
88void EmulatedConsole::UnloadInput() {
89 motion_devices.reset();
90 for (auto& touch : touch_devices) {
91 touch.reset();
92 }
93}
94
95void EmulatedConsole::EnableConfiguration() {
96 is_configuring = true;
97 SaveCurrentConfig();
98}
99
100void EmulatedConsole::DisableConfiguration() {
101 is_configuring = false;
102}
103
104bool EmulatedConsole::IsConfiguring() const {
105 return is_configuring;
106}
107
108void EmulatedConsole::SaveCurrentConfig() {
109 if (!is_configuring) {
110 return;
111 }
112}
113
114void EmulatedConsole::RestoreConfig() {
115 if (!is_configuring) {
116 return;
117 }
118 ReloadFromSettings();
119}
120
121Common::ParamPackage EmulatedConsole::GetMotionParam() const {
122 return motion_params;
123}
124
125void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
126 motion_params = param;
127 ReloadInput();
128}
129
130void EmulatedConsole::SetMotion(Common::Input::CallbackStatus callback) {
131 std::lock_guard lock{mutex};
132 auto& raw_status = console.motion_values.raw_status;
133 auto& emulated = console.motion_values.emulated;
134
135 raw_status = TransformToMotion(callback);
136 emulated.SetAcceleration(Common::Vec3f{
137 raw_status.accel.x.value,
138 raw_status.accel.y.value,
139 raw_status.accel.z.value,
140 });
141 emulated.SetGyroscope(Common::Vec3f{
142 raw_status.gyro.x.value,
143 raw_status.gyro.y.value,
144 raw_status.gyro.z.value,
145 });
146 emulated.UpdateRotation(raw_status.delta_timestamp);
147 emulated.UpdateOrientation(raw_status.delta_timestamp);
148
149 if (is_configuring) {
150 TriggerOnChange(ConsoleTriggerType::Motion);
151 return;
152 }
153
154 auto& motion = console.motion_state;
155 motion.accel = emulated.GetAcceleration();
156 motion.gyro = emulated.GetGyroscope();
157 motion.rotation = emulated.GetGyroscope();
158 motion.orientation = emulated.GetOrientation();
159 motion.quaternion = emulated.GetQuaternion();
160 motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
161
162 TriggerOnChange(ConsoleTriggerType::Motion);
163}
164
165void EmulatedConsole::SetTouch(Common::Input::CallbackStatus callback,
166 [[maybe_unused]] std::size_t index) {
167 if (index >= console.touch_values.size()) {
168 return;
169 }
170 std::lock_guard lock{mutex};
171
172 console.touch_values[index] = TransformToTouch(callback);
173
174 if (is_configuring) {
175 TriggerOnChange(ConsoleTriggerType::Touch);
176 return;
177 }
178
179 // TODO(german77): Remap touch id in sequential order
180 console.touch_state[index] = {
181 .position = {console.touch_values[index].x.value, console.touch_values[index].y.value},
182 .id = static_cast<u32>(console.touch_values[index].id),
183 .pressed = console.touch_values[index].pressed.value,
184 };
185
186 TriggerOnChange(ConsoleTriggerType::Touch);
187}
188
189ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
190 return console.motion_values;
191}
192
193TouchValues EmulatedConsole::GetTouchValues() const {
194 return console.touch_values;
195}
196
197ConsoleMotion EmulatedConsole::GetMotion() const {
198 return console.motion_state;
199}
200
201TouchFingerState EmulatedConsole::GetTouch() const {
202 return console.touch_state;
203}
204
205void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
206 for (const auto& poller_pair : callback_list) {
207 const ConsoleUpdateCallback& poller = poller_pair.second;
208 if (poller.on_change) {
209 poller.on_change(type);
210 }
211 }
212}
213
214int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
215 std::lock_guard lock{mutex};
216 callback_list.insert_or_assign(last_callback_key, update_callback);
217 return last_callback_key++;
218}
219
220void EmulatedConsole::DeleteCallback(int key) {
221 std::lock_guard lock{mutex};
222 const auto& iterator = callback_list.find(key);
223 if (iterator == callback_list.end()) {
224 LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
225 return;
226 }
227 callback_list.erase(iterator);
228}
229} // namespace Core::HID