From 0248614add99c1df1bc7c9ff97091f678ff75aca Mon Sep 17 00:00:00 2001 From: Ameer Date: Sun, 21 Jun 2020 12:36:28 -0400 Subject: GC Adapter Implementation --- src/input_common/udp/client.cpp | 140 ++++++++++++++++++++++------------------ src/input_common/udp/client.h | 2 + src/input_common/udp/protocol.h | 32 ++++++--- src/input_common/udp/udp.cpp | 18 ++++-- 4 files changed, 116 insertions(+), 76 deletions(-) (limited to 'src/input_common/udp') diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index da5227058..befa4c86d 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp @@ -59,7 +59,8 @@ public: void StartReceive() { socket.async_receive_from( boost::asio::buffer(receive_buffer), receive_endpoint, - [this](const boost::system::error_code& error, std::size_t bytes_transferred) { + [this](const boost::system::error_code& error, std::size_t bytes_transferred) + { HandleReceive(error, bytes_transferred); }); } @@ -211,21 +212,27 @@ void Client::StartCommunication(const std::string& host, u16 port, u8 pad_index, void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id, std::function success_callback, std::function failure_callback) { - std::thread([=] { - Common::Event success_event; - SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {}, - [&](Response::PadData data) { success_event.Set(); }}; - Socket socket{host, port, pad_index, client_id, std::move(callback)}; - std::thread worker_thread{SocketLoop, &socket}; - bool result = success_event.WaitFor(std::chrono::seconds(8)); - socket.Stop(); - worker_thread.join(); - if (result) { - success_callback(); - } else { - failure_callback(); - } - }) + std::thread([=] + { + Common::Event success_event; + SocketCallback callback{[](Response::Version version) + { + }, + [](Response::PortInfo info) + { + }, + [&](Response::PadData data) { success_event.Set(); }}; + Socket socket{host, port, pad_index, client_id, std::move(callback)}; + std::thread worker_thread{SocketLoop, &socket}; + bool result = success_event.WaitFor(std::chrono::seconds(8)); + socket.Stop(); + worker_thread.join(); + if (result) { + success_callback(); + } else { + failure_callback(); + } + }) .detach(); } @@ -234,53 +241,60 @@ CalibrationConfigurationJob::CalibrationConfigurationJob( std::function status_callback, std::function data_callback) { - std::thread([=] { - constexpr u16 CALIBRATION_THRESHOLD = 100; - - u16 min_x{UINT16_MAX}; - u16 min_y{UINT16_MAX}; - u16 max_x{}; - u16 max_y{}; - - Status current_status{Status::Initialized}; - SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {}, - [&](Response::PadData data) { - if (current_status == Status::Initialized) { - // Receiving data means the communication is ready now - current_status = Status::Ready; - status_callback(current_status); - } - if (!data.touch_1.is_active) { - return; - } - LOG_DEBUG(Input, "Current touch: {} {}", data.touch_1.x, - data.touch_1.y); - min_x = std::min(min_x, static_cast(data.touch_1.x)); - min_y = std::min(min_y, static_cast(data.touch_1.y)); - if (current_status == Status::Ready) { - // First touch - min data (min_x/min_y) - current_status = Status::Stage1Completed; - status_callback(current_status); - } - if (data.touch_1.x - min_x > CALIBRATION_THRESHOLD && - data.touch_1.y - min_y > CALIBRATION_THRESHOLD) { - // Set the current position as max value and finishes - // configuration - max_x = data.touch_1.x; - max_y = data.touch_1.y; - current_status = Status::Completed; - data_callback(min_x, min_y, max_x, max_y); - status_callback(current_status); - - complete_event.Set(); - } - }}; - Socket socket{host, port, pad_index, client_id, std::move(callback)}; - std::thread worker_thread{SocketLoop, &socket}; - complete_event.Wait(); - socket.Stop(); - worker_thread.join(); - }) + std::thread([=] + { + constexpr u16 CALIBRATION_THRESHOLD = 100; + + u16 min_x{UINT16_MAX}; + u16 min_y{UINT16_MAX}; + u16 max_x{}; + u16 max_y{}; + + Status current_status{Status::Initialized}; + SocketCallback callback{[](Response::Version version) + { + }, + [](Response::PortInfo info) + { + }, + [&](Response::PadData data) + { + if (current_status == Status::Initialized) { + // Receiving data means the communication is ready now + current_status = Status::Ready; + status_callback(current_status); + } + if (!data.touch_1.is_active) { + return; + } + LOG_DEBUG(Input, "Current touch: {} {}", data.touch_1.x, + data.touch_1.y); + min_x = std::min(min_x, static_cast(data.touch_1.x)); + min_y = std::min(min_y, static_cast(data.touch_1.y)); + if (current_status == Status::Ready) { + // First touch - min data (min_x/min_y) + current_status = Status::Stage1Completed; + status_callback(current_status); + } + if (data.touch_1.x - min_x > CALIBRATION_THRESHOLD && + data.touch_1.y - min_y > CALIBRATION_THRESHOLD) { + // Set the current position as max value and finishes + // configuration + max_x = data.touch_1.x; + max_y = data.touch_1.y; + current_status = Status::Completed; + data_callback(min_x, min_y, max_x, max_y); + status_callback(current_status); + + complete_event.Set(); + } + }}; + Socket socket{host, port, pad_index, client_id, std::move(callback)}; + std::thread worker_thread{SocketLoop, &socket}; + complete_event.Wait(); + socket.Stop(); + worker_thread.join(); + }) .detach(); } diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h index b8c654755..b58e319b6 100644 --- a/src/input_common/udp/client.h +++ b/src/input_common/udp/client.h @@ -40,6 +40,7 @@ struct DeviceStatus { u16 max_x{}; u16 max_y{}; }; + std::optional touch_calibration; }; @@ -72,6 +73,7 @@ public: Stage1Completed, Completed, }; + /** * Constructs and starts the job with the specified parameter. * diff --git a/src/input_common/udp/protocol.h b/src/input_common/udp/protocol.h index 3ba4d1fc8..2b31846db 100644 --- a/src/input_common/udp/protocol.h +++ b/src/input_common/udp/protocol.h @@ -35,6 +35,7 @@ struct Header { ///> the data Type type{}; }; + static_assert(sizeof(Header) == 20, "UDP Message Header struct has wrong size"); static_assert(std::is_trivially_copyable_v
, "UDP Message Header is not trivially copyable"); @@ -54,7 +55,9 @@ constexpr Type GetMessageType(); namespace Request { -struct Version {}; +struct Version { +}; + /** * Requests the server to send information about what controllers are plugged into the ports * In citra's case, we only have one controller, so for simplicity's sake, we can just send a @@ -62,12 +65,14 @@ struct Version {}; * nice to make this configurable */ constexpr u32 MAX_PORTS = 4; + struct PortInfo { u32_le pad_count{}; ///> Number of ports to request data for std::array port; }; + static_assert(std::is_trivially_copyable_v, - "UDP Request PortInfo is not trivially copyable"); + "UDP Request PortInfo is not trivially copyable"); /** * Request the latest pad information from the server. If the server hasn't received this message @@ -80,6 +85,7 @@ struct PadData { Id, Mac, }; + /// Determines which method will be used as a look up for the controller Flags flags{}; /// Index of the port of the controller to retrieve data about @@ -87,9 +93,10 @@ struct PadData { /// Mac address of the controller to retrieve data about MacAddress mac; }; + static_assert(sizeof(PadData) == 8, "UDP Request PadData struct has wrong size"); static_assert(std::is_trivially_copyable_v, - "UDP Request PadData is not trivially copyable"); + "UDP Request PadData is not trivially copyable"); /** * Creates a message with the proper header data that can be sent to the server. @@ -114,9 +121,10 @@ namespace Response { struct Version { u16_le version{}; }; + static_assert(sizeof(Version) == 2, "UDP Response Version struct has wrong size"); static_assert(std::is_trivially_copyable_v, - "UDP Response Version is not trivially copyable"); + "UDP Response Version is not trivially copyable"); struct PortInfo { u8 id{}; @@ -127,9 +135,10 @@ struct PortInfo { u8 battery{}; u8 is_pad_active{}; }; + static_assert(sizeof(PortInfo) == 12, "UDP Response PortInfo struct has wrong size"); static_assert(std::is_trivially_copyable_v, - "UDP Response PortInfo is not trivially copyable"); + "UDP Response PortInfo is not trivially copyable"); #pragma pack(push, 1) struct PadData { @@ -206,16 +215,16 @@ struct PadData { static_assert(sizeof(PadData) == 80, "UDP Response PadData struct has wrong size "); static_assert(std::is_trivially_copyable_v, - "UDP Response PadData is not trivially copyable"); + "UDP Response PadData is not trivially copyable"); static_assert(sizeof(Message) == MAX_PACKET_SIZE, - "UDP MAX_PACKET_SIZE is no longer larger than Message"); + "UDP MAX_PACKET_SIZE is no longer larger than Message"); static_assert(sizeof(PadData::AnalogButton) == 12, - "UDP Response AnalogButton struct has wrong size "); + "UDP Response AnalogButton struct has wrong size "); static_assert(sizeof(PadData::TouchPad) == 6, "UDP Response TouchPad struct has wrong size "); static_assert(sizeof(PadData::Accelerometer) == 12, - "UDP Response Accelerometer struct has wrong size "); + "UDP Response Accelerometer struct has wrong size "); static_assert(sizeof(PadData::Gyroscope) == 12, "UDP Response Gyroscope struct has wrong size "); /** @@ -232,22 +241,27 @@ template <> constexpr Type GetMessageType() { return Type::Version; } + template <> constexpr Type GetMessageType() { return Type::PortInfo; } + template <> constexpr Type GetMessageType() { return Type::PadData; } + template <> constexpr Type GetMessageType() { return Type::Version; } + template <> constexpr Type GetMessageType() { return Type::PortInfo; } + template <> constexpr Type GetMessageType() { return Type::PadData; diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp index 8c6ef1394..343c3985e 100644 --- a/src/input_common/udp/udp.cpp +++ b/src/input_common/udp/udp.cpp @@ -16,7 +16,10 @@ namespace InputCommon::CemuhookUDP { class UDPTouchDevice final : public Input::TouchDevice { public: - explicit UDPTouchDevice(std::shared_ptr status_) : status(std::move(status_)) {} + explicit UDPTouchDevice(std::shared_ptr status_) + : status(std::move(status_)) { + } + std::tuple GetStatus() const override { std::lock_guard guard(status->update_mutex); return status->touch_status; @@ -28,7 +31,10 @@ private: class UDPMotionDevice final : public Input::MotionDevice { public: - explicit UDPMotionDevice(std::shared_ptr status_) : status(std::move(status_)) {} + explicit UDPMotionDevice(std::shared_ptr status_) + : status(std::move(status_)) { + } + std::tuple, Common::Vec3> GetStatus() const override { std::lock_guard guard(status->update_mutex); return status->motion_status; @@ -40,7 +46,9 @@ private: class UDPTouchFactory final : public Input::Factory { public: - explicit UDPTouchFactory(std::shared_ptr status_) : status(std::move(status_)) {} + explicit UDPTouchFactory(std::shared_ptr status_) + : status(std::move(status_)) { + } std::unique_ptr Create(const Common::ParamPackage& params) override { { @@ -61,7 +69,9 @@ private: class UDPMotionFactory final : public Input::Factory { public: - explicit UDPMotionFactory(std::shared_ptr status_) : status(std::move(status_)) {} + explicit UDPMotionFactory(std::shared_ptr status_) + : status(std::move(status_)) { + } std::unique_ptr Create(const Common::ParamPackage& params) override { return std::make_unique(status); -- cgit v1.2.3