diff options
Diffstat (limited to 'src/input_common/udp/udp.cpp')
-rw-r--r-- | src/input_common/udp/udp.cpp | 159 |
1 files changed, 82 insertions, 77 deletions
diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp index 4b347e47e..9829da6f0 100644 --- a/src/input_common/udp/udp.cpp +++ b/src/input_common/udp/udp.cpp @@ -1,105 +1,110 @@ -// Copyright 2018 Citra Emulator Project +// Copyright 2020 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include <mutex> -#include <optional> -#include <tuple> - -#include "common/param_package.h" -#include "core/frontend/input.h" -#include "core/settings.h" +#include <utility> +#include "common/assert.h" +#include "common/threadsafe_queue.h" #include "input_common/udp/client.h" #include "input_common/udp/udp.h" -namespace InputCommon::CemuhookUDP { +namespace InputCommon { -class UDPTouchDevice final : public Input::TouchDevice { +class UDPMotion final : public Input::MotionDevice { public: - explicit UDPTouchDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} - std::tuple<float, float, bool> GetStatus() const override { - std::lock_guard guard(status->update_mutex); - return status->touch_status; + explicit UDPMotion(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_) + : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} + + Input::MotionStatus GetStatus() const override { + return client->GetPadState(ip, port, pad).motion_status; } private: - std::shared_ptr<DeviceStatus> status; + const std::string ip; + const u16 port; + const u16 pad; + CemuhookUDP::Client* client; + mutable std::mutex mutex; }; -class UDPMotionDevice final : public Input::MotionDevice { -public: - explicit UDPMotionDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} - std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const override { - std::lock_guard guard(status->update_mutex); - return status->motion_status; - } +/// A motion device factory that creates motion devices from a UDP client +UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_) + : client(std::move(client_)) {} + +/** + * Creates motion device + * @param params contains parameters for creating the device: + * - "port": the UDP port number + */ +std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) { + auto ip = params.Get("ip", "127.0.0.1"); + const auto port = static_cast<u16>(params.Get("port", 26760)); + const auto pad = static_cast<u16>(params.Get("pad_index", 0)); + + return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get()); +} -private: - std::shared_ptr<DeviceStatus> status; -}; +void UDPMotionFactory::BeginConfiguration() { + polling = true; + client->BeginConfiguration(); +} -class UDPTouchFactory final : public Input::Factory<Input::TouchDevice> { -public: - explicit UDPTouchFactory(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} - - std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override { - { - std::lock_guard guard(status->update_mutex); - status->touch_calibration = DeviceStatus::CalibrationData{}; - // These default values work well for DS4 but probably not other touch inputs - status->touch_calibration->min_x = params.Get("min_x", 100); - status->touch_calibration->min_y = params.Get("min_y", 50); - status->touch_calibration->max_x = params.Get("max_x", 1800); - status->touch_calibration->max_y = params.Get("max_y", 850); +void UDPMotionFactory::EndConfiguration() { + polling = false; + client->EndConfiguration(); +} + +Common::ParamPackage UDPMotionFactory::GetNextInput() { + Common::ParamPackage params; + CemuhookUDP::UDPPadStatus pad; + auto& queue = client->GetPadQueue(); + while (queue.Pop(pad)) { + if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) { + continue; } - return std::make_unique<UDPTouchDevice>(status); + params.Set("engine", "cemuhookudp"); + params.Set("ip", pad.host); + params.Set("port", static_cast<u16>(pad.port)); + params.Set("pad_index", static_cast<u16>(pad.pad_index)); + params.Set("motion", static_cast<u16>(pad.motion)); + return params; } + return params; +} -private: - std::shared_ptr<DeviceStatus> status; -}; - -class UDPMotionFactory final : public Input::Factory<Input::MotionDevice> { +class UDPTouch final : public Input::TouchDevice { public: - explicit UDPMotionFactory(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {} + explicit UDPTouch(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_) + : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} - std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override { - return std::make_unique<UDPMotionDevice>(status); + Input::TouchStatus GetStatus() const override { + return client->GetTouchState(); } private: - std::shared_ptr<DeviceStatus> status; + const std::string ip; + [[maybe_unused]] const u16 port; + [[maybe_unused]] const u16 pad; + CemuhookUDP::Client* client; + mutable std::mutex mutex; }; -State::State() { - auto status = std::make_shared<DeviceStatus>(); - client = - std::make_unique<Client>(status, Settings::values.udp_input_address, - Settings::values.udp_input_port, Settings::values.udp_pad_index); - - motion_factory = std::make_shared<UDPMotionFactory>(status); - touch_factory = std::make_shared<UDPTouchFactory>(status); - - Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", motion_factory); - Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", touch_factory); -} - -State::~State() { - Input::UnregisterFactory<Input::TouchDevice>("cemuhookudp"); - Input::UnregisterFactory<Input::MotionDevice>("cemuhookudp"); -} - -std::vector<Common::ParamPackage> State::GetInputDevices() const { - // TODO support binding udp devices - return {}; +/// A motion device factory that creates motion devices from a UDP client +UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_) + : client(std::move(client_)) {} + +/** + * Creates motion device + * @param params contains parameters for creating the device: + * - "port": the UDP port number + */ +std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) { + auto ip = params.Get("ip", "127.0.0.1"); + const auto port = static_cast<u16>(params.Get("port", 26760)); + const auto pad = static_cast<u16>(params.Get("pad_index", 0)); + + return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get()); } -void State::ReloadUDPClient() { - client->ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, - Settings::values.udp_pad_index); -} - -std::unique_ptr<State> Init() { - return std::make_unique<State>(); -} -} // namespace InputCommon::CemuhookUDP +} // namespace InputCommon |