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