summaryrefslogtreecommitdiff
path: root/src/input_common/udp/udp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/udp/udp.cpp')
-rw-r--r--src/input_common/udp/udp.cpp181
1 files changed, 110 insertions, 71 deletions
diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp
index 03bae5752..eba077a36 100644
--- a/src/input_common/udp/udp.cpp
+++ b/src/input_common/udp/udp.cpp
@@ -1,105 +1,144 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2020 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#include <atomic>
6#include <list>
5#include <mutex> 7#include <mutex>
6#include <optional> 8#include <utility>
7#include <tuple> 9#include "common/assert.h"
8 10#include "common/threadsafe_queue.h"
9#include "common/param_package.h"
10#include "core/frontend/input.h"
11#include "core/settings.h"
12#include "input_common/udp/client.h" 11#include "input_common/udp/client.h"
13#include "input_common/udp/udp.h" 12#include "input_common/udp/udp.h"
14 13
15namespace InputCommon::CemuhookUDP { 14namespace InputCommon {
16 15
17class UDPTouchDevice final : public Input::TouchDevice { 16class UDPMotion final : public Input::MotionDevice {
18public: 17public:
19 explicit UDPTouchDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} 18 UDPMotion(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_)
20 std::tuple<float, float, bool> GetStatus() const override { 19 : ip(ip_), port(port_), pad(pad_), client(client_) {}
21 std::lock_guard guard(status->update_mutex);
22 return status->touch_status;
23 }
24
25private:
26 std::shared_ptr<DeviceStatus> status;
27};
28 20
29class UDPMotionDevice final : public Input::MotionDevice {
30public:
31 explicit UDPMotionDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {}
32 Input::MotionStatus GetStatus() const override { 21 Input::MotionStatus GetStatus() const override {
33 std::lock_guard guard(status->update_mutex); 22 return client->GetPadState(pad).motion_status;
34 return status->motion_status;
35 } 23 }
36 24
37private: 25private:
38 std::shared_ptr<DeviceStatus> status; 26 const std::string ip;
27 const int port;
28 const int pad;
29 CemuhookUDP::Client* client;
30 mutable std::mutex mutex;
39}; 31};
40 32
41class UDPTouchFactory final : public Input::Factory<Input::TouchDevice> { 33/// A motion device factory that creates motion devices from JC Adapter
42public: 34UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_)
43 explicit UDPTouchFactory(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} 35 : client(std::move(client_)) {}
44 36
45 std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override { 37/**
46 { 38 * Creates motion device
47 std::lock_guard guard(status->update_mutex); 39 * @param params contains parameters for creating the device:
48 status->touch_calibration = DeviceStatus::CalibrationData{}; 40 * - "port": the nth jcpad on the adapter
49 // These default values work well for DS4 but probably not other touch inputs 41 */
50 status->touch_calibration->min_x = params.Get("min_x", 100); 42std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) {
51 status->touch_calibration->min_y = params.Get("min_y", 50); 43 const std::string ip = params.Get("ip", "127.0.0.1");
52 status->touch_calibration->max_x = params.Get("max_x", 1800); 44 const int port = params.Get("port", 26760);
53 status->touch_calibration->max_y = params.Get("max_y", 850); 45 const int pad = params.Get("pad_index", 0);
46
47 return std::make_unique<UDPMotion>(ip, port, pad, client.get());
48}
49
50void UDPMotionFactory::BeginConfiguration() {
51 polling = true;
52 client->BeginConfiguration();
53}
54
55void UDPMotionFactory::EndConfiguration() {
56 polling = false;
57 client->EndConfiguration();
58}
59
60Common::ParamPackage UDPMotionFactory::GetNextInput() {
61 Common::ParamPackage params;
62 CemuhookUDP::UDPPadStatus pad;
63 auto& queue = client->GetPadQueue();
64 for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) {
65 while (queue[pad_number].Pop(pad)) {
66 if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) {
67 continue;
68 }
69 params.Set("engine", "cemuhookudp");
70 params.Set("ip", "127.0.0.1");
71 params.Set("port", 26760);
72 params.Set("pad_index", static_cast<int>(pad_number));
73 params.Set("motion", static_cast<u16>(pad.motion));
74 return params;
54 } 75 }
55 return std::make_unique<UDPTouchDevice>(status);
56 } 76 }
77 return params;
78}
57 79
58private: 80class UDPTouch final : public Input::TouchDevice {
59 std::shared_ptr<DeviceStatus> status;
60};
61
62class UDPMotionFactory final : public Input::Factory<Input::MotionDevice> {
63public: 81public:
64 explicit UDPMotionFactory(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} 82 UDPTouch(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_)
83 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
65 84
66 std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override { 85 std::tuple<float, float, bool> GetStatus() const override {
67 return std::make_unique<UDPMotionDevice>(status); 86 return client->GetPadState(pad).touch_status;
68 } 87 }
69 88
70private: 89private:
71 std::shared_ptr<DeviceStatus> status; 90 const std::string ip;
91 const int port;
92 const int pad;
93 CemuhookUDP::Client* client;
94 mutable std::mutex mutex;
72}; 95};
73 96
74State::State() { 97/// A motion device factory that creates motion devices from JC Adapter
75 auto status = std::make_shared<DeviceStatus>(); 98UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_)
76 client = 99 : client(std::move(client_)) {}
77 std::make_unique<Client>(status, Settings::values.udp_input_address, 100
78 Settings::values.udp_input_port, Settings::values.udp_pad_index); 101/**
79 102 * Creates motion device
80 motion_factory = std::make_shared<UDPMotionFactory>(status); 103 * @param params contains parameters for creating the device:
81 touch_factory = std::make_shared<UDPTouchFactory>(status); 104 * - "port": the nth jcpad on the adapter
82 105 */
83 Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", motion_factory); 106std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) {
84 Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", touch_factory); 107 const std::string ip = params.Get("ip", "127.0.0.1");
108 const int port = params.Get("port", 26760);
109 const int pad = params.Get("pad_index", 0);
110
111 return std::make_unique<UDPTouch>(ip, port, pad, client.get());
85} 112}
86 113
87State::~State() { 114void UDPTouchFactory::BeginConfiguration() {
88 Input::UnregisterFactory<Input::TouchDevice>("cemuhookudp"); 115 polling = true;
89 Input::UnregisterFactory<Input::MotionDevice>("cemuhookudp"); 116 client->BeginConfiguration();
90} 117}
91 118
92std::vector<Common::ParamPackage> State::GetInputDevices() const { 119void UDPTouchFactory::EndConfiguration() {
93 // TODO support binding udp devices 120 polling = false;
94 return {}; 121 client->EndConfiguration();
95} 122}
96 123
97void State::ReloadUDPClient() { 124Common::ParamPackage UDPTouchFactory::GetNextInput() {
98 client->ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, 125 Common::ParamPackage params;
99 Settings::values.udp_pad_index); 126 CemuhookUDP::UDPPadStatus pad;
127 auto& queue = client->GetPadQueue();
128 for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) {
129 while (queue[pad_number].Pop(pad)) {
130 if (pad.touch == CemuhookUDP::PadTouch::Undefined) {
131 continue;
132 }
133 params.Set("engine", "cemuhookudp");
134 params.Set("ip", "127.0.0.1");
135 params.Set("port", 26760);
136 params.Set("pad_index", static_cast<int>(pad_number));
137 params.Set("touch", static_cast<u16>(pad.touch));
138 return params;
139 }
140 }
141 return params;
100} 142}
101 143
102std::unique_ptr<State> Init() { 144} // namespace InputCommon
103 return std::make_unique<State>();
104}
105} // namespace InputCommon::CemuhookUDP