From 4c6f2c2547e1d97f12ebe708fac693a6183bbc45 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 20 Sep 2021 16:57:55 -0500 Subject: input_common: Move touch and analog from button. Move udp protocol --- src/input_common/helpers/stick_from_buttons.cpp | 270 ++++++++++++++++++++++++ src/input_common/helpers/stick_from_buttons.h | 31 +++ src/input_common/helpers/touch_from_buttons.cpp | 70 ++++++ src/input_common/helpers/touch_from_buttons.h | 22 ++ src/input_common/helpers/udp_protocol.cpp | 78 +++++++ src/input_common/helpers/udp_protocol.h | 259 +++++++++++++++++++++++ 6 files changed, 730 insertions(+) create mode 100644 src/input_common/helpers/stick_from_buttons.cpp create mode 100644 src/input_common/helpers/stick_from_buttons.h create mode 100644 src/input_common/helpers/touch_from_buttons.cpp create mode 100644 src/input_common/helpers/touch_from_buttons.h create mode 100644 src/input_common/helpers/udp_protocol.cpp create mode 100644 src/input_common/helpers/udp_protocol.h (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp new file mode 100644 index 000000000..38f150746 --- /dev/null +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -0,0 +1,270 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include "common/math_util.h" +#include "common/settings.h" +#include "input_common/helpers/stick_from_buttons.h" + +namespace InputCommon { + +class Stick final : public Input::InputDevice { +public: + using Button = std::unique_ptr; + + Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_, + float modifier_scale_, float modifier_angle_) + : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)), + right(std::move(right_)), modifier(std::move(modifier_)), modifier_scale(modifier_scale_), + modifier_angle(modifier_angle_) { + Input::InputCallback button_up_callback{ + [this](Input::CallbackStatus callback_) { UpdateUpButtonStatus(callback_); }}; + Input::InputCallback button_down_callback{ + [this](Input::CallbackStatus callback_) { UpdateDownButtonStatus(callback_); }}; + Input::InputCallback button_left_callback{ + [this](Input::CallbackStatus callback_) { UpdateLeftButtonStatus(callback_); }}; + Input::InputCallback button_right_callback{ + [this](Input::CallbackStatus callback_) { UpdateRightButtonStatus(callback_); }}; + Input::InputCallback button_modifier_callback{ + [this](Input::CallbackStatus callback_) { UpdateModButtonStatus(callback_); }}; + up->SetCallback(button_up_callback); + down->SetCallback(button_down_callback); + left->SetCallback(button_left_callback); + right->SetCallback(button_right_callback); + modifier->SetCallback(button_modifier_callback); + } + + bool IsAngleGreater(float old_angle, float new_angle) const { + constexpr float TAU = Common::PI * 2.0f; + // Use wider angle to ease the transition. + constexpr float aperture = TAU * 0.15f; + const float top_limit = new_angle + aperture; + return (old_angle > new_angle && old_angle <= top_limit) || + (old_angle + TAU > new_angle && old_angle + TAU <= top_limit); + } + + bool IsAngleSmaller(float old_angle, float new_angle) const { + constexpr float TAU = Common::PI * 2.0f; + // Use wider angle to ease the transition. + constexpr float aperture = TAU * 0.15f; + const float bottom_limit = new_angle - aperture; + return (old_angle >= bottom_limit && old_angle < new_angle) || + (old_angle - TAU >= bottom_limit && old_angle - TAU < new_angle); + } + + float GetAngle(std::chrono::time_point now) const { + constexpr float TAU = Common::PI * 2.0f; + float new_angle = angle; + + auto time_difference = static_cast( + std::chrono::duration_cast(now - last_update).count()); + time_difference /= 1000.0f * 1000.0f; + if (time_difference > 0.5f) { + time_difference = 0.5f; + } + + if (IsAngleGreater(new_angle, goal_angle)) { + new_angle -= modifier_angle * time_difference; + if (new_angle < 0) { + new_angle += TAU; + } + if (!IsAngleGreater(new_angle, goal_angle)) { + return goal_angle; + } + } else if (IsAngleSmaller(new_angle, goal_angle)) { + new_angle += modifier_angle * time_difference; + if (new_angle >= TAU) { + new_angle -= TAU; + } + if (!IsAngleSmaller(new_angle, goal_angle)) { + return goal_angle; + } + } else { + return goal_angle; + } + return new_angle; + } + + void SetGoalAngle(bool r, bool l, bool u, bool d) { + // Move to the right + if (r && !u && !d) { + goal_angle = 0.0f; + } + + // Move to the upper right + if (r && u && !d) { + goal_angle = Common::PI * 0.25f; + } + + // Move up + if (u && !l && !r) { + goal_angle = Common::PI * 0.5f; + } + + // Move to the upper left + if (l && u && !d) { + goal_angle = Common::PI * 0.75f; + } + + // Move to the left + if (l && !u && !d) { + goal_angle = Common::PI; + } + + // Move to the bottom left + if (l && !u && d) { + goal_angle = Common::PI * 1.25f; + } + + // Move down + if (d && !l && !r) { + goal_angle = Common::PI * 1.5f; + } + + // Move to the bottom right + if (r && !u && d) { + goal_angle = Common::PI * 1.75f; + } + } + + void UpdateUpButtonStatus(Input::CallbackStatus button_callback) { + up_status = button_callback.button_status.value; + UpdateStatus(); + } + + void UpdateDownButtonStatus(Input::CallbackStatus button_callback) { + down_status = button_callback.button_status.value; + UpdateStatus(); + } + + void UpdateLeftButtonStatus(Input::CallbackStatus button_callback) { + left_status = button_callback.button_status.value; + UpdateStatus(); + } + + void UpdateRightButtonStatus(Input::CallbackStatus button_callback) { + right_status = button_callback.button_status.value; + UpdateStatus(); + } + + void UpdateModButtonStatus(Input::CallbackStatus button_callback) { + modifier_status = button_callback.button_status.value; + UpdateStatus(); + } + + void UpdateStatus() { + const float coef = modifier_status ? modifier_scale : 1.0f; + + bool r = right_status; + bool l = left_status; + bool u = up_status; + bool d = down_status; + + // Eliminate contradictory movements + if (r && l) { + r = false; + l = false; + } + if (u && d) { + u = false; + d = false; + } + + // Move if a key is pressed + if (r || l || u || d) { + amplitude = coef; + } else { + amplitude = 0; + } + + const auto now = std::chrono::steady_clock::now(); + const auto time_difference = static_cast( + std::chrono::duration_cast(now - last_update).count()); + + if (time_difference < 10) { + // Disable analog mode if inputs are too fast + SetGoalAngle(r, l, u, d); + angle = goal_angle; + } else { + angle = GetAngle(now); + SetGoalAngle(r, l, u, d); + } + + last_update = now; + Input::CallbackStatus status{ + .type = Input::InputType::Stick, + .stick_status = GetStatus(), + }; + TriggerOnChange(status); + } + + Input::StickStatus GetStatus() const { + Input::StickStatus status{}; + status.x.properties = properties; + status.y.properties = properties; + if (Settings::values.emulate_analog_keyboard) { + const auto now = std::chrono::steady_clock::now(); + float angle_ = GetAngle(now); + status.x.raw_value = std::cos(angle_) * amplitude; + status.y.raw_value = std::sin(angle_) * amplitude; + return status; + } + constexpr float SQRT_HALF = 0.707106781f; + int x = 0, y = 0; + if (right_status) { + ++x; + } + if (left_status) { + --x; + } + if (up_status) { + ++y; + } + if (down_status) { + --y; + } + const float coef = modifier_status ? modifier_scale : 1.0f; + status.x.raw_value = static_cast(x) * coef * (y == 0 ? 1.0f : SQRT_HALF); + status.y.raw_value = static_cast(y) * coef * (x == 0 ? 1.0f : SQRT_HALF); + return status; + } + +private: + Button up; + Button down; + Button left; + Button right; + Button modifier; + float modifier_scale; + float modifier_angle; + float angle{}; + float goal_angle{}; + float amplitude{}; + bool up_status; + bool down_status; + bool left_status; + bool right_status; + bool modifier_status; + const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; + std::chrono::time_point last_update; +}; + +std::unique_ptr StickFromButton::Create(const Common::ParamPackage& params) { + const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); + auto up = Input::CreateDeviceFromString(params.Get("up", null_engine)); + auto down = Input::CreateDeviceFromString(params.Get("down", null_engine)); + auto left = Input::CreateDeviceFromString(params.Get("left", null_engine)); + auto right = + Input::CreateDeviceFromString(params.Get("right", null_engine)); + auto modifier = + Input::CreateDeviceFromString(params.Get("modifier", null_engine)); + auto modifier_scale = params.Get("modifier_scale", 0.5f); + auto modifier_angle = params.Get("modifier_angle", 5.5f); + return std::make_unique(std::move(up), std::move(down), std::move(left), + std::move(right), std::move(modifier), modifier_scale, + modifier_angle); +} + +} // namespace InputCommon diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h new file mode 100644 index 000000000..1d6e24c98 --- /dev/null +++ b/src/input_common/helpers/stick_from_buttons.h @@ -0,0 +1,31 @@ + +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/input.h" + +namespace InputCommon { + +/** + * An analog device factory that takes direction button devices and combines them into a analog + * device. + */ +class StickFromButton final : public Input::Factory { +public: + /** + * Creates an analog device from direction button devices + * @param params contains parameters for creating the device: + * - "up": a serialized ParamPackage for creating a button device for up direction + * - "down": a serialized ParamPackage for creating a button device for down direction + * - "left": a serialized ParamPackage for creating a button device for left direction + * - "right": a serialized ParamPackage for creating a button device for right direction + * - "modifier": a serialized ParamPackage for creating a button device as the modifier + * - "modifier_scale": a float for the multiplier the modifier gives to the position + */ + std::unique_ptr Create(const Common::ParamPackage& params) override; +}; + +} // namespace InputCommon diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp new file mode 100644 index 000000000..2abfaf841 --- /dev/null +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -0,0 +1,70 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "common/settings.h" +#include "core/frontend/framebuffer_layout.h" +#include "input_common/helpers/touch_from_buttons.h" + +namespace InputCommon { + +class TouchFromButtonDevice final : public Input::InputDevice { +public: + using Button = std::unique_ptr; + TouchFromButtonDevice(Button button_, u32 touch_id_, float x_, float y_) + : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { + Input::InputCallback button_up_callback{ + [this](Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; + button->SetCallback(button_up_callback); + } + + Input::TouchStatus GetStatus(bool pressed) const { + const Input::ButtonStatus button_status{ + .value = pressed, + }; + Input::TouchStatus status{ + .pressed = button_status, + .x = {}, + .y = {}, + .id = touch_id, + }; + status.x.properties = properties; + status.y.properties = properties; + + if (!pressed) { + return status; + } + + status.x.raw_value = x; + status.y.raw_value = y; + return status; + } + + void UpdateButtonStatus(Input::CallbackStatus button_callback) { + const Input::CallbackStatus status{ + .type = Input::InputType::Touch, + .touch_status = GetStatus(button_callback.button_status.value), + }; + TriggerOnChange(status); + } + +private: + Button button; + const u32 touch_id; + const float x; + const float y; + const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; +}; + +std::unique_ptr TouchFromButton::Create(const Common::ParamPackage& params) { + const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); + auto button = + Input::CreateDeviceFromString(params.Get("button", null_engine)); + const auto touch_id = params.Get("touch_id", 0); + const float x = params.Get("x", 0.0f) / 1280.0f; + const float y = params.Get("y", 0.0f) / 720.0f; + return std::make_unique(std::move(button), touch_id, x, y); +} + +} // namespace InputCommon diff --git a/src/input_common/helpers/touch_from_buttons.h b/src/input_common/helpers/touch_from_buttons.h new file mode 100644 index 000000000..21b353728 --- /dev/null +++ b/src/input_common/helpers/touch_from_buttons.h @@ -0,0 +1,22 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/input.h" + +namespace InputCommon { + +/** + * A touch device factory that takes a list of button devices and combines them into a touch device. + */ +class TouchFromButton final : public Input::Factory { +public: + /** + * Creates a touch device from a list of button devices + */ + std::unique_ptr Create(const Common::ParamPackage& params) override; +}; + +} // namespace InputCommon diff --git a/src/input_common/helpers/udp_protocol.cpp b/src/input_common/helpers/udp_protocol.cpp new file mode 100644 index 000000000..cdeab7e11 --- /dev/null +++ b/src/input_common/helpers/udp_protocol.cpp @@ -0,0 +1,78 @@ +// Copyright 2018 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include "common/logging/log.h" +#include "input_common/helpers/udp_protocol.h" + +namespace InputCommon::CemuhookUDP { + +static constexpr std::size_t GetSizeOfResponseType(Type t) { + switch (t) { + case Type::Version: + return sizeof(Response::Version); + case Type::PortInfo: + return sizeof(Response::PortInfo); + case Type::PadData: + return sizeof(Response::PadData); + } + return 0; +} + +namespace Response { + +/** + * Returns Type if the packet is valid, else none + * + * Note: Modifies the buffer to zero out the crc (since thats the easiest way to check without + * copying the buffer) + */ +std::optional Validate(u8* data, std::size_t size) { + if (size < sizeof(Header)) { + return std::nullopt; + } + Header header{}; + std::memcpy(&header, data, sizeof(Header)); + if (header.magic != SERVER_MAGIC) { + LOG_ERROR(Input, "UDP Packet has an unexpected magic value"); + return std::nullopt; + } + if (header.protocol_version != PROTOCOL_VERSION) { + LOG_ERROR(Input, "UDP Packet protocol mismatch"); + return std::nullopt; + } + if (header.type < Type::Version || header.type > Type::PadData) { + LOG_ERROR(Input, "UDP Packet is an unknown type"); + return std::nullopt; + } + + // Packet size must equal sizeof(Header) + sizeof(Data) + // and also verify that the packet info mentions the correct size. Since the spec includes the + // type of the packet as part of the data, we need to include it in size calculations here + // ie: payload_length == sizeof(T) + sizeof(Type) + const std::size_t data_len = GetSizeOfResponseType(header.type); + if (header.payload_length != data_len + sizeof(Type) || size < data_len + sizeof(Header)) { + LOG_ERROR( + Input, + "UDP Packet payload length doesn't match. Received: {} PayloadLength: {} Expected: {}", + size, header.payload_length, data_len + sizeof(Type)); + return std::nullopt; + } + + const u32 crc32 = header.crc; + boost::crc_32_type result; + // zero out the crc in the buffer and then run the crc against it + std::memset(&data[offsetof(Header, crc)], 0, sizeof(u32_le)); + + result.process_bytes(data, data_len + sizeof(Header)); + if (crc32 != result.checksum()) { + LOG_ERROR(Input, "UDP Packet CRC check failed. Offset: {}", offsetof(Header, crc)); + return std::nullopt; + } + return header.type; +} +} // namespace Response + +} // namespace InputCommon::CemuhookUDP diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h new file mode 100644 index 000000000..1bdc9209e --- /dev/null +++ b/src/input_common/helpers/udp_protocol.h @@ -0,0 +1,259 @@ +// Copyright 2018 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include + +#include + +#include "common/bit_field.h" +#include "common/swap.h" + +namespace InputCommon::CemuhookUDP { + +constexpr std::size_t MAX_PACKET_SIZE = 100; +constexpr u16 PROTOCOL_VERSION = 1001; +constexpr u32 CLIENT_MAGIC = 0x43555344; // DSUC (but flipped for LE) +constexpr u32 SERVER_MAGIC = 0x53555344; // DSUS (but flipped for LE) + +enum class Type : u32 { + Version = 0x00100000, + PortInfo = 0x00100001, + PadData = 0x00100002, +}; + +struct Header { + u32_le magic{}; + u16_le protocol_version{}; + u16_le payload_length{}; + u32_le crc{}; + u32_le id{}; + ///> In the protocol, the type of the packet is not part of the header, but its convenient to + ///> include in the header so the callee doesn't have to duplicate the type twice when building + ///> 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"); + +using MacAddress = std::array; +constexpr MacAddress EMPTY_MAC_ADDRESS = {0, 0, 0, 0, 0, 0}; + +#pragma pack(push, 1) +template +struct Message { + Header header{}; + T data; +}; +#pragma pack(pop) + +template +constexpr Type GetMessageType(); + +namespace Request { + +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 + * request explicitly for the first controller port and leave it at that. In the future it would be + * 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"); + +/** + * Request the latest pad information from the server. If the server hasn't received this message + * from the client in a reasonable time frame, the server will stop sending updates. The default + * timeout seems to be 5 seconds. + */ +struct PadData { + enum class Flags : u8 { + AllPorts, + 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 + u8 port_id{}; + /// 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"); + +/** + * Creates a message with the proper header data that can be sent to the server. + * @param data Request body to send + * @param client_id ID of the udp client (usually not checked on the server) + */ +template +Message Create(const T data, const u32 client_id = 0) { + boost::crc_32_type crc; + Header header{ + CLIENT_MAGIC, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, client_id, GetMessageType(), + }; + Message message{header, data}; + crc.process_bytes(&message, sizeof(Message)); + message.header.crc = crc.checksum(); + return message; +} +} // namespace Request + +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"); + +struct PortInfo { + u8 id{}; + u8 state{}; + u8 model{}; + u8 connection_type{}; + MacAddress mac; + 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"); + +struct TouchPad { + u8 is_active{}; + u8 id{}; + u16_le x{}; + u16_le y{}; +}; +static_assert(sizeof(TouchPad) == 6, "UDP Response TouchPad struct has wrong size "); + +#pragma pack(push, 1) +struct PadData { + PortInfo info{}; + u32_le packet_counter{}; + + u16_le digital_button{}; + // The following union isn't trivially copyable but we don't use this input anyway. + // union DigitalButton { + // u16_le button; + // BitField<0, 1, u16> button_1; // Share + // BitField<1, 1, u16> button_2; // L3 + // BitField<2, 1, u16> button_3; // R3 + // BitField<3, 1, u16> button_4; // Options + // BitField<4, 1, u16> button_5; // Up + // BitField<5, 1, u16> button_6; // Right + // BitField<6, 1, u16> button_7; // Down + // BitField<7, 1, u16> button_8; // Left + // BitField<8, 1, u16> button_9; // L2 + // BitField<9, 1, u16> button_10; // R2 + // BitField<10, 1, u16> button_11; // L1 + // BitField<11, 1, u16> button_12; // R1 + // BitField<12, 1, u16> button_13; // Triangle + // BitField<13, 1, u16> button_14; // Circle + // BitField<14, 1, u16> button_15; // Cross + // BitField<15, 1, u16> button_16; // Square + // } digital_button; + + u8 home; + /// If the device supports a "click" on the touchpad, this will change to 1 when a click happens + u8 touch_hard_press{}; + u8 left_stick_x{}; + u8 left_stick_y{}; + u8 right_stick_x{}; + u8 right_stick_y{}; + + struct AnalogButton { + u8 button_8{}; + u8 button_7{}; + u8 button_6{}; + u8 button_5{}; + u8 button_12{}; + u8 button_11{}; + u8 button_10{}; + u8 button_9{}; + u8 button_16{}; + u8 button_15{}; + u8 button_14{}; + u8 button_13{}; + } analog_button; + + std::array touch; + + u64_le motion_timestamp; + + struct Accelerometer { + float x{}; + float y{}; + float z{}; + } accel; + + struct Gyroscope { + float pitch{}; + float yaw{}; + float roll{}; + } gyro; +}; +#pragma pack(pop) + +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"); + +static_assert(sizeof(Message) == MAX_PACKET_SIZE, + "UDP MAX_PACKET_SIZE is no longer larger than Message"); + +static_assert(sizeof(PadData::AnalogButton) == 12, + "UDP Response AnalogButton struct has wrong size "); +static_assert(sizeof(PadData::Accelerometer) == 12, + "UDP Response Accelerometer struct has wrong size "); +static_assert(sizeof(PadData::Gyroscope) == 12, "UDP Response Gyroscope struct has wrong size "); + +/** + * Create a Response Message from the data + * @param data array of bytes sent from the server + * @return boost::none if it failed to parse or Type if it succeeded. The client can then safely + * copy the data into the appropriate struct for that Type + */ +std::optional Validate(u8* data, std::size_t size); + +} // namespace Response + +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; +} +} // namespace InputCommon::CemuhookUDP -- cgit v1.2.3 From 06a5ef5874144a70e30e577a83ba68d1dad79e78 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 11 Oct 2021 00:43:11 -0500 Subject: core/hid: Add output devices --- src/input_common/helpers/stick_from_buttons.cpp | 3 ++- src/input_common/helpers/stick_from_buttons.h | 3 ++- src/input_common/helpers/touch_from_buttons.cpp | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 38f150746..89ba4aeb1 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -251,7 +251,8 @@ private: std::chrono::time_point last_update; }; -std::unique_ptr StickFromButton::Create(const Common::ParamPackage& params) { +std::unique_ptr StickFromButton::Create( + const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); auto up = Input::CreateDeviceFromString(params.Get("up", null_engine)); auto down = Input::CreateDeviceFromString(params.Get("down", null_engine)); diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h index 1d6e24c98..87165e022 100644 --- a/src/input_common/helpers/stick_from_buttons.h +++ b/src/input_common/helpers/stick_from_buttons.h @@ -25,7 +25,8 @@ public: * - "modifier": a serialized ParamPackage for creating a button device as the modifier * - "modifier_scale": a float for the multiplier the modifier gives to the position */ - std::unique_ptr Create(const Common::ParamPackage& params) override; + std::unique_ptr Create( + const Common::ParamPackage& params) override; }; } // namespace InputCommon diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 2abfaf841..6c9046ffb 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -57,7 +57,9 @@ private: const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; }; -std::unique_ptr TouchFromButton::Create(const Common::ParamPackage& params) { + +std::unique_ptr TouchFromButton::Create( + const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); auto button = Input::CreateDeviceFromString(params.Get("button", null_engine)); -- cgit v1.2.3 From e0da5c1bbcdf85676f968b63c8ae2587f0464193 Mon Sep 17 00:00:00 2001 From: german77 Date: Fri, 15 Oct 2021 19:07:47 -0500 Subject: kraken: Fix errors from rebase and format files --- src/input_common/helpers/stick_from_buttons.cpp | 3 +-- src/input_common/helpers/stick_from_buttons.h | 3 +-- src/input_common/helpers/touch_from_buttons.cpp | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 89ba4aeb1..38f150746 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -251,8 +251,7 @@ private: std::chrono::time_point last_update; }; -std::unique_ptr StickFromButton::Create( - const Common::ParamPackage& params) { +std::unique_ptr StickFromButton::Create(const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); auto up = Input::CreateDeviceFromString(params.Get("up", null_engine)); auto down = Input::CreateDeviceFromString(params.Get("down", null_engine)); diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h index 87165e022..1d6e24c98 100644 --- a/src/input_common/helpers/stick_from_buttons.h +++ b/src/input_common/helpers/stick_from_buttons.h @@ -25,8 +25,7 @@ public: * - "modifier": a serialized ParamPackage for creating a button device as the modifier * - "modifier_scale": a float for the multiplier the modifier gives to the position */ - std::unique_ptr Create( - const Common::ParamPackage& params) override; + std::unique_ptr Create(const Common::ParamPackage& params) override; }; } // namespace InputCommon diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 6c9046ffb..2abfaf841 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -57,9 +57,7 @@ private: const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; }; - -std::unique_ptr TouchFromButton::Create( - const Common::ParamPackage& params) { +std::unique_ptr TouchFromButton::Create(const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); auto button = Input::CreateDeviceFromString(params.Get("button", null_engine)); -- cgit v1.2.3 From b5e72de753ae4de5c5fae7087abb00dc4242451d Mon Sep 17 00:00:00 2001 From: german77 Date: Thu, 21 Oct 2021 13:56:52 -0500 Subject: kraken: Address comments from review review fixes --- src/input_common/helpers/stick_from_buttons.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h index 1d6e24c98..82dff5ca8 100644 --- a/src/input_common/helpers/stick_from_buttons.h +++ b/src/input_common/helpers/stick_from_buttons.h @@ -1,4 +1,3 @@ - // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -- cgit v1.2.3 From c6c32daf40ae1c720f0a2897c538bb1117371ea5 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 24 Oct 2021 20:28:54 -0500 Subject: input_common: Add manual update options to input devices --- src/input_common/helpers/stick_from_buttons.cpp | 16 ++++++++++++++++ src/input_common/helpers/touch_from_buttons.cpp | 1 + 2 files changed, 17 insertions(+) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 38f150746..9101f11ce 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -200,6 +200,22 @@ public: TriggerOnChange(status); } + void ForceUpdate() override{ + up->ForceUpdate(); + down->ForceUpdate(); + left->ForceUpdate(); + right->ForceUpdate(); + modifier->ForceUpdate(); + } + + void SoftUpdate() override { + Input::CallbackStatus status{ + .type = Input::InputType::Stick, + .stick_status = GetStatus(), + }; + TriggerOnChange(status); + } + Input::StickStatus GetStatus() const { Input::StickStatus status{}; status.x.properties = properties; diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 2abfaf841..bb2bad5b1 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -17,6 +17,7 @@ public: Input::InputCallback button_up_callback{ [this](Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; button->SetCallback(button_up_callback); + button->ForceUpdate(); } Input::TouchStatus GetStatus(bool pressed) const { -- cgit v1.2.3 From 064ddacf49aa7155e26add55983b81fdda997077 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 24 Oct 2021 23:23:54 -0500 Subject: core/hid: Rework battery mappings --- src/input_common/helpers/stick_from_buttons.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 9101f11ce..806a0e8bb 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -200,7 +200,7 @@ public: TriggerOnChange(status); } - void ForceUpdate() override{ + void ForceUpdate() override { up->ForceUpdate(); down->ForceUpdate(); left->ForceUpdate(); -- cgit v1.2.3 From 2b1b0c2a30e242b08ec120e09803ec54d5445703 Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 30 Oct 2021 22:23:10 -0500 Subject: kraken: Address comments from review start lion review --- src/input_common/helpers/stick_from_buttons.cpp | 70 ++++++++++++++----------- src/input_common/helpers/stick_from_buttons.h | 4 +- src/input_common/helpers/touch_from_buttons.cpp | 29 +++++----- src/input_common/helpers/touch_from_buttons.h | 4 +- 4 files changed, 57 insertions(+), 50 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 806a0e8bb..1d5948f79 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -10,25 +10,27 @@ namespace InputCommon { -class Stick final : public Input::InputDevice { +class Stick final : public Common::Input::InputDevice { public: - using Button = std::unique_ptr; + using Button = std::unique_ptr; Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_, float modifier_scale_, float modifier_angle_) : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)), right(std::move(right_)), modifier(std::move(modifier_)), modifier_scale(modifier_scale_), modifier_angle(modifier_angle_) { - Input::InputCallback button_up_callback{ - [this](Input::CallbackStatus callback_) { UpdateUpButtonStatus(callback_); }}; - Input::InputCallback button_down_callback{ - [this](Input::CallbackStatus callback_) { UpdateDownButtonStatus(callback_); }}; - Input::InputCallback button_left_callback{ - [this](Input::CallbackStatus callback_) { UpdateLeftButtonStatus(callback_); }}; - Input::InputCallback button_right_callback{ - [this](Input::CallbackStatus callback_) { UpdateRightButtonStatus(callback_); }}; - Input::InputCallback button_modifier_callback{ - [this](Input::CallbackStatus callback_) { UpdateModButtonStatus(callback_); }}; + Common::Input::InputCallback button_up_callback{ + [this](Common::Input::CallbackStatus callback_) { UpdateUpButtonStatus(callback_); }}; + Common::Input::InputCallback button_down_callback{ + [this](Common::Input::CallbackStatus callback_) { UpdateDownButtonStatus(callback_); }}; + Common::Input::InputCallback button_left_callback{ + [this](Common::Input::CallbackStatus callback_) { UpdateLeftButtonStatus(callback_); }}; + Common::Input::InputCallback button_right_callback{ + [this](Common::Input::CallbackStatus callback_) { + UpdateRightButtonStatus(callback_); + }}; + Common::Input::InputCallback button_modifier_callback{ + [this](Common::Input::CallbackStatus callback_) { UpdateModButtonStatus(callback_); }}; up->SetCallback(button_up_callback); down->SetCallback(button_down_callback); left->SetCallback(button_left_callback); @@ -129,27 +131,27 @@ public: } } - void UpdateUpButtonStatus(Input::CallbackStatus button_callback) { + void UpdateUpButtonStatus(Common::Input::CallbackStatus button_callback) { up_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateDownButtonStatus(Input::CallbackStatus button_callback) { + void UpdateDownButtonStatus(Common::Input::CallbackStatus button_callback) { down_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateLeftButtonStatus(Input::CallbackStatus button_callback) { + void UpdateLeftButtonStatus(Common::Input::CallbackStatus button_callback) { left_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateRightButtonStatus(Input::CallbackStatus button_callback) { + void UpdateRightButtonStatus(Common::Input::CallbackStatus button_callback) { right_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateModButtonStatus(Input::CallbackStatus button_callback) { + void UpdateModButtonStatus(Common::Input::CallbackStatus button_callback) { modifier_status = button_callback.button_status.value; UpdateStatus(); } @@ -193,8 +195,8 @@ public: } last_update = now; - Input::CallbackStatus status{ - .type = Input::InputType::Stick, + Common::Input::CallbackStatus status{ + .type = Common::Input::InputType::Stick, .stick_status = GetStatus(), }; TriggerOnChange(status); @@ -209,15 +211,15 @@ public: } void SoftUpdate() override { - Input::CallbackStatus status{ - .type = Input::InputType::Stick, + Common::Input::CallbackStatus status{ + .type = Common::Input::InputType::Stick, .stick_status = GetStatus(), }; TriggerOnChange(status); } - Input::StickStatus GetStatus() const { - Input::StickStatus status{}; + Common::Input::StickStatus GetStatus() const { + Common::Input::StickStatus status{}; status.x.properties = properties; status.y.properties = properties; if (Settings::values.emulate_analog_keyboard) { @@ -263,19 +265,23 @@ private: bool left_status; bool right_status; bool modifier_status; - const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; + const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; std::chrono::time_point last_update; }; -std::unique_ptr StickFromButton::Create(const Common::ParamPackage& params) { +std::unique_ptr StickFromButton::Create( + const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); - auto up = Input::CreateDeviceFromString(params.Get("up", null_engine)); - auto down = Input::CreateDeviceFromString(params.Get("down", null_engine)); - auto left = Input::CreateDeviceFromString(params.Get("left", null_engine)); - auto right = - Input::CreateDeviceFromString(params.Get("right", null_engine)); - auto modifier = - Input::CreateDeviceFromString(params.Get("modifier", null_engine)); + auto up = Common::Input::CreateDeviceFromString( + params.Get("up", null_engine)); + auto down = Common::Input::CreateDeviceFromString( + params.Get("down", null_engine)); + auto left = Common::Input::CreateDeviceFromString( + params.Get("left", null_engine)); + auto right = Common::Input::CreateDeviceFromString( + params.Get("right", null_engine)); + auto modifier = Common::Input::CreateDeviceFromString( + params.Get("modifier", null_engine)); auto modifier_scale = params.Get("modifier_scale", 0.5f); auto modifier_angle = params.Get("modifier_angle", 5.5f); return std::make_unique(std::move(up), std::move(down), std::move(left), diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h index 82dff5ca8..437ace4f7 100644 --- a/src/input_common/helpers/stick_from_buttons.h +++ b/src/input_common/helpers/stick_from_buttons.h @@ -12,7 +12,7 @@ namespace InputCommon { * An analog device factory that takes direction button devices and combines them into a analog * device. */ -class StickFromButton final : public Input::Factory { +class StickFromButton final : public Common::Input::Factory { public: /** * Creates an analog device from direction button devices @@ -24,7 +24,7 @@ public: * - "modifier": a serialized ParamPackage for creating a button device as the modifier * - "modifier_scale": a float for the multiplier the modifier gives to the position */ - std::unique_ptr Create(const Common::ParamPackage& params) override; + std::unique_ptr Create(const Common::ParamPackage& params) override; }; } // namespace InputCommon diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index bb2bad5b1..fee41cae3 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -9,22 +9,22 @@ namespace InputCommon { -class TouchFromButtonDevice final : public Input::InputDevice { +class TouchFromButtonDevice final : public Common::Input::InputDevice { public: - using Button = std::unique_ptr; + using Button = std::unique_ptr; TouchFromButtonDevice(Button button_, u32 touch_id_, float x_, float y_) : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { - Input::InputCallback button_up_callback{ - [this](Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; + Common::Input::InputCallback button_up_callback{ + [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; button->SetCallback(button_up_callback); button->ForceUpdate(); } - Input::TouchStatus GetStatus(bool pressed) const { - const Input::ButtonStatus button_status{ + Common::Input::TouchStatus GetStatus(bool pressed) const { + const Common::Input::ButtonStatus button_status{ .value = pressed, }; - Input::TouchStatus status{ + Common::Input::TouchStatus status{ .pressed = button_status, .x = {}, .y = {}, @@ -42,9 +42,9 @@ public: return status; } - void UpdateButtonStatus(Input::CallbackStatus button_callback) { - const Input::CallbackStatus status{ - .type = Input::InputType::Touch, + void UpdateButtonStatus(Common::Input::CallbackStatus button_callback) { + const Common::Input::CallbackStatus status{ + .type = Common::Input::InputType::Touch, .touch_status = GetStatus(button_callback.button_status.value), }; TriggerOnChange(status); @@ -55,13 +55,14 @@ private: const u32 touch_id; const float x; const float y; - const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; + const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; }; -std::unique_ptr TouchFromButton::Create(const Common::ParamPackage& params) { +std::unique_ptr TouchFromButton::Create( + const Common::ParamPackage& params) { const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); - auto button = - Input::CreateDeviceFromString(params.Get("button", null_engine)); + auto button = Common::Input::CreateDeviceFromString( + params.Get("button", null_engine)); const auto touch_id = params.Get("touch_id", 0); const float x = params.Get("x", 0.0f) / 1280.0f; const float y = params.Get("y", 0.0f) / 720.0f; diff --git a/src/input_common/helpers/touch_from_buttons.h b/src/input_common/helpers/touch_from_buttons.h index 21b353728..628f18215 100644 --- a/src/input_common/helpers/touch_from_buttons.h +++ b/src/input_common/helpers/touch_from_buttons.h @@ -11,12 +11,12 @@ namespace InputCommon { /** * A touch device factory that takes a list of button devices and combines them into a touch device. */ -class TouchFromButton final : public Input::Factory { +class TouchFromButton final : public Common::Input::Factory { public: /** * Creates a touch device from a list of button devices */ - std::unique_ptr Create(const Common::ParamPackage& params) override; + std::unique_ptr Create(const Common::ParamPackage& params) override; }; } // namespace InputCommon -- cgit v1.2.3 From 730f07830247cfcdc551c253d30c6717fc16316c Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 31 Oct 2021 10:41:44 -0500 Subject: settings: Fix Debug controller type options --- src/input_common/helpers/touch_from_buttons.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index fee41cae3..024343715 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -12,7 +12,7 @@ namespace InputCommon { class TouchFromButtonDevice final : public Common::Input::InputDevice { public: using Button = std::unique_ptr; - TouchFromButtonDevice(Button button_, u32 touch_id_, float x_, float y_) + TouchFromButtonDevice(Button button_, int touch_id_, float x_, float y_) : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { Common::Input::InputCallback button_up_callback{ [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; @@ -52,7 +52,7 @@ public: private: Button button; - const u32 touch_id; + const int touch_id; const float x; const float y; const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; -- cgit v1.2.3 From 136eb9c4c2b2425c2dd45a79cf444dee7170714d Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 1 Nov 2021 19:49:14 -0600 Subject: core/hid: Fully emulate motion from button --- src/input_common/helpers/stick_from_buttons.cpp | 12 ++++++++++++ src/input_common/helpers/touch_from_buttons.cpp | 11 ++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 1d5948f79..77fcd655e 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -36,6 +36,8 @@ public: left->SetCallback(button_left_callback); right->SetCallback(button_right_callback); modifier->SetCallback(button_modifier_callback); + last_x_axis_value = 0.0f; + last_y_axis_value = 0.0f; } bool IsAngleGreater(float old_angle, float new_angle) const { @@ -199,6 +201,8 @@ public: .type = Common::Input::InputType::Stick, .stick_status = GetStatus(), }; + last_x_axis_value = status.stick_status.x.raw_value; + last_y_axis_value = status.stick_status.y.raw_value; TriggerOnChange(status); } @@ -215,6 +219,12 @@ public: .type = Common::Input::InputType::Stick, .stick_status = GetStatus(), }; + if (last_x_axis_value == status.stick_status.x.raw_value && + last_y_axis_value == status.stick_status.y.raw_value) { + return; + } + last_x_axis_value = status.stick_status.x.raw_value; + last_y_axis_value = status.stick_status.y.raw_value; TriggerOnChange(status); } @@ -265,6 +275,8 @@ private: bool left_status; bool right_status; bool modifier_status; + float last_x_axis_value; + float last_y_axis_value; const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; std::chrono::time_point last_update; }; diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 024343715..35d60bc90 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -16,10 +16,15 @@ public: : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { Common::Input::InputCallback button_up_callback{ [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; + last_button_value = false; button->SetCallback(button_up_callback); button->ForceUpdate(); } + void ForceUpdate() override { + button->ForceUpdate(); + } + Common::Input::TouchStatus GetStatus(bool pressed) const { const Common::Input::ButtonStatus button_status{ .value = pressed, @@ -47,11 +52,15 @@ public: .type = Common::Input::InputType::Touch, .touch_status = GetStatus(button_callback.button_status.value), }; - TriggerOnChange(status); + if (last_button_value != button_callback.button_status.value) { + last_button_value = button_callback.button_status.value; + TriggerOnChange(status); + } } private: Button button; + bool last_button_value; const int touch_id; const float x; const float y; -- cgit v1.2.3 From 639402850ac65c694967ef6519becb65abe89b39 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Fri, 26 Nov 2021 15:45:37 -0600 Subject: input_common: Fully implement UDP controllers --- src/input_common/helpers/udp_protocol.h | 75 +++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 22 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h index 1bdc9209e..bcba12c58 100644 --- a/src/input_common/helpers/udp_protocol.h +++ b/src/input_common/helpers/udp_protocol.h @@ -56,6 +56,12 @@ constexpr Type GetMessageType(); namespace Request { +enum RegisterFlags : u8 { + AllPads, + PadID, + PadMACAdddress, +}; + struct Version {}; /** * Requests the server to send information about what controllers are plugged into the ports @@ -77,13 +83,8 @@ static_assert(std::is_trivially_copyable_v, * timeout seems to be 5 seconds. */ struct PadData { - enum class Flags : u8 { - AllPorts, - Id, - Mac, - }; /// Determines which method will be used as a look up for the controller - Flags flags{}; + RegisterFlags flags{}; /// Index of the port of the controller to retrieve data about u8 port_id{}; /// Mac address of the controller to retrieve data about @@ -113,6 +114,36 @@ Message Create(const T data, const u32 client_id = 0) { namespace Response { +enum class ConnectionType : u8 { + None, + Usb, + Bluetooth, +}; + +enum class State : u8 { + Disconnected, + Reserved, + Connected, +}; + +enum class Model : u8 { + None, + PartialGyro, + FullGyro, + Generic, +}; + +enum class Battery : u8 { + None = 0x00, + Dying = 0x01, + Low = 0x02, + Medium = 0x03, + High = 0x04, + Full = 0x05, + Charging = 0xEE, + Charged = 0xEF, +}; + struct Version { u16_le version{}; }; @@ -122,11 +153,11 @@ static_assert(std::is_trivially_copyable_v, struct PortInfo { u8 id{}; - u8 state{}; - u8 model{}; - u8 connection_type{}; + State state{}; + Model model{}; + ConnectionType connection_type{}; MacAddress mac; - u8 battery{}; + Battery battery{}; u8 is_pad_active{}; }; static_assert(sizeof(PortInfo) == 12, "UDP Response PortInfo struct has wrong size"); @@ -177,18 +208,18 @@ struct PadData { u8 right_stick_y{}; struct AnalogButton { - u8 button_8{}; - u8 button_7{}; - u8 button_6{}; - u8 button_5{}; - u8 button_12{}; - u8 button_11{}; - u8 button_10{}; - u8 button_9{}; - u8 button_16{}; - u8 button_15{}; - u8 button_14{}; - u8 button_13{}; + u8 button_dpad_left_analog{}; + u8 button_dpad_down_analog{}; + u8 button_dpad_right_analog{}; + u8 button_dpad_up_analog{}; + u8 button_square_analog{}; + u8 button_cross_analog{}; + u8 button_circle_analog{}; + u8 button_triangle_analog{}; + u8 button_r1_analog{}; + u8 button_l1_analog{}; + u8 trigger_r2{}; + u8 trigger_l2{}; } analog_button; std::array touch; -- cgit v1.2.3 From e05d2a70b24e550d67fcdd24aae7094ad41745f8 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 21:09:28 -0500 Subject: common/input: Avoid numerous large copies of CallbackStatus CallbackStatus instances aren't the cheapest things to copy around (relative to everything else), given that they're currently 520 bytes in size and are currently copied numerous times when callbacks are invoked. Instead, we can pass the status by const reference to avoid all the copying. --- src/input_common/helpers/stick_from_buttons.cpp | 75 +++++++++++++++---------- src/input_common/helpers/touch_from_buttons.cpp | 11 ++-- 2 files changed, 51 insertions(+), 35 deletions(-) (limited to 'src/input_common/helpers') diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 77fcd655e..e23394f5f 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp @@ -19,23 +19,36 @@ public: : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)), right(std::move(right_)), modifier(std::move(modifier_)), modifier_scale(modifier_scale_), modifier_angle(modifier_angle_) { - Common::Input::InputCallback button_up_callback{ - [this](Common::Input::CallbackStatus callback_) { UpdateUpButtonStatus(callback_); }}; - Common::Input::InputCallback button_down_callback{ - [this](Common::Input::CallbackStatus callback_) { UpdateDownButtonStatus(callback_); }}; - Common::Input::InputCallback button_left_callback{ - [this](Common::Input::CallbackStatus callback_) { UpdateLeftButtonStatus(callback_); }}; - Common::Input::InputCallback button_right_callback{ - [this](Common::Input::CallbackStatus callback_) { - UpdateRightButtonStatus(callback_); - }}; - Common::Input::InputCallback button_modifier_callback{ - [this](Common::Input::CallbackStatus callback_) { UpdateModButtonStatus(callback_); }}; - up->SetCallback(button_up_callback); - down->SetCallback(button_down_callback); - left->SetCallback(button_left_callback); - right->SetCallback(button_right_callback); - modifier->SetCallback(button_modifier_callback); + up->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateUpButtonStatus(callback_); + }, + }); + down->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateDownButtonStatus(callback_); + }, + }); + left->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateLeftButtonStatus(callback_); + }, + }); + right->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateRightButtonStatus(callback_); + }, + }); + modifier->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateModButtonStatus(callback_); + }, + }); last_x_axis_value = 0.0f; last_y_axis_value = 0.0f; } @@ -133,27 +146,27 @@ public: } } - void UpdateUpButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateUpButtonStatus(const Common::Input::CallbackStatus& button_callback) { up_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateDownButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateDownButtonStatus(const Common::Input::CallbackStatus& button_callback) { down_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateLeftButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateLeftButtonStatus(const Common::Input::CallbackStatus& button_callback) { left_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateRightButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateRightButtonStatus(const Common::Input::CallbackStatus& button_callback) { right_status = button_callback.button_status.value; UpdateStatus(); } - void UpdateModButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateModButtonStatus(const Common::Input::CallbackStatus& button_callback) { modifier_status = button_callback.button_status.value; UpdateStatus(); } @@ -265,18 +278,18 @@ private: Button left; Button right; Button modifier; - float modifier_scale; - float modifier_angle; + float modifier_scale{}; + float modifier_angle{}; float angle{}; float goal_angle{}; float amplitude{}; - bool up_status; - bool down_status; - bool left_status; - bool right_status; - bool modifier_status; - float last_x_axis_value; - float last_y_axis_value; + bool up_status{}; + bool down_status{}; + bool left_status{}; + bool right_status{}; + bool modifier_status{}; + float last_x_axis_value{}; + float last_y_axis_value{}; const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; std::chrono::time_point last_update; }; diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 35d60bc90..ece1e3b32 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp @@ -14,10 +14,13 @@ public: using Button = std::unique_ptr; TouchFromButtonDevice(Button button_, int touch_id_, float x_, float y_) : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { - Common::Input::InputCallback button_up_callback{ - [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; last_button_value = false; - button->SetCallback(button_up_callback); + button->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback_) { + UpdateButtonStatus(callback_); + }, + }); button->ForceUpdate(); } @@ -47,7 +50,7 @@ public: return status; } - void UpdateButtonStatus(Common::Input::CallbackStatus button_callback) { + void UpdateButtonStatus(const Common::Input::CallbackStatus& button_callback) { const Common::Input::CallbackStatus status{ .type = Common::Input::InputType::Touch, .touch_status = GetStatus(button_callback.button_status.value), -- cgit v1.2.3