summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/input_common/CMakeLists.txt6
-rw-r--r--src/input_common/drivers/udp_client.cpp (renamed from src/input_common/udp/client.cpp)242
-rw-r--r--src/input_common/drivers/udp_client.h (renamed from src/input_common/udp/client.h)80
-rw-r--r--src/input_common/udp/udp.cpp110
-rw-r--r--src/input_common/udp/udp.h57
5 files changed, 54 insertions, 441 deletions
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 19270dc84..9c0c82138 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -9,6 +9,8 @@ add_library(input_common STATIC
9 drivers/tas_input.h 9 drivers/tas_input.h
10 drivers/touch_screen.cpp 10 drivers/touch_screen.cpp
11 drivers/touch_screen.h 11 drivers/touch_screen.h
12 drivers/udp_client.cpp
13 drivers/udp_client.h
12 helpers/stick_from_buttons.cpp 14 helpers/stick_from_buttons.cpp
13 helpers/stick_from_buttons.h 15 helpers/stick_from_buttons.h
14 helpers/touch_from_buttons.cpp 16 helpers/touch_from_buttons.cpp
@@ -29,10 +31,6 @@ add_library(input_common STATIC
29 motion_input.h 31 motion_input.h
30 sdl/sdl.cpp 32 sdl/sdl.cpp
31 sdl/sdl.h 33 sdl/sdl.h
32 udp/client.cpp
33 udp/client.h
34 udp/udp.cpp
35 udp/udp.h
36) 34)
37 35
38if (MSVC) 36if (MSVC)
diff --git a/src/input_common/udp/client.cpp b/src/input_common/drivers/udp_client.cpp
index bcc29c4e0..6fcc3a01b 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/drivers/udp_client.cpp
@@ -2,15 +2,13 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <chrono>
6#include <cstring>
7#include <functional>
8#include <random> 5#include <random>
9#include <thread>
10#include <boost/asio.hpp> 6#include <boost/asio.hpp>
7
11#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/param_package.h"
12#include "common/settings.h" 10#include "common/settings.h"
13#include "input_common/udp/client.h" 11#include "input_common/drivers/udp_client.h"
14#include "input_common/helpers/udp_protocol.h" 12#include "input_common/helpers/udp_protocol.h"
15 13
16using boost::asio::ip::udp; 14using boost::asio::ip::udp;
@@ -86,7 +84,6 @@ private:
86 case Type::PadData: { 84 case Type::PadData: {
87 Response::PadData pad_data; 85 Response::PadData pad_data;
88 std::memcpy(&pad_data, &receive_buffer[sizeof(Header)], sizeof(Response::PadData)); 86 std::memcpy(&pad_data, &receive_buffer[sizeof(Header)], sizeof(Response::PadData));
89 SanitizeMotion(pad_data);
90 callback.pad_data(std::move(pad_data)); 87 callback.pad_data(std::move(pad_data));
91 break; 88 break;
92 } 89 }
@@ -115,28 +112,6 @@ private:
115 StartSend(timer.expiry()); 112 StartSend(timer.expiry());
116 } 113 }
117 114
118 void SanitizeMotion(Response::PadData& data) {
119 // Zero out any non number value
120 if (!std::isnormal(data.gyro.pitch)) {
121 data.gyro.pitch = 0;
122 }
123 if (!std::isnormal(data.gyro.roll)) {
124 data.gyro.roll = 0;
125 }
126 if (!std::isnormal(data.gyro.yaw)) {
127 data.gyro.yaw = 0;
128 }
129 if (!std::isnormal(data.accel.x)) {
130 data.accel.x = 0;
131 }
132 if (!std::isnormal(data.accel.y)) {
133 data.accel.y = 0;
134 }
135 if (!std::isnormal(data.accel.z)) {
136 data.accel.z = 0;
137 }
138 }
139
140 SocketCallback callback; 115 SocketCallback callback;
141 boost::asio::io_service io_service; 116 boost::asio::io_service io_service;
142 boost::asio::basic_waitable_timer<clock> timer; 117 boost::asio::basic_waitable_timer<clock> timer;
@@ -160,48 +135,23 @@ static void SocketLoop(Socket* socket) {
160 socket->Loop(); 135 socket->Loop();
161} 136}
162 137
163Client::Client() { 138UDPClient::UDPClient(const std::string& input_engine_) : InputEngine(input_engine_) {
164 LOG_INFO(Input, "Udp Initialization started"); 139 LOG_INFO(Input, "Udp Initialization started");
165 finger_id.fill(MAX_TOUCH_FINGERS);
166 ReloadSockets(); 140 ReloadSockets();
167} 141}
168 142
169Client::~Client() { 143UDPClient::~UDPClient() {
170 Reset(); 144 Reset();
171} 145}
172 146
173Client::ClientConnection::ClientConnection() = default; 147UDPClient::ClientConnection::ClientConnection() = default;
174 148
175Client::ClientConnection::~ClientConnection() = default; 149UDPClient::ClientConnection::~ClientConnection() = default;
176
177std::vector<Common::ParamPackage> Client::GetInputDevices() const {
178 std::vector<Common::ParamPackage> devices;
179 for (std::size_t pad = 0; pad < pads.size(); pad++) {
180 if (!DeviceConnected(pad)) {
181 continue;
182 }
183 std::string name = fmt::format("UDP Controller {}", pad);
184 devices.emplace_back(Common::ParamPackage{
185 {"class", "cemuhookudp"},
186 {"display", std::move(name)},
187 {"port", std::to_string(pad)},
188 });
189 }
190 return devices;
191}
192
193bool Client::DeviceConnected(std::size_t pad) const {
194 // Use last timestamp to detect if the socket has stopped sending data
195 const auto now = std::chrono::steady_clock::now();
196 const auto time_difference = static_cast<u64>(
197 std::chrono::duration_cast<std::chrono::milliseconds>(now - pads[pad].last_update).count());
198 return time_difference < 1000 && pads[pad].connected;
199}
200 150
201void Client::ReloadSockets() { 151void UDPClient::ReloadSockets() {
202 Reset(); 152 Reset();
203 153
204 std::stringstream servers_ss(static_cast<std::string>(Settings::values.udp_input_servers)); 154 std::stringstream servers_ss(Settings::values.udp_input_servers.GetValue());
205 std::string server_token; 155 std::string server_token;
206 std::size_t client = 0; 156 std::size_t client = 0;
207 while (std::getline(servers_ss, server_token, ',')) { 157 while (std::getline(servers_ss, server_token, ',')) {
@@ -229,7 +179,7 @@ void Client::ReloadSockets() {
229 } 179 }
230} 180}
231 181
232std::size_t Client::GetClientNumber(std::string_view host, u16 port) const { 182std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
233 for (std::size_t client = 0; client < clients.size(); client++) { 183 for (std::size_t client = 0; client < clients.size(); client++) {
234 if (clients[client].active == -1) { 184 if (clients[client].active == -1) {
235 continue; 185 continue;
@@ -241,15 +191,15 @@ std::size_t Client::GetClientNumber(std::string_view host, u16 port) const {
241 return MAX_UDP_CLIENTS; 191 return MAX_UDP_CLIENTS;
242} 192}
243 193
244void Client::OnVersion([[maybe_unused]] Response::Version data) { 194void UDPClient::OnVersion([[maybe_unused]] Response::Version data) {
245 LOG_TRACE(Input, "Version packet received: {}", data.version); 195 LOG_TRACE(Input, "Version packet received: {}", data.version);
246} 196}
247 197
248void Client::OnPortInfo([[maybe_unused]] Response::PortInfo data) { 198void UDPClient::OnPortInfo([[maybe_unused]] Response::PortInfo data) {
249 LOG_TRACE(Input, "PortInfo packet received: {}", data.model); 199 LOG_TRACE(Input, "PortInfo packet received: {}", data.model);
250} 200}
251 201
252void Client::OnPadData(Response::PadData data, std::size_t client) { 202void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
253 const std::size_t pad_index = (client * PADS_PER_CLIENT) + data.info.id; 203 const std::size_t pad_index = (client * PADS_PER_CLIENT) + data.info.id;
254 204
255 if (pad_index >= pads.size()) { 205 if (pad_index >= pads.size()) {
@@ -277,32 +227,25 @@ void Client::OnPadData(Response::PadData data, std::size_t client) {
277 .count()); 227 .count());
278 pads[pad_index].last_update = now; 228 pads[pad_index].last_update = now;
279 229
280 const Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw};
281 pads[pad_index].motion.SetAcceleration({data.accel.x, -data.accel.z, data.accel.y});
282 // Gyroscope values are not it the correct scale from better joy. 230 // Gyroscope values are not it the correct scale from better joy.
283 // Dividing by 312 allows us to make one full turn = 1 turn 231 // Dividing by 312 allows us to make one full turn = 1 turn
284 // This must be a configurable valued called sensitivity 232 // This must be a configurable valued called sensitivity
285 pads[pad_index].motion.SetGyroscope(raw_gyroscope / 312.0f); 233 const float gyro_scale = 1.0f / 312.0f;
286 pads[pad_index].motion.UpdateRotation(time_difference); 234
287 pads[pad_index].motion.UpdateOrientation(time_difference); 235 const BasicMotion motion{
288 236 .gyro_x = data.gyro.pitch * gyro_scale,
289 { 237 .gyro_y = data.gyro.roll * gyro_scale,
290 std::lock_guard guard(pads[pad_index].status.update_mutex); 238 .gyro_z = -data.gyro.yaw * gyro_scale,
291 pads[pad_index].status.motion_status = pads[pad_index].motion.GetMotion(); 239 .accel_x = data.accel.x,
292 240 .accel_y = -data.accel.z,
293 for (std::size_t id = 0; id < data.touch.size(); ++id) { 241 .accel_z = data.accel.y,
294 UpdateTouchInput(data.touch[id], client, id); 242 .delta_timestamp = time_difference,
295 } 243 };
296 244 const PadIdentifier identifier = GetPadIdentifier(pad_index);
297 if (configuring) { 245 SetMotion(identifier, 0, motion);
298 const Common::Vec3f gyroscope = pads[pad_index].motion.GetGyroscope();
299 const Common::Vec3f accelerometer = pads[pad_index].motion.GetAcceleration();
300 UpdateYuzuSettings(client, data.info.id, accelerometer, gyroscope);
301 }
302 }
303} 246}
304 247
305void Client::StartCommunication(std::size_t client, const std::string& host, u16 port) { 248void UDPClient::StartCommunication(std::size_t client, const std::string& host, u16 port) {
306 SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, 249 SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
307 [this](Response::PortInfo info) { OnPortInfo(info); }, 250 [this](Response::PortInfo info) { OnPortInfo(info); },
308 [this, client](Response::PadData data) { OnPadData(data, client); }}; 251 [this, client](Response::PadData data) { OnPadData(data, client); }};
@@ -312,16 +255,22 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
312 clients[client].active = 0; 255 clients[client].active = 0;
313 clients[client].socket = std::make_unique<Socket>(host, port, callback); 256 clients[client].socket = std::make_unique<Socket>(host, port, callback);
314 clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()}; 257 clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
315 258 for (std::size_t index = 0; index < PADS_PER_CLIENT; ++index) {
316 // Set motion parameters 259 const PadIdentifier identifier = GetPadIdentifier(client * PADS_PER_CLIENT + index);
317 // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode 260 PreSetController(identifier);
318 // Real HW values are unknown, 0.0001 is an approximate to Standard
319 for (std::size_t pad = 0; pad < PADS_PER_CLIENT; pad++) {
320 pads[client * PADS_PER_CLIENT + pad].motion.SetGyroThreshold(0.0001f);
321 } 261 }
322} 262}
323 263
324void Client::Reset() { 264const PadIdentifier UDPClient::GetPadIdentifier(std::size_t pad_index) const {
265 const std::size_t client = pad_index / PADS_PER_CLIENT;
266 return {
267 .guid = Common::UUID{clients[client].host},
268 .port = static_cast<std::size_t>(clients[client].port),
269 .pad = pad_index,
270 };
271}
272
273void UDPClient::Reset() {
325 for (auto& client : clients) { 274 for (auto& client : clients) {
326 if (client.thread.joinable()) { 275 if (client.thread.joinable()) {
327 client.active = -1; 276 client.active = -1;
@@ -331,117 +280,6 @@ void Client::Reset() {
331 } 280 }
332} 281}
333 282
334void Client::UpdateYuzuSettings(std::size_t client, std::size_t pad_index,
335 const Common::Vec3<float>& acc, const Common::Vec3<float>& gyro) {
336 if (gyro.Length() > 0.2f) {
337 LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {})", client,
338 gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2]);
339 }
340 UDPPadStatus pad{
341 .host = clients[client].host,
342 .port = clients[client].port,
343 .pad_index = pad_index,
344 };
345 for (std::size_t i = 0; i < 3; ++i) {
346 if (gyro[i] > 5.0f || gyro[i] < -5.0f) {
347 pad.motion = static_cast<PadMotion>(i);
348 pad.motion_value = gyro[i];
349 pad_queue.Push(pad);
350 }
351 if (acc[i] > 1.75f || acc[i] < -1.75f) {
352 pad.motion = static_cast<PadMotion>(i + 3);
353 pad.motion_value = acc[i];
354 pad_queue.Push(pad);
355 }
356 }
357}
358
359std::optional<std::size_t> Client::GetUnusedFingerID() const {
360 std::size_t first_free_id = 0;
361 while (first_free_id < MAX_TOUCH_FINGERS) {
362 if (!std::get<2>(touch_status[first_free_id])) {
363 return first_free_id;
364 } else {
365 first_free_id++;
366 }
367 }
368 return std::nullopt;
369}
370
371void Client::UpdateTouchInput(Response::TouchPad& touch_pad, std::size_t client, std::size_t id) {
372 // TODO: Use custom calibration per device
373 const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
374 const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100));
375 const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50));
376 const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800));
377 const u16 max_y = static_cast<u16>(touch_param.Get("max_y", 850));
378 const std::size_t touch_id = client * 2 + id;
379 if (touch_pad.is_active) {
380 if (finger_id[touch_id] == MAX_TOUCH_FINGERS) {
381 const auto first_free_id = GetUnusedFingerID();
382 if (!first_free_id) {
383 // Invalid finger id skip to next input
384 return;
385 }
386 finger_id[touch_id] = *first_free_id;
387 }
388 auto& [x, y, pressed] = touch_status[finger_id[touch_id]];
389 x = static_cast<float>(std::clamp(static_cast<u16>(touch_pad.x), min_x, max_x) - min_x) /
390 static_cast<float>(max_x - min_x);
391 y = static_cast<float>(std::clamp(static_cast<u16>(touch_pad.y), min_y, max_y) - min_y) /
392 static_cast<float>(max_y - min_y);
393 pressed = true;
394 return;
395 }
396
397 if (finger_id[touch_id] != MAX_TOUCH_FINGERS) {
398 touch_status[finger_id[touch_id]] = {};
399 finger_id[touch_id] = MAX_TOUCH_FINGERS;
400 }
401}
402
403void Client::BeginConfiguration() {
404 pad_queue.Clear();
405 configuring = true;
406}
407
408void Client::EndConfiguration() {
409 pad_queue.Clear();
410 configuring = false;
411}
412
413DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) {
414 const std::size_t client_number = GetClientNumber(host, port);
415 if (client_number == MAX_UDP_CLIENTS || pad >= PADS_PER_CLIENT) {
416 return pads[0].status;
417 }
418 return pads[(client_number * PADS_PER_CLIENT) + pad].status;
419}
420
421const DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) const {
422 const std::size_t client_number = GetClientNumber(host, port);
423 if (client_number == MAX_UDP_CLIENTS || pad >= PADS_PER_CLIENT) {
424 return pads[0].status;
425 }
426 return pads[(client_number * PADS_PER_CLIENT) + pad].status;
427}
428
429Input::TouchStatus& Client::GetTouchState() {
430 return touch_status;
431}
432
433const Input::TouchStatus& Client::GetTouchState() const {
434 return touch_status;
435}
436
437Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() {
438 return pad_queue;
439}
440
441const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
442 return pad_queue;
443}
444
445void TestCommunication(const std::string& host, u16 port, 283void TestCommunication(const std::string& host, u16 port,
446 const std::function<void()>& success_callback, 284 const std::function<void()>& success_callback,
447 const std::function<void()>& failure_callback) { 285 const std::function<void()>& failure_callback) {
diff --git a/src/input_common/udp/client.h b/src/input_common/drivers/udp_client.h
index 380f9bb76..58b2e921d 100644
--- a/src/input_common/udp/client.h
+++ b/src/input_common/drivers/udp_client.h
@@ -1,23 +1,14 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included
4 4
5#pragma once 5#pragma once
6 6
7#include <functional>
8#include <memory>
9#include <mutex>
10#include <optional> 7#include <optional>
11#include <string> 8
12#include <thread>
13#include <tuple>
14#include "common/common_types.h" 9#include "common/common_types.h"
15#include "common/param_package.h"
16#include "common/thread.h" 10#include "common/thread.h"
17#include "common/threadsafe_queue.h" 11#include "input_common/input_engine.h"
18#include "common/vector_math.h"
19#include "core/frontend/input.h"
20#include "input_common/motion_input.h"
21 12
22namespace InputCommon::CemuhookUDP { 13namespace InputCommon::CemuhookUDP {
23 14
@@ -30,16 +21,6 @@ struct TouchPad;
30struct Version; 21struct Version;
31} // namespace Response 22} // namespace Response
32 23
33enum class PadMotion {
34 GyroX,
35 GyroY,
36 GyroZ,
37 AccX,
38 AccY,
39 AccZ,
40 Undefined,
41};
42
43enum class PadTouch { 24enum class PadTouch {
44 Click, 25 Click,
45 Undefined, 26 Undefined,
@@ -49,14 +30,10 @@ struct UDPPadStatus {
49 std::string host{"127.0.0.1"}; 30 std::string host{"127.0.0.1"};
50 u16 port{26760}; 31 u16 port{26760};
51 std::size_t pad_index{}; 32 std::size_t pad_index{};
52 PadMotion motion{PadMotion::Undefined};
53 f32 motion_value{0.0f};
54}; 33};
55 34
56struct DeviceStatus { 35struct DeviceStatus {
57 std::mutex update_mutex; 36 std::mutex update_mutex;
58 Input::MotionStatus motion_status;
59 std::tuple<float, float, bool> touch_status;
60 37
61 // calibration data for scaling the device's touch area to 3ds 38 // calibration data for scaling the device's touch area to 3ds
62 struct CalibrationData { 39 struct CalibrationData {
@@ -68,32 +45,17 @@ struct DeviceStatus {
68 std::optional<CalibrationData> touch_calibration; 45 std::optional<CalibrationData> touch_calibration;
69}; 46};
70 47
71class Client { 48/**
49 * A button device factory representing a keyboard. It receives keyboard events and forward them
50 * to all button devices it created.
51 */
52class UDPClient final : public InputCommon::InputEngine {
72public: 53public:
73 // Initialize the UDP client capture and read sequence 54 explicit UDPClient(const std::string& input_engine_);
74 Client(); 55 ~UDPClient();
75
76 // Close and release the client
77 ~Client();
78
79 // Used for polling
80 void BeginConfiguration();
81 void EndConfiguration();
82
83 std::vector<Common::ParamPackage> GetInputDevices() const;
84 56
85 bool DeviceConnected(std::size_t pad) const;
86 void ReloadSockets(); 57 void ReloadSockets();
87 58
88 Common::SPSCQueue<UDPPadStatus>& GetPadQueue();
89 const Common::SPSCQueue<UDPPadStatus>& GetPadQueue() const;
90
91 DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad);
92 const DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad) const;
93
94 Input::TouchStatus& GetTouchState();
95 const Input::TouchStatus& GetTouchState() const;
96
97private: 59private:
98 struct PadData { 60 struct PadData {
99 std::size_t pad_index{}; 61 std::size_t pad_index{};
@@ -101,9 +63,6 @@ private:
101 DeviceStatus status; 63 DeviceStatus status;
102 u64 packet_sequence{}; 64 u64 packet_sequence{};
103 65
104 // Realtime values
105 // motion is initalized with PID values for drift correction on joycons
106 InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f};
107 std::chrono::time_point<std::chrono::steady_clock> last_update; 66 std::chrono::time_point<std::chrono::steady_clock> last_update;
108 }; 67 };
109 68
@@ -127,28 +86,13 @@ private:
127 void OnPortInfo(Response::PortInfo); 86 void OnPortInfo(Response::PortInfo);
128 void OnPadData(Response::PadData, std::size_t client); 87 void OnPadData(Response::PadData, std::size_t client);
129 void StartCommunication(std::size_t client, const std::string& host, u16 port); 88 void StartCommunication(std::size_t client, const std::string& host, u16 port);
130 void UpdateYuzuSettings(std::size_t client, std::size_t pad_index, 89 const PadIdentifier GetPadIdentifier(std::size_t pad_index) const;
131 const Common::Vec3<float>& acc, const Common::Vec3<float>& gyro);
132
133 // Returns an unused finger id, if there is no fingers available std::nullopt will be
134 // returned
135 std::optional<std::size_t> GetUnusedFingerID() const;
136
137 // Merges and updates all touch inputs into the touch_status array
138 void UpdateTouchInput(Response::TouchPad& touch_pad, std::size_t client, std::size_t id);
139
140 bool configuring = false;
141 90
142 // Allocate clients for 8 udp servers 91 // Allocate clients for 8 udp servers
143 static constexpr std::size_t MAX_UDP_CLIENTS = 8; 92 static constexpr std::size_t MAX_UDP_CLIENTS = 8;
144 static constexpr std::size_t PADS_PER_CLIENT = 4; 93 static constexpr std::size_t PADS_PER_CLIENT = 4;
145 // Each client can have up 2 touch inputs
146 static constexpr std::size_t MAX_TOUCH_FINGERS = MAX_UDP_CLIENTS * 2;
147 std::array<PadData, MAX_UDP_CLIENTS * PADS_PER_CLIENT> pads{}; 94 std::array<PadData, MAX_UDP_CLIENTS * PADS_PER_CLIENT> pads{};
148 std::array<ClientConnection, MAX_UDP_CLIENTS> clients{}; 95 std::array<ClientConnection, MAX_UDP_CLIENTS> clients{};
149 Common::SPSCQueue<UDPPadStatus> pad_queue{};
150 Input::TouchStatus touch_status{};
151 std::array<std::size_t, MAX_TOUCH_FINGERS> finger_id{};
152}; 96};
153 97
154/// An async job allowing configuration of the touchpad calibration. 98/// An async job allowing configuration of the touchpad calibration.
diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp
deleted file mode 100644
index 9829da6f0..000000000
--- a/src/input_common/udp/udp.cpp
+++ /dev/null
@@ -1,110 +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 <mutex>
6#include <utility>
7#include "common/assert.h"
8#include "common/threadsafe_queue.h"
9#include "input_common/udp/client.h"
10#include "input_common/udp/udp.h"
11
12namespace InputCommon {
13
14class UDPMotion final : public Input::MotionDevice {
15public:
16 explicit UDPMotion(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
17 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
18
19 Input::MotionStatus GetStatus() const override {
20 return client->GetPadState(ip, port, pad).motion_status;
21 }
22
23private:
24 const std::string ip;
25 const u16 port;
26 const u16 pad;
27 CemuhookUDP::Client* client;
28 mutable std::mutex mutex;
29};
30
31/// A motion device factory that creates motion devices from a UDP client
32UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_)
33 : client(std::move(client_)) {}
34
35/**
36 * Creates motion device
37 * @param params contains parameters for creating the device:
38 * - "port": the UDP port number
39 */
40std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) {
41 auto ip = params.Get("ip", "127.0.0.1");
42 const auto port = static_cast<u16>(params.Get("port", 26760));
43 const auto pad = static_cast<u16>(params.Get("pad_index", 0));
44
45 return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get());
46}
47
48void UDPMotionFactory::BeginConfiguration() {
49 polling = true;
50 client->BeginConfiguration();
51}
52
53void UDPMotionFactory::EndConfiguration() {
54 polling = false;
55 client->EndConfiguration();
56}
57
58Common::ParamPackage UDPMotionFactory::GetNextInput() {
59 Common::ParamPackage params;
60 CemuhookUDP::UDPPadStatus pad;
61 auto& queue = client->GetPadQueue();
62 while (queue.Pop(pad)) {
63 if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) {
64 continue;
65 }
66 params.Set("engine", "cemuhookudp");
67 params.Set("ip", pad.host);
68 params.Set("port", static_cast<u16>(pad.port));
69 params.Set("pad_index", static_cast<u16>(pad.pad_index));
70 params.Set("motion", static_cast<u16>(pad.motion));
71 return params;
72 }
73 return params;
74}
75
76class UDPTouch final : public Input::TouchDevice {
77public:
78 explicit UDPTouch(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
79 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
80
81 Input::TouchStatus GetStatus() const override {
82 return client->GetTouchState();
83 }
84
85private:
86 const std::string ip;
87 [[maybe_unused]] const u16 port;
88 [[maybe_unused]] const u16 pad;
89 CemuhookUDP::Client* client;
90 mutable std::mutex mutex;
91};
92
93/// A motion device factory that creates motion devices from a UDP client
94UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_)
95 : client(std::move(client_)) {}
96
97/**
98 * Creates motion device
99 * @param params contains parameters for creating the device:
100 * - "port": the UDP port number
101 */
102std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) {
103 auto ip = params.Get("ip", "127.0.0.1");
104 const auto port = static_cast<u16>(params.Get("port", 26760));
105 const auto pad = static_cast<u16>(params.Get("pad_index", 0));
106
107 return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get());
108}
109
110} // namespace InputCommon
diff --git a/src/input_common/udp/udp.h b/src/input_common/udp/udp.h
deleted file mode 100644
index ea3fd4175..000000000
--- a/src/input_common/udp/udp.h
+++ /dev/null
@@ -1,57 +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/udp/client.h"
10
11namespace InputCommon {
12
13/// A motion device factory that creates motion devices from udp clients
14class UDPMotionFactory final : public Input::Factory<Input::MotionDevice> {
15public:
16 explicit UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_);
17
18 std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
19
20 Common::ParamPackage GetNextInput();
21
22 /// For device input configuration/polling
23 void BeginConfiguration();
24 void EndConfiguration();
25
26 bool IsPolling() const {
27 return polling;
28 }
29
30private:
31 std::shared_ptr<CemuhookUDP::Client> client;
32 bool polling = false;
33};
34
35/// A touch device factory that creates touch devices from udp clients
36class UDPTouchFactory final : public Input::Factory<Input::TouchDevice> {
37public:
38 explicit UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_);
39
40 std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
41
42 Common::ParamPackage GetNextInput();
43
44 /// For device input configuration/polling
45 void BeginConfiguration();
46 void EndConfiguration();
47
48 bool IsPolling() const {
49 return polling;
50 }
51
52private:
53 std::shared_ptr<CemuhookUDP::Client> client;
54 bool polling = false;
55};
56
57} // namespace InputCommon