summaryrefslogtreecommitdiff
path: root/src/core/hid/emulated_console.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hid/emulated_console.cpp')
-rw-r--r--src/core/hid/emulated_console.cpp324
1 files changed, 0 insertions, 324 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
deleted file mode 100644
index b4afd930e..000000000
--- a/src/core/hid/emulated_console.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/settings.h"
5#include "core/hid/emulated_console.h"
6#include "core/hid/input_converter.h"
7
8namespace Core::HID {
9EmulatedConsole::EmulatedConsole() = default;
10
11EmulatedConsole::~EmulatedConsole() = default;
12
13void EmulatedConsole::ReloadFromSettings() {
14 // Using first motion device from player 1. No need to assign any unique config at the moment
15 const auto& player = Settings::values.players.GetValue()[0];
16 motion_params[0] = Common::ParamPackage(player.motions[0]);
17
18 ReloadInput();
19}
20
21void EmulatedConsole::SetTouchParams() {
22 std::size_t index = 0;
23
24 // We can't use mouse as touch if native mouse is enabled
25 if (!Settings::values.mouse_enabled) {
26 touch_params[index++] =
27 Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
28 }
29
30 touch_params[index++] =
31 Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
32 touch_params[index++] =
33 Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"};
34
35 for (int i = 0; i < static_cast<int>(MaxActiveTouchInputs); i++) {
36 Common::ParamPackage touchscreen_param{};
37 touchscreen_param.Set("engine", "touch");
38 touchscreen_param.Set("axis_x", i * 2);
39 touchscreen_param.Set("axis_y", (i * 2) + 1);
40 touchscreen_param.Set("button", i);
41 touch_params[index++] = std::move(touchscreen_param);
42 }
43
44 if (Settings::values.touch_from_button_maps.empty()) {
45 LOG_WARNING(Input, "touch_from_button_maps is unset by frontend config");
46 return;
47 }
48
49 const auto button_index =
50 static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
51 const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
52
53 // Map the rest of the fingers from touch from button configuration
54 for (const auto& config_entry : touch_buttons) {
55 if (index >= MaxTouchDevices) {
56 continue;
57 }
58 Common::ParamPackage params{config_entry};
59 Common::ParamPackage touch_button_params;
60 const int x = params.Get("x", 0);
61 const int y = params.Get("y", 0);
62 params.Erase("x");
63 params.Erase("y");
64 touch_button_params.Set("engine", "touch_from_button");
65 touch_button_params.Set("button", params.Serialize());
66 touch_button_params.Set("x", x);
67 touch_button_params.Set("y", y);
68 touch_params[index] = std::move(touch_button_params);
69 index++;
70 }
71}
72
73void EmulatedConsole::ReloadInput() {
74 // If you load any device here add the equivalent to the UnloadInput() function
75 SetTouchParams();
76
77 motion_params[1] = Common::ParamPackage{"engine:virtual_gamepad,port:8,motion:0"};
78
79 for (std::size_t index = 0; index < motion_devices.size(); ++index) {
80 motion_devices[index] = Common::Input::CreateInputDevice(motion_params[index]);
81 if (!motion_devices[index]) {
82 continue;
83 }
84 motion_devices[index]->SetCallback({
85 .on_change =
86 [this](const Common::Input::CallbackStatus& callback) { SetMotion(callback); },
87 });
88 }
89
90 // Restore motion state
91 auto& emulated_motion = console.motion_values.emulated;
92 auto& motion = console.motion_state;
93 emulated_motion.ResetRotations();
94 emulated_motion.ResetQuaternion();
95 motion.accel = emulated_motion.GetAcceleration();
96 motion.gyro = emulated_motion.GetGyroscope();
97 motion.rotation = emulated_motion.GetRotations();
98 motion.orientation = emulated_motion.GetOrientation();
99 motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
100
101 // Unique index for identifying touch device source
102 std::size_t index = 0;
103 for (auto& touch_device : touch_devices) {
104 touch_device = Common::Input::CreateInputDevice(touch_params[index]);
105 if (!touch_device) {
106 continue;
107 }
108 touch_device->SetCallback({
109 .on_change =
110 [this, index](const Common::Input::CallbackStatus& callback) {
111 SetTouch(callback, index);
112 },
113 });
114 index++;
115 }
116}
117
118void EmulatedConsole::UnloadInput() {
119 for (auto& motion : motion_devices) {
120 motion.reset();
121 }
122 for (auto& touch : touch_devices) {
123 touch.reset();
124 }
125}
126
127void EmulatedConsole::EnableConfiguration() {
128 is_configuring = true;
129 SaveCurrentConfig();
130}
131
132void EmulatedConsole::DisableConfiguration() {
133 is_configuring = false;
134}
135
136bool EmulatedConsole::IsConfiguring() const {
137 return is_configuring;
138}
139
140void EmulatedConsole::SaveCurrentConfig() {
141 if (!is_configuring) {
142 return;
143 }
144}
145
146void EmulatedConsole::RestoreConfig() {
147 if (!is_configuring) {
148 return;
149 }
150 ReloadFromSettings();
151}
152
153Common::ParamPackage EmulatedConsole::GetMotionParam() const {
154 return motion_params[0];
155}
156
157void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
158 motion_params[0] = std::move(param);
159 ReloadInput();
160}
161
162void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
163 std::unique_lock lock{mutex};
164 auto& raw_status = console.motion_values.raw_status;
165 auto& emulated = console.motion_values.emulated;
166
167 raw_status = TransformToMotion(callback);
168 emulated.SetAcceleration(Common::Vec3f{
169 raw_status.accel.x.value,
170 raw_status.accel.y.value,
171 raw_status.accel.z.value,
172 });
173 emulated.SetGyroscope(Common::Vec3f{
174 raw_status.gyro.x.value,
175 raw_status.gyro.y.value,
176 raw_status.gyro.z.value,
177 });
178 emulated.UpdateRotation(raw_status.delta_timestamp);
179 emulated.UpdateOrientation(raw_status.delta_timestamp);
180
181 if (is_configuring) {
182 lock.unlock();
183 TriggerOnChange(ConsoleTriggerType::Motion);
184 return;
185 }
186
187 auto& motion = console.motion_state;
188 motion.accel = emulated.GetAcceleration();
189 motion.gyro = emulated.GetGyroscope();
190 motion.rotation = emulated.GetRotations();
191 motion.orientation = emulated.GetOrientation();
192 motion.quaternion = emulated.GetQuaternion();
193 motion.gyro_bias = emulated.GetGyroBias();
194 motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
195 // Find what is this value
196 motion.verticalization_error = 0.0f;
197
198 lock.unlock();
199 TriggerOnChange(ConsoleTriggerType::Motion);
200}
201
202void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index) {
203 if (index >= MaxTouchDevices) {
204 return;
205 }
206 std::unique_lock lock{mutex};
207
208 const auto touch_input = TransformToTouch(callback);
209 auto touch_index = GetIndexFromFingerId(index);
210 bool is_new_input = false;
211
212 if (!touch_index.has_value() && touch_input.pressed.value) {
213 touch_index = GetNextFreeIndex();
214 is_new_input = true;
215 }
216
217 // No free entries or invalid state. Ignore input
218 if (!touch_index.has_value()) {
219 return;
220 }
221
222 auto& touch_value = console.touch_values[touch_index.value()];
223
224 if (is_new_input) {
225 touch_value.pressed.value = true;
226 touch_value.id = static_cast<int>(index);
227 }
228
229 touch_value.x = touch_input.x;
230 touch_value.y = touch_input.y;
231
232 if (!touch_input.pressed.value) {
233 touch_value.pressed.value = false;
234 }
235
236 if (is_configuring) {
237 lock.unlock();
238 TriggerOnChange(ConsoleTriggerType::Touch);
239 return;
240 }
241
242 // Touch outside allowed range. Ignore input
243 if (touch_index.value() >= MaxActiveTouchInputs) {
244 return;
245 }
246
247 console.touch_state[touch_index.value()] = {
248 .position = {touch_value.x.value, touch_value.y.value},
249 .id = static_cast<u32>(touch_index.value()),
250 .pressed = touch_input.pressed.value,
251 };
252
253 lock.unlock();
254 TriggerOnChange(ConsoleTriggerType::Touch);
255}
256
257ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
258 std::scoped_lock lock{mutex};
259 return console.motion_values;
260}
261
262TouchValues EmulatedConsole::GetTouchValues() const {
263 std::scoped_lock lock{mutex};
264 return console.touch_values;
265}
266
267ConsoleMotion EmulatedConsole::GetMotion() const {
268 std::scoped_lock lock{mutex};
269 return console.motion_state;
270}
271
272TouchFingerState EmulatedConsole::GetTouch() const {
273 std::scoped_lock lock{mutex};
274 return console.touch_state;
275}
276
277std::optional<std::size_t> EmulatedConsole::GetIndexFromFingerId(std::size_t finger_id) const {
278 for (std::size_t index = 0; index < MaxTouchDevices; ++index) {
279 const auto& finger = console.touch_values[index];
280 if (!finger.pressed.value) {
281 continue;
282 }
283 if (finger.id == static_cast<int>(finger_id)) {
284 return index;
285 }
286 }
287 return std::nullopt;
288}
289
290std::optional<std::size_t> EmulatedConsole::GetNextFreeIndex() const {
291 for (std::size_t index = 0; index < MaxTouchDevices; ++index) {
292 if (!console.touch_values[index].pressed.value) {
293 return index;
294 }
295 }
296 return std::nullopt;
297}
298
299void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
300 std::scoped_lock lock{callback_mutex};
301 for (const auto& poller_pair : callback_list) {
302 const ConsoleUpdateCallback& poller = poller_pair.second;
303 if (poller.on_change) {
304 poller.on_change(type);
305 }
306 }
307}
308
309int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
310 std::scoped_lock lock{callback_mutex};
311 callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
312 return last_callback_key++;
313}
314
315void EmulatedConsole::DeleteCallback(int key) {
316 std::scoped_lock lock{callback_mutex};
317 const auto& iterator = callback_list.find(key);
318 if (iterator == callback_list.end()) {
319 LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
320 return;
321 }
322 callback_list.erase(iterator);
323}
324} // namespace Core::HID