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.cpp208
1 files changed, 208 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..c65d05041
--- /dev/null
+++ b/src/core/hid/emulated_console.cpp
@@ -0,0 +1,208 @@
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 <fmt/format.h>
6
7#include "core/hid/emulated_console.h"
8#include "core/hid/input_converter.h"
9
10namespace Core::HID {
11EmulatedConsole::EmulatedConsole() {}
12
13EmulatedConsole::~EmulatedConsole() = default;
14
15void EmulatedConsole::ReloadFromSettings() {
16 // Using first motion device from player 1. No need to assign a special config at the moment
17 const auto& player = Settings::values.players.GetValue()[0];
18 motion_params = Common::ParamPackage(player.motions[0]);
19
20 ReloadInput();
21}
22
23void EmulatedConsole::ReloadInput() {
24 motion_devices = Input::CreateDevice<Input::InputDevice>(motion_params);
25 if (motion_devices) {
26 Input::InputCallback motion_callback{
27 [this](Input::CallbackStatus callback) { SetMotion(callback); }};
28 motion_devices->SetCallback(motion_callback);
29 }
30
31 // TODO: Fix this mess
32 std::size_t index = 0;
33 const std::string mouse_device_string =
34 fmt::format("engine:mouse,axis_x:10,axis_y:11,button:{}", index);
35 touch_devices[index] = Input::CreateDeviceFromString<Input::InputDevice>(mouse_device_string);
36 Input::InputCallback trigger_callbackk{
37 [this, index](Input::CallbackStatus callback) { SetTouch(callback, index); }};
38 touch_devices[index]->SetCallback(trigger_callbackk);
39
40 index++;
41 const auto button_index =
42 static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
43 const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
44 for (const auto& config_entry : touch_buttons) {
45 Common::ParamPackage params{config_entry};
46 Common::ParamPackage touch_button_params;
47 const int x = params.Get("x", 0);
48 const int y = params.Get("y", 0);
49 params.Erase("x");
50 params.Erase("y");
51 touch_button_params.Set("engine", "touch_from_button");
52 touch_button_params.Set("button", params.Serialize());
53 touch_button_params.Set("x", x);
54 touch_button_params.Set("y", y);
55 touch_button_params.Set("touch_id", static_cast<int>(index));
56 LOG_ERROR(Common, "{} ", touch_button_params.Serialize());
57 touch_devices[index] =
58 Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize());
59 if (!touch_devices[index]) {
60 continue;
61 }
62
63 Input::InputCallback trigger_callback{
64 [this, index](Input::CallbackStatus callback) { SetTouch(callback, index); }};
65 touch_devices[index]->SetCallback(trigger_callback);
66 index++;
67 }
68}
69
70void EmulatedConsole::UnloadInput() {
71 motion_devices.reset();
72 for (auto& touch : touch_devices) {
73 touch.reset();
74 }
75}
76
77void EmulatedConsole::EnableConfiguration() {
78 is_configuring = true;
79 SaveCurrentConfig();
80}
81
82void EmulatedConsole::DisableConfiguration() {
83 is_configuring = false;
84}
85
86bool EmulatedConsole::IsConfiguring() const {
87 return is_configuring;
88}
89
90void EmulatedConsole::SaveCurrentConfig() {
91 if (!is_configuring) {
92 return;
93 }
94}
95
96void EmulatedConsole::RestoreConfig() {
97 if (!is_configuring) {
98 return;
99 }
100 ReloadFromSettings();
101}
102
103Common::ParamPackage EmulatedConsole::GetMotionParam() const {
104 return motion_params;
105}
106
107void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
108 motion_params = param;
109 ReloadInput();
110}
111
112void EmulatedConsole::SetMotion(Input::CallbackStatus callback) {
113 std::lock_guard lock{mutex};
114 auto& raw_status = console.motion_values.raw_status;
115 auto& emulated = console.motion_values.emulated;
116
117 raw_status = TransformToMotion(callback);
118 emulated.SetAcceleration(Common::Vec3f{
119 raw_status.accel.x.value,
120 raw_status.accel.y.value,
121 raw_status.accel.z.value,
122 });
123 emulated.SetGyroscope(Common::Vec3f{
124 raw_status.gyro.x.value,
125 raw_status.gyro.y.value,
126 raw_status.gyro.z.value,
127 });
128 emulated.UpdateRotation(raw_status.delta_timestamp);
129 emulated.UpdateOrientation(raw_status.delta_timestamp);
130
131 if (is_configuring) {
132 TriggerOnChange(ConsoleTriggerType::Motion);
133 return;
134 }
135
136 auto& motion = console.motion_state;
137 motion.accel = emulated.GetAcceleration();
138 motion.gyro = emulated.GetGyroscope();
139 motion.rotation = emulated.GetGyroscope();
140 motion.orientation = emulated.GetOrientation();
141 motion.quaternion = emulated.GetQuaternion();
142 motion.is_at_rest = emulated.IsMoving(motion_sensitivity);
143
144 TriggerOnChange(ConsoleTriggerType::Motion);
145}
146
147void EmulatedConsole::SetTouch(Input::CallbackStatus callback, [[maybe_unused]] std::size_t index) {
148 if (index >= console.touch_values.size()) {
149 return;
150 }
151 std::lock_guard lock{mutex};
152
153 console.touch_values[index] = TransformToTouch(callback);
154
155 if (is_configuring) {
156 TriggerOnChange(ConsoleTriggerType::Touch);
157 return;
158 }
159
160 console.touch_state[index] = {
161 .position = {console.touch_values[index].x.value, console.touch_values[index].y.value},
162 .id = console.touch_values[index].id,
163 .pressed = console.touch_values[index].pressed.value,
164 };
165
166 TriggerOnChange(ConsoleTriggerType::Touch);
167}
168
169ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
170 return console.motion_values;
171}
172
173TouchValues EmulatedConsole::GetTouchValues() const {
174 return console.touch_values;
175}
176
177ConsoleMotion EmulatedConsole::GetMotion() const {
178 return console.motion_state;
179}
180
181TouchFingerState EmulatedConsole::GetTouch() const {
182 return console.touch_state;
183}
184
185void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
186 for (const std::pair<int, ConsoleUpdateCallback> poller_pair : callback_list) {
187 const ConsoleUpdateCallback& poller = poller_pair.second;
188 if (poller.on_change) {
189 poller.on_change(type);
190 }
191 }
192}
193
194int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
195 std::lock_guard lock{mutex};
196 callback_list.insert_or_assign(last_callback_key, update_callback);
197 return last_callback_key++;
198}
199
200void EmulatedConsole::DeleteCallback(int key) {
201 std::lock_guard lock{mutex};
202 if (!callback_list.contains(key)) {
203 LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
204 return;
205 }
206 callback_list.erase(key);
207}
208} // namespace Core::HID