input_common/CMakeLists: Make some warnings errors
Makes the input_common code warnings consistent with the rest of the codebase.
This commit is contained in:
		
							parent
							
								
									ca416a0fb8
								
							
						
					
					
						commit
						046c0c91a3
					
				| @ -20,8 +20,8 @@ struct Rectangle { | ||||
| 
 | ||||
|     constexpr Rectangle() = default; | ||||
| 
 | ||||
|     constexpr Rectangle(T left, T top, T right, T bottom) | ||||
|         : left(left), top(top), right(right), bottom(bottom) {} | ||||
|     constexpr Rectangle(T left_, T top_, T right_, T bottom_) | ||||
|         : left(left_), top(top_), right(right_), bottom(bottom_) {} | ||||
| 
 | ||||
|     [[nodiscard]] T GetWidth() const { | ||||
|         if constexpr (std::is_floating_point_v<T>) { | ||||
|  | ||||
| @ -87,7 +87,13 @@ public: | ||||
| 
 | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const { | ||||
|         return {x * f, y * f}; | ||||
|         using TV = decltype(T{} * V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -98,7 +104,13 @@ public: | ||||
| 
 | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const { | ||||
|         return {x / f, y / f}; | ||||
|         using TV = decltype(T{} / V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -168,7 +180,10 @@ public: | ||||
| 
 | ||||
| template <typename T, typename V> | ||||
| [[nodiscard]] constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) { | ||||
|     return Vec2<T>(f * vec.x, f * vec.y); | ||||
|     using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|     return Vec2<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)), | ||||
|                    static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y))); | ||||
| } | ||||
| 
 | ||||
| using Vec2f = Vec2<float>; | ||||
| @ -237,7 +252,14 @@ public: | ||||
| 
 | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const { | ||||
|         return {x * f, y * f, z * f}; | ||||
|         using TV = decltype(T{} * V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -247,7 +269,14 @@ public: | ||||
|     } | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const { | ||||
|         return {x / f, y / f, z / f}; | ||||
|         using TV = decltype(T{} / V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -367,7 +396,11 @@ public: | ||||
| 
 | ||||
| template <typename T, typename V> | ||||
| [[nodiscard]] constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) { | ||||
|     return Vec3<T>(f * vec.x, f * vec.y, f * vec.z); | ||||
|     using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|     return Vec3<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)), | ||||
|                    static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y)), | ||||
|                    static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.z))); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| @ -446,7 +479,15 @@ public: | ||||
| 
 | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const { | ||||
|         return {x * f, y * f, z * f, w * f}; | ||||
|         using TV = decltype(T{} * V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(w) * static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -457,7 +498,15 @@ public: | ||||
| 
 | ||||
|     template <typename V> | ||||
|     [[nodiscard]] constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const { | ||||
|         return {x / f, y / f, z / f, w / f}; | ||||
|         using TV = decltype(T{} / V{}); | ||||
|         using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|         return { | ||||
|             static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)), | ||||
|             static_cast<TV>(static_cast<C>(w) / static_cast<C>(f)), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     template <typename V> | ||||
| @ -582,7 +631,15 @@ public: | ||||
| 
 | ||||
| template <typename T, typename V> | ||||
| [[nodiscard]] constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { | ||||
|     return {f * vec.x, f * vec.y, f * vec.z, f * vec.w}; | ||||
|     using TV = decltype(V{} * T{}); | ||||
|     using C = std::common_type_t<T, V>; | ||||
| 
 | ||||
|     return { | ||||
|         static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.x)), | ||||
|         static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.y)), | ||||
|         static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.z)), | ||||
|         static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.w)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| using Vec4f = Vec4<float>; | ||||
|  | ||||
| @ -29,6 +29,35 @@ add_library(input_common STATIC | ||||
|     udp/udp.h | ||||
| ) | ||||
| 
 | ||||
| if (MSVC) | ||||
|     target_compile_options(input_common PRIVATE | ||||
|         # 'expression' : signed/unsigned mismatch | ||||
|         /we4018 | ||||
|         # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point) | ||||
|         /we4244 | ||||
|         # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch | ||||
|         /we4245 | ||||
|         # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data | ||||
|         /we4254 | ||||
|         # 'var' : conversion from 'size_t' to 'type', possible loss of data | ||||
|         /we4267 | ||||
|         # 'context' : truncation from 'type1' to 'type2' | ||||
|         /we4305 | ||||
|     ) | ||||
| else() | ||||
|     target_compile_options(input_common PRIVATE | ||||
|         -Werror=conversion | ||||
|         -Werror=ignored-qualifiers | ||||
|         -Werror=implicit-fallthrough | ||||
|         -Werror=reorder | ||||
|         -Werror=shadow | ||||
|         -Werror=sign-compare | ||||
|         -Werror=unused-but-set-parameter | ||||
|         -Werror=unused-but-set-variable | ||||
|         -Werror=unused-variable | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| if(SDL2_FOUND) | ||||
|     target_sources(input_common PRIVATE | ||||
|         sdl/sdl_impl.cpp | ||||
|  | ||||
| @ -20,18 +20,22 @@ public: | ||||
|         constexpr float SQRT_HALF = 0.707106781f; | ||||
|         int x = 0, y = 0; | ||||
| 
 | ||||
|         if (right->GetStatus()) | ||||
|         if (right->GetStatus()) { | ||||
|             ++x; | ||||
|         if (left->GetStatus()) | ||||
|         } | ||||
|         if (left->GetStatus()) { | ||||
|             --x; | ||||
|         if (up->GetStatus()) | ||||
|         } | ||||
|         if (up->GetStatus()) { | ||||
|             ++y; | ||||
|         if (down->GetStatus()) | ||||
|         } | ||||
|         if (down->GetStatus()) { | ||||
|             --y; | ||||
|         } | ||||
| 
 | ||||
|         float coef = modifier->GetStatus() ? modifier_scale : 1.0f; | ||||
|         return std::make_tuple(x * coef * (y == 0 ? 1.0f : SQRT_HALF), | ||||
|                                y * coef * (x == 0 ? 1.0f : SQRT_HALF)); | ||||
|         const float coef = modifier->GetStatus() ? modifier_scale : 1.0f; | ||||
|         return std::make_tuple(static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF), | ||||
|                                static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF)); | ||||
|     } | ||||
| 
 | ||||
|     bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override { | ||||
|  | ||||
| @ -21,7 +21,7 @@ | ||||
| 
 | ||||
| namespace GCAdapter { | ||||
| 
 | ||||
| /// Used to loop through and assign button in poller
 | ||||
| // Used to loop through and assign button in poller
 | ||||
| constexpr std::array<PadButton, 12> PadButtonArray{ | ||||
|     PadButton::PAD_BUTTON_LEFT, PadButton::PAD_BUTTON_RIGHT, PadButton::PAD_BUTTON_DOWN, | ||||
|     PadButton::PAD_BUTTON_UP,   PadButton::PAD_TRIGGER_Z,    PadButton::PAD_TRIGGER_R, | ||||
| @ -29,6 +29,18 @@ constexpr std::array<PadButton, 12> PadButtonArray{ | ||||
|     PadButton::PAD_BUTTON_X,    PadButton::PAD_BUTTON_Y,     PadButton::PAD_BUTTON_START, | ||||
| }; | ||||
| 
 | ||||
| static void PadToState(const GCPadStatus& pad, GCState& out_state) { | ||||
|     for (const auto& button : PadButtonArray) { | ||||
|         const auto button_key = static_cast<u16>(button); | ||||
|         const auto button_value = (pad.button & button_key) != 0; | ||||
|         out_state.buttons.insert_or_assign(static_cast<s32>(button_key), button_value); | ||||
|     } | ||||
| 
 | ||||
|     for (std::size_t i = 0; i < pad.axis_values.size(); ++i) { | ||||
|         out_state.axes.insert_or_assign(static_cast<u32>(i), pad.axis_values[i]); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Adapter::Adapter() { | ||||
|     if (usb_adapter_handle != nullptr) { | ||||
|         return; | ||||
| @ -78,17 +90,17 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad | ||||
| 
 | ||||
|         for (std::size_t i = 0; i < b1_buttons.size(); ++i) { | ||||
|             if ((b1 & (1U << i)) != 0) { | ||||
|                 pad.button |= static_cast<u16>(b1_buttons[i]); | ||||
|                 pad.button = static_cast<u16>(pad.button | static_cast<u16>(b1_buttons[i])); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (std::size_t j = 0; j < b2_buttons.size(); ++j) { | ||||
|             if ((b2 & (1U << j)) != 0) { | ||||
|                 pad.button |= static_cast<u16>(b2_buttons[j]); | ||||
|                 pad.button = static_cast<u16>(pad.button | static_cast<u16>(b2_buttons[j])); | ||||
|             } | ||||
|         } | ||||
|         for (PadAxes axis : axes) { | ||||
|             const std::size_t index = static_cast<std::size_t>(axis); | ||||
|             const auto index = static_cast<std::size_t>(axis); | ||||
|             pad.axis_values[index] = adapter_payload[offset + 3 + index]; | ||||
|         } | ||||
| 
 | ||||
| @ -100,17 +112,6 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad | ||||
|     return pad; | ||||
| } | ||||
| 
 | ||||
| void Adapter::PadToState(const GCPadStatus& pad, GCState& state) { | ||||
|     for (const auto& button : PadButtonArray) { | ||||
|         const u16 button_value = static_cast<u16>(button); | ||||
|         state.buttons.insert_or_assign(button_value, pad.button & button_value); | ||||
|     } | ||||
| 
 | ||||
|     for (size_t i = 0; i < pad.axis_values.size(); ++i) { | ||||
|         state.axes.insert_or_assign(static_cast<u8>(i), pad.axis_values[i]); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Adapter::Read() { | ||||
|     LOG_DEBUG(Input, "GC Adapter Read() thread started"); | ||||
| 
 | ||||
| @ -250,7 +251,7 @@ void Adapter::GetGCEndpoint(libusb_device* device) { | ||||
|             const libusb_interface_descriptor* interface = &interfaceContainer->altsetting[i]; | ||||
|             for (u8 e = 0; e < interface->bNumEndpoints; e++) { | ||||
|                 const libusb_endpoint_descriptor* endpoint = &interface->endpoint[e]; | ||||
|                 if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) { | ||||
|                 if ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) != 0) { | ||||
|                     input_endpoint = endpoint->bEndpointAddress; | ||||
|                 } else { | ||||
|                     output_endpoint = endpoint->bEndpointAddress; | ||||
| @ -419,7 +420,7 @@ const std::array<GCState, 4>& Adapter::GetPadState() const { | ||||
|     return state; | ||||
| } | ||||
| 
 | ||||
| int Adapter::GetOriginValue(int port, int axis) const { | ||||
| int Adapter::GetOriginValue(u32 port, u32 axis) const { | ||||
|     return origin_status[port].axis_values[axis]; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -60,7 +60,7 @@ struct GCPadStatus { | ||||
| 
 | ||||
| struct GCState { | ||||
|     std::unordered_map<int, bool> buttons; | ||||
|     std::unordered_map<int, u16> axes; | ||||
|     std::unordered_map<u32, u16> axes; | ||||
| }; | ||||
| 
 | ||||
| enum class ControllerTypes { None, Wired, Wireless }; | ||||
| @ -89,13 +89,11 @@ public: | ||||
|     std::array<GCState, 4>& GetPadState(); | ||||
|     const std::array<GCState, 4>& GetPadState() const; | ||||
| 
 | ||||
|     int GetOriginValue(int port, int axis) const; | ||||
|     int GetOriginValue(u32 port, u32 axis) const; | ||||
| 
 | ||||
| private: | ||||
|     GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload); | ||||
| 
 | ||||
|     void PadToState(const GCPadStatus& pad, GCState& state); | ||||
| 
 | ||||
|     void Read(); | ||||
| 
 | ||||
|     /// Resets status of device connected to port
 | ||||
|  | ||||
| @ -15,7 +15,7 @@ namespace InputCommon { | ||||
| 
 | ||||
| class GCButton final : public Input::ButtonDevice { | ||||
| public: | ||||
|     explicit GCButton(int port_, int button_, const GCAdapter::Adapter* adapter) | ||||
|     explicit GCButton(u32 port_, int button_, const GCAdapter::Adapter* adapter) | ||||
|         : port(port_), button(button_), gcadapter(adapter) {} | ||||
| 
 | ||||
|     ~GCButton() override; | ||||
| @ -28,14 +28,14 @@ public: | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     const int port; | ||||
|     const u32 port; | ||||
|     const int button; | ||||
|     const GCAdapter::Adapter* gcadapter; | ||||
| }; | ||||
| 
 | ||||
| class GCAxisButton final : public Input::ButtonDevice { | ||||
| public: | ||||
|     explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_, | ||||
|     explicit GCAxisButton(u32 port_, u32 axis_, float threshold_, bool trigger_if_greater_, | ||||
|                           const GCAdapter::Adapter* adapter) | ||||
|         : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_), | ||||
|           gcadapter(adapter), | ||||
| @ -56,8 +56,8 @@ public: | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     const int port; | ||||
|     const int axis; | ||||
|     const u32 port; | ||||
|     const u32 axis; | ||||
|     float threshold; | ||||
|     bool trigger_if_greater; | ||||
|     const GCAdapter::Adapter* gcadapter; | ||||
| @ -70,8 +70,8 @@ GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_) | ||||
| GCButton::~GCButton() = default; | ||||
| 
 | ||||
| std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::ParamPackage& params) { | ||||
|     const int button_id = params.Get("button", 0); | ||||
|     const int port = params.Get("port", 0); | ||||
|     const auto button_id = params.Get("button", 0); | ||||
|     const auto port = static_cast<u32>(params.Get("port", 0)); | ||||
| 
 | ||||
|     constexpr int PAD_STICK_ID = static_cast<u16>(GCAdapter::PadButton::PAD_STICK); | ||||
| 
 | ||||
| @ -149,25 +149,27 @@ void GCButtonFactory::EndConfiguration() { | ||||
| 
 | ||||
| class GCAnalog final : public Input::AnalogDevice { | ||||
| public: | ||||
|     GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_, | ||||
|              const GCAdapter::Adapter* adapter, float range_) | ||||
|     explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, | ||||
|                       const GCAdapter::Adapter* adapter, float range_) | ||||
|         : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter), | ||||
|           origin_value_x(static_cast<float>(adapter->GetOriginValue(port_, axis_x_))), | ||||
|           origin_value_y(static_cast<float>(adapter->GetOriginValue(port_, axis_y_))), | ||||
|           range(range_) {} | ||||
| 
 | ||||
|     float GetAxis(int axis) const { | ||||
|     float GetAxis(u32 axis) const { | ||||
|         if (gcadapter->DeviceConnected(port)) { | ||||
|             std::lock_guard lock{mutex}; | ||||
|             const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y; | ||||
|             return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / (100.0f * range); | ||||
|             const auto axis_value = | ||||
|                 static_cast<float>(gcadapter->GetPadState()[port].axes.at(axis)); | ||||
|             return (axis_value - origin_value) / (100.0f * range); | ||||
|         } | ||||
|         return 0.0f; | ||||
|     } | ||||
| 
 | ||||
|     std::pair<float, float> GetAnalog(int axis_x, int axis_y) const { | ||||
|         float x = GetAxis(axis_x); | ||||
|         float y = GetAxis(axis_y); | ||||
|     std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { | ||||
|         float x = GetAxis(analog_axis_x); | ||||
|         float y = GetAxis(analog_axis_y); | ||||
| 
 | ||||
|         // Make sure the coordinates are in the unit circle,
 | ||||
|         // otherwise normalize it.
 | ||||
| @ -208,9 +210,9 @@ public: | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     const int port; | ||||
|     const int axis_x; | ||||
|     const int axis_y; | ||||
|     const u32 port; | ||||
|     const u32 axis_x; | ||||
|     const u32 axis_y; | ||||
|     const float deadzone; | ||||
|     const GCAdapter::Adapter* gcadapter; | ||||
|     const float origin_value_x; | ||||
| @ -231,11 +233,11 @@ GCAnalogFactory::GCAnalogFactory(std::shared_ptr<GCAdapter::Adapter> adapter_) | ||||
|  *     - "axis_y": the index of the axis to be bind as y-axis | ||||
|  */ | ||||
| std::unique_ptr<Input::AnalogDevice> GCAnalogFactory::Create(const Common::ParamPackage& params) { | ||||
|     const int port = params.Get("port", 0); | ||||
|     const int axis_x = params.Get("axis_x", 0); | ||||
|     const int axis_y = params.Get("axis_y", 1); | ||||
|     const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); | ||||
|     const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); | ||||
|     const auto port = static_cast<u32>(params.Get("port", 0)); | ||||
|     const auto axis_x = static_cast<u32>(params.Get("axis_x", 0)); | ||||
|     const auto axis_y = static_cast<u32>(params.Get("axis_y", 1)); | ||||
|     const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); | ||||
|     const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); | ||||
| 
 | ||||
|     return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter.get(), range); | ||||
| } | ||||
| @ -256,7 +258,7 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() { | ||||
|     for (std::size_t port = 0; port < queue.size(); ++port) { | ||||
|         while (queue[port].Pop(pad)) { | ||||
|             if (pad.axis == GCAdapter::PadAxes::Undefined || | ||||
|                 std::abs((pad.axis_value - 128.0f) / 128.0f) < 0.1) { | ||||
|                 std::abs((static_cast<float>(pad.axis_value) - 128.0f) / 128.0f) < 0.1f) { | ||||
|                 continue; | ||||
|             } | ||||
|             // An analog device needs two axes, so we need to store the axis for later and wait for
 | ||||
|  | ||||
| @ -49,8 +49,9 @@ public: | ||||
|     void ChangeKeyStatus(int key_code, bool pressed) { | ||||
|         std::lock_guard guard{mutex}; | ||||
|         for (const KeyButtonPair& pair : list) { | ||||
|             if (pair.key_code == key_code) | ||||
|             if (pair.key_code == key_code) { | ||||
|                 pair.key_button->status.store(pressed); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -73,7 +74,7 @@ KeyButton::~KeyButton() { | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) { | ||||
|     int key_code = params.Get("code", 0); | ||||
|     const int key_code = params.Get("code", 0); | ||||
|     std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list); | ||||
|     key_button_list->AddKeyButton(key_code, button.get()); | ||||
|     return button; | ||||
|  | ||||
| @ -196,6 +196,10 @@ ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPacka | ||||
|     return impl->GetButtonMappingForDevice(device); | ||||
| } | ||||
| 
 | ||||
| MotionMapping InputSubsystem::GetMotionMappingForDevice(const Common::ParamPackage& device) const { | ||||
|     return impl->GetMotionMappingForDevice(device); | ||||
| } | ||||
| 
 | ||||
| GCAnalogFactory* InputSubsystem::GetGCAnalogs() { | ||||
|     return impl->gcanalog.get(); | ||||
| } | ||||
|  | ||||
| @ -18,11 +18,11 @@ namespace InputCommon { | ||||
| // Implementation class of the motion emulation device
 | ||||
| class MotionEmuDevice { | ||||
| public: | ||||
|     MotionEmuDevice(int update_millisecond, float sensitivity) | ||||
|         : update_millisecond(update_millisecond), | ||||
|     explicit MotionEmuDevice(int update_millisecond_, float sensitivity_) | ||||
|         : update_millisecond(update_millisecond_), | ||||
|           update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>( | ||||
|               std::chrono::milliseconds(update_millisecond))), | ||||
|           sensitivity(sensitivity), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {} | ||||
|           sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {} | ||||
| 
 | ||||
|     ~MotionEmuDevice() { | ||||
|         if (motion_emu_thread.joinable()) { | ||||
| @ -37,16 +37,18 @@ public: | ||||
|     } | ||||
| 
 | ||||
|     void Tilt(int x, int y) { | ||||
|         auto mouse_move = Common::MakeVec(x, y) - mouse_origin; | ||||
|         if (is_tilting) { | ||||
|             std::lock_guard guard{tilt_mutex}; | ||||
|             if (mouse_move.x == 0 && mouse_move.y == 0) { | ||||
|                 tilt_angle = 0; | ||||
|             } else { | ||||
|                 tilt_direction = mouse_move.Cast<float>(); | ||||
|                 tilt_angle = | ||||
|                     std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f); | ||||
|             } | ||||
|         if (!is_tilting) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         std::lock_guard guard{tilt_mutex}; | ||||
|         const auto mouse_move = Common::MakeVec(x, y) - mouse_origin; | ||||
|         if (mouse_move.x == 0 && mouse_move.y == 0) { | ||||
|             tilt_angle = 0; | ||||
|         } else { | ||||
|             tilt_direction = mouse_move.Cast<float>(); | ||||
|             tilt_angle = | ||||
|                 std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -86,11 +88,10 @@ private: | ||||
|     void MotionEmuThread() { | ||||
|         auto update_time = std::chrono::steady_clock::now(); | ||||
|         Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0); | ||||
|         Common::Quaternion<float> old_q; | ||||
| 
 | ||||
|         while (!shutdown_event.WaitUntil(update_time)) { | ||||
|             update_time += update_duration; | ||||
|             old_q = q; | ||||
|             const Common::Quaternion<float> old_q = q; | ||||
| 
 | ||||
|             { | ||||
|                 std::lock_guard guard{tilt_mutex}; | ||||
| @ -100,14 +101,14 @@ private: | ||||
|                     Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle); | ||||
|             } | ||||
| 
 | ||||
|             auto inv_q = q.Inverse(); | ||||
|             const auto inv_q = q.Inverse(); | ||||
| 
 | ||||
|             // Set the gravity vector in world space
 | ||||
|             auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f); | ||||
| 
 | ||||
|             // Find the angular rate vector in world space
 | ||||
|             auto angular_rate = ((q - old_q) * inv_q).xyz * 2; | ||||
|             angular_rate *= 1000 / update_millisecond / Common::PI * 180; | ||||
|             angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f; | ||||
| 
 | ||||
|             // Transform the two vectors from world space to 3DS space
 | ||||
|             gravity = QuaternionRotate(inv_q, gravity); | ||||
| @ -136,7 +137,7 @@ private: | ||||
| // can forward all the inputs to the implementation only when it is valid.
 | ||||
| class MotionEmuDeviceWrapper : public Input::MotionDevice { | ||||
| public: | ||||
|     MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) { | ||||
|     explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) { | ||||
|         device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); | ||||
|     } | ||||
| 
 | ||||
| @ -148,8 +149,8 @@ public: | ||||
| }; | ||||
| 
 | ||||
| std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) { | ||||
|     int update_period = params.Get("update_period", 100); | ||||
|     float sensitivity = params.Get("sensitivity", 0.01f); | ||||
|     const int update_period = params.Get("update_period", 100); | ||||
|     const float sensitivity = params.Get("sensitivity", 0.01f); | ||||
|     auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity); | ||||
|     // Previously created device is disconnected here. Having two motion devices for 3DS is not
 | ||||
|     // expected.
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ class MotionKey final : public Input::MotionDevice { | ||||
| public: | ||||
|     using Button = std::unique_ptr<Input::ButtonDevice>; | ||||
| 
 | ||||
|     MotionKey(Button key_) : key(std::move(key_)) {} | ||||
|     explicit MotionKey(Button key_) : key(std::move(key_)) {} | ||||
| 
 | ||||
|     Input::MotionStatus GetStatus() const override { | ||||
| 
 | ||||
|  | ||||
| @ -8,8 +8,7 @@ | ||||
| 
 | ||||
| namespace InputCommon { | ||||
| 
 | ||||
| MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd) | ||||
|     : kp(new_kp), ki(new_ki), kd(new_kd), quat{{0, 0, -1}, 0} {} | ||||
| MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd) : kp(new_kp), ki(new_ki), kd(new_kd) {} | ||||
| 
 | ||||
| void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) { | ||||
|     accel = acceleration; | ||||
| @ -59,7 +58,7 @@ bool MotionInput::IsCalibrated(f32 sensitivity) const { | ||||
| } | ||||
| 
 | ||||
| void MotionInput::UpdateRotation(u64 elapsed_time) { | ||||
|     const f32 sample_period = elapsed_time / 1000000.0f; | ||||
|     const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f; | ||||
|     if (sample_period > 0.1f) { | ||||
|         return; | ||||
|     } | ||||
| @ -75,7 +74,7 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { | ||||
|     f32 q2 = quat.xyz[0]; | ||||
|     f32 q3 = quat.xyz[1]; | ||||
|     f32 q4 = quat.xyz[2]; | ||||
|     const f32 sample_period = elapsed_time / 1000000.0f; | ||||
|     const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f; | ||||
| 
 | ||||
|     // Ignore invalid elapsed time
 | ||||
|     if (sample_period > 0.1f) { | ||||
| @ -203,21 +202,21 @@ Input::MotionStatus MotionInput::GetRandomMotion(int accel_magnitude, int gyro_m | ||||
|     std::random_device device; | ||||
|     std::mt19937 gen(device()); | ||||
|     std::uniform_int_distribution<s16> distribution(-1000, 1000); | ||||
|     const Common::Vec3f gyroscope = { | ||||
|         distribution(gen) * 0.001f, | ||||
|         distribution(gen) * 0.001f, | ||||
|         distribution(gen) * 0.001f, | ||||
|     const Common::Vec3f gyroscope{ | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|     }; | ||||
|     const Common::Vec3f accelerometer = { | ||||
|         distribution(gen) * 0.001f, | ||||
|         distribution(gen) * 0.001f, | ||||
|         distribution(gen) * 0.001f, | ||||
|     const Common::Vec3f accelerometer{ | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|         static_cast<f32>(distribution(gen)) * 0.001f, | ||||
|     }; | ||||
|     const Common::Vec3f rotation = {}; | ||||
|     const std::array<Common::Vec3f, 3> orientation = { | ||||
|         Common::Vec3f{1.0f, 0, 0}, | ||||
|         Common::Vec3f{0, 1.0f, 0}, | ||||
|         Common::Vec3f{0, 0, 1.0f}, | ||||
|     constexpr Common::Vec3f rotation; | ||||
|     constexpr std::array orientation{ | ||||
|         Common::Vec3f{1.0f, 0.0f, 0.0f}, | ||||
|         Common::Vec3f{0.0f, 1.0f, 0.0f}, | ||||
|         Common::Vec3f{0.0f, 0.0f, 1.0f}, | ||||
|     }; | ||||
|     return {accelerometer * accel_magnitude, gyroscope * gyro_magnitude, rotation, orientation}; | ||||
| } | ||||
| @ -247,9 +246,6 @@ void MotionInput::SetOrientationFromAccelerometer() { | ||||
|     const f32 sample_period = 0.015f; | ||||
| 
 | ||||
|     const auto normal_accel = accel.Normalized(); | ||||
|     const f32 ax = -normal_accel.x; | ||||
|     const f32 ay = normal_accel.y; | ||||
|     const f32 az = -normal_accel.z; | ||||
| 
 | ||||
|     while (!IsCalibrated(0.01f) && ++iterations < 100) { | ||||
|         // Short name local variable for readability
 | ||||
| @ -258,7 +254,7 @@ void MotionInput::SetOrientationFromAccelerometer() { | ||||
|         f32 q3 = quat.xyz[1]; | ||||
|         f32 q4 = quat.xyz[2]; | ||||
| 
 | ||||
|         Common::Vec3f rad_gyro = {}; | ||||
|         Common::Vec3f rad_gyro; | ||||
|         const f32 ax = -normal_accel.x; | ||||
|         const f32 ay = normal_accel.y; | ||||
|         const f32 az = -normal_accel.z; | ||||
|  | ||||
| @ -22,7 +22,7 @@ public: | ||||
|     MotionInput& operator=(MotionInput&&) = default; | ||||
| 
 | ||||
|     void SetAcceleration(const Common::Vec3f& acceleration); | ||||
|     void SetGyroscope(const Common::Vec3f& acceleration); | ||||
|     void SetGyroscope(const Common::Vec3f& gyroscope); | ||||
|     void SetQuaternion(const Common::Quaternion<f32>& quaternion); | ||||
|     void SetGyroDrift(const Common::Vec3f& drift); | ||||
|     void SetGyroThreshold(f32 threshold); | ||||
| @ -49,16 +49,16 @@ private: | ||||
|     void SetOrientationFromAccelerometer(); | ||||
| 
 | ||||
|     // PID constants
 | ||||
|     const f32 kp; | ||||
|     const f32 ki; | ||||
|     const f32 kd; | ||||
|     f32 kp; | ||||
|     f32 ki; | ||||
|     f32 kd; | ||||
| 
 | ||||
|     // PID errors
 | ||||
|     Common::Vec3f real_error; | ||||
|     Common::Vec3f integral_error; | ||||
|     Common::Vec3f derivative_error; | ||||
| 
 | ||||
|     Common::Quaternion<f32> quat; | ||||
|     Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f}; | ||||
|     Common::Vec3f rotations; | ||||
|     Common::Vec3f accel; | ||||
|     Common::Vec3f gyro; | ||||
|  | ||||
| @ -56,9 +56,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { | ||||
| class SDLJoystick { | ||||
| public: | ||||
|     SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, | ||||
|                 SDL_GameController* gamecontroller) | ||||
|                 SDL_GameController* game_controller) | ||||
|         : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, | ||||
|           sdl_controller{gamecontroller, &SDL_GameControllerClose} {} | ||||
|           sdl_controller{game_controller, &SDL_GameControllerClose} {} | ||||
| 
 | ||||
|     void SetButton(int button, bool value) { | ||||
|         std::lock_guard lock{mutex}; | ||||
| @ -77,10 +77,10 @@ public: | ||||
| 
 | ||||
|     float GetAxis(int axis, float range) const { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         return state.axes.at(axis) / (32767.0f * range); | ||||
|         return static_cast<float>(state.axes.at(axis)) / (32767.0f * range); | ||||
|     } | ||||
| 
 | ||||
|     bool RumblePlay(f32 amp_low, f32 amp_high, int time) { | ||||
|     bool RumblePlay(f32 amp_low, f32 amp_high, u32 time) { | ||||
|         const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); | ||||
|         const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); | ||||
|         // Lower drastically the number of state changes
 | ||||
| @ -124,7 +124,7 @@ public: | ||||
|         return std::make_tuple(x, y); | ||||
|     } | ||||
| 
 | ||||
|     const InputCommon::MotionInput& GetMotion() const { | ||||
|     const MotionInput& GetMotion() const { | ||||
|         return motion; | ||||
|     } | ||||
| 
 | ||||
| @ -172,15 +172,15 @@ private: | ||||
|     } state; | ||||
|     std::string guid; | ||||
|     int port; | ||||
|     u16 last_state_rumble_high; | ||||
|     u16 last_state_rumble_low; | ||||
|     u16 last_state_rumble_high = 0; | ||||
|     u16 last_state_rumble_low = 0; | ||||
|     std::chrono::time_point<std::chrono::system_clock> last_vibration; | ||||
|     std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | ||||
|     std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | ||||
|     mutable std::mutex mutex; | ||||
| 
 | ||||
|     // motion is initalized without PID values as motion input is not aviable for SDL2
 | ||||
|     InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; | ||||
|     // Motion is initialized without PID values as motion input is not aviable for SDL2
 | ||||
|     MotionInput motion{0.0f, 0.0f, 0.0f}; | ||||
| }; | ||||
| 
 | ||||
| std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { | ||||
| @ -192,7 +192,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& g | ||||
|                                                           nullptr, nullptr); | ||||
|             it->second.emplace_back(std::move(joystick)); | ||||
|         } | ||||
|         return it->second[port]; | ||||
|         return it->second[static_cast<std::size_t>(port)]; | ||||
|     } | ||||
|     auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr); | ||||
|     return joystick_map[guid].emplace_back(std::move(joystick)); | ||||
| @ -212,7 +212,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_ | ||||
|                              return sdl_joystick == joystick->GetSDLJoystick(); | ||||
|                          }); | ||||
|         if (vec_it != map_it->second.end()) { | ||||
|             // This is the common case: There is already an existing SDL_Joystick maped to a
 | ||||
|             // This is the common case: There is already an existing SDL_Joystick mapped to a
 | ||||
|             // SDLJoystick. return the SDLJoystick
 | ||||
|             return *vec_it; | ||||
|         } | ||||
| @ -220,7 +220,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_ | ||||
|         // Search for a SDLJoystick without a mapped SDL_Joystick...
 | ||||
|         const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), | ||||
|                                              [](const std::shared_ptr<SDLJoystick>& joystick) { | ||||
|                                                  return !joystick->GetSDLJoystick(); | ||||
|                                                  return joystick->GetSDLJoystick() == nullptr; | ||||
|                                              }); | ||||
|         if (nullptr_it != map_it->second.end()) { | ||||
|             // ... and map it
 | ||||
| @ -273,22 +273,21 @@ void SDLState::InitJoystick(int joystick_index) { | ||||
| void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { | ||||
|     const std::string guid = GetGUID(sdl_joystick); | ||||
| 
 | ||||
|     std::shared_ptr<SDLJoystick> joystick; | ||||
|     std::shared_ptr<SDLJoystick> found_joystick; | ||||
|     { | ||||
|         std::lock_guard lock{joystick_map_mutex}; | ||||
|         // This call to guid is safe since the joystick is guaranteed to be in the map
 | ||||
|         const auto& joystick_guid_list = joystick_map[guid]; | ||||
|         const auto joystick_it = | ||||
|             std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), | ||||
|                          [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { | ||||
|                              return joystick->GetSDLJoystick() == sdl_joystick; | ||||
|                          }); | ||||
|         joystick = *joystick_it; | ||||
|         const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), | ||||
|                                               [&sdl_joystick](const auto& joystick) { | ||||
|                                                   return joystick->GetSDLJoystick() == sdl_joystick; | ||||
|                                               }); | ||||
|         found_joystick = *joystick_it; | ||||
|     } | ||||
| 
 | ||||
|     // Destruct SDL_Joystick outside the lock guard because SDL can internally call the
 | ||||
|     // event callback which locks the mutex again.
 | ||||
|     joystick->SetSDLJoystick(nullptr, nullptr); | ||||
|     found_joystick->SetSDLJoystick(nullptr, nullptr); | ||||
| } | ||||
| 
 | ||||
| void SDLState::HandleGameControllerEvent(const SDL_Event& event) { | ||||
| @ -392,8 +391,8 @@ private: | ||||
| 
 | ||||
| class SDLAnalog final : public Input::AnalogDevice { | ||||
| public: | ||||
|     SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, float deadzone_, | ||||
|               float range_) | ||||
|     explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, | ||||
|                        float deadzone_, float range_) | ||||
|         : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), | ||||
|           range(range_) {} | ||||
| 
 | ||||
| @ -672,13 +671,13 @@ SDLState::SDLState() { | ||||
|     RegisterFactory<ButtonDevice>("sdl", button_factory); | ||||
|     RegisterFactory<MotionDevice>("sdl", motion_factory); | ||||
| 
 | ||||
|     // If the frontend is going to manage the event loop, then we dont start one here
 | ||||
|     start_thread = !SDL_WasInit(SDL_INIT_JOYSTICK); | ||||
|     // If the frontend is going to manage the event loop, then we don't start one here
 | ||||
|     start_thread = SDL_WasInit(SDL_INIT_JOYSTICK) == 0; | ||||
|     if (start_thread && SDL_Init(SDL_INIT_JOYSTICK) < 0) { | ||||
|         LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); | ||||
|         return; | ||||
|     } | ||||
|     has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); | ||||
|     has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0; | ||||
|     if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) { | ||||
|         LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError()); | ||||
|     } | ||||
| @ -723,8 +722,8 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | ||||
|     std::vector<Common::ParamPackage> devices; | ||||
|     for (const auto& [key, value] : joystick_map) { | ||||
|         for (const auto& joystick : value) { | ||||
|             auto joy = joystick->GetSDLJoystick(); | ||||
|             if (auto controller = joystick->GetSDLGameController()) { | ||||
|             auto* joy = joystick->GetSDLJoystick(); | ||||
|             if (auto* controller = joystick->GetSDLGameController()) { | ||||
|                 std::string name = | ||||
|                     fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort()); | ||||
|                 devices.emplace_back(Common::ParamPackage{ | ||||
| @ -748,7 +747,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | ||||
| } | ||||
| 
 | ||||
| namespace { | ||||
| Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, u8 axis, | ||||
| Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, | ||||
|                                                       float value = 0.1f) { | ||||
|     Common::ParamPackage params({{"engine", "sdl"}}); | ||||
|     params.Set("port", port); | ||||
| @ -764,7 +763,7 @@ Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid | ||||
|     return params; | ||||
| } | ||||
| 
 | ||||
| Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, u8 button) { | ||||
| Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, s32 button) { | ||||
|     Common::ParamPackage params({{"engine", "sdl"}}); | ||||
|     params.Set("port", port); | ||||
|     params.Set("guid", std::move(guid)); | ||||
| @ -772,7 +771,7 @@ Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid | ||||
|     return params; | ||||
| } | ||||
| 
 | ||||
| Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, u8 hat, u8 value) { | ||||
| Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, s32 hat, s32 value) { | ||||
|     Common::ParamPackage params({{"engine", "sdl"}}); | ||||
| 
 | ||||
|     params.Set("port", port); | ||||
| @ -802,17 +801,19 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve | ||||
|     case SDL_JOYAXISMOTION: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | ||||
|         return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                                 event.jaxis.axis, event.jaxis.value); | ||||
|                                                 static_cast<s32>(event.jaxis.axis), | ||||
|                                                 event.jaxis.value); | ||||
|     } | ||||
|     case SDL_JOYBUTTONUP: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); | ||||
|         return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                                 event.jbutton.button); | ||||
|                                                 static_cast<s32>(event.jbutton.button)); | ||||
|     } | ||||
|     case SDL_JOYHATMOTION: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); | ||||
|         return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                              event.jhat.hat, event.jhat.value); | ||||
|                                              static_cast<s32>(event.jhat.hat), | ||||
|                                              static_cast<s32>(event.jhat.value)); | ||||
|     } | ||||
|     } | ||||
|     return {}; | ||||
| @ -823,17 +824,19 @@ Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Eve | ||||
|     case SDL_JOYAXISMOTION: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | ||||
|         return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                                 event.jaxis.axis, event.jaxis.value); | ||||
|                                                 static_cast<s32>(event.jaxis.axis), | ||||
|                                                 event.jaxis.value); | ||||
|     } | ||||
|     case SDL_JOYBUTTONUP: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); | ||||
|         return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                                 event.jbutton.button); | ||||
|                                                 static_cast<s32>(event.jbutton.button)); | ||||
|     } | ||||
|     case SDL_JOYHATMOTION: { | ||||
|         const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); | ||||
|         return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | ||||
|                                              event.jhat.hat, event.jhat.value); | ||||
|                                              static_cast<s32>(event.jhat.hat), | ||||
|                                              static_cast<s32>(event.jhat.value)); | ||||
|     } | ||||
|     } | ||||
|     return {}; | ||||
| @ -1062,7 +1065,7 @@ public: | ||||
|             if (event.type == SDL_JOYAXISMOTION) { | ||||
|                 const auto axis = event.jaxis.axis; | ||||
|                 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | ||||
|                 const auto controller = joystick->GetSDLGameController(); | ||||
|                 auto* const controller = joystick->GetSDLGameController(); | ||||
|                 if (controller) { | ||||
|                     const auto axis_left_x = | ||||
|                         SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) | ||||
|  | ||||
| @ -11,9 +11,11 @@ namespace InputCommon { | ||||
| class TouchFromButtonDevice final : public Input::TouchDevice { | ||||
| public: | ||||
|     TouchFromButtonDevice() { | ||||
|         for (const auto& config_entry : | ||||
|              Settings::values.touch_from_button_maps[Settings::values.touch_from_button_map_index] | ||||
|                  .buttons) { | ||||
|         const auto button_index = | ||||
|             static_cast<std::size_t>(Settings::values.touch_from_button_map_index); | ||||
|         const auto& buttons = Settings::values.touch_from_button_maps[button_index].buttons; | ||||
| 
 | ||||
|         for (const auto& config_entry : buttons) { | ||||
|             const Common::ParamPackage package{config_entry}; | ||||
|             map.emplace_back( | ||||
|                 Input::CreateDevice<Input::ButtonDevice>(config_entry), | ||||
|  | ||||
| @ -26,11 +26,11 @@ class Socket { | ||||
| public: | ||||
|     using clock = std::chrono::system_clock; | ||||
| 
 | ||||
|     explicit Socket(const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
|                     SocketCallback callback) | ||||
|         : callback(std::move(callback)), timer(io_service), | ||||
|           socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id), | ||||
|           pad_index(pad_index) { | ||||
|     explicit Socket(const std::string& host, u16 port, std::size_t pad_index_, u32 client_id_, | ||||
|                     SocketCallback callback_) | ||||
|         : callback(std::move(callback_)), timer(io_service), | ||||
|           socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id_), | ||||
|           pad_index(pad_index_) { | ||||
|         boost::system::error_code ec{}; | ||||
|         auto ipv4 = boost::asio::ip::make_address_v4(host, ec); | ||||
|         if (ec.value() != boost::system::errc::success) { | ||||
| @ -93,13 +93,17 @@ private: | ||||
|     void HandleSend(const boost::system::error_code& error) { | ||||
|         boost::system::error_code _ignored{}; | ||||
|         // Send a request for getting port info for the pad
 | ||||
|         Request::PortInfo port_info{1, {pad_index, 0, 0, 0}}; | ||||
|         const Request::PortInfo port_info{1, {static_cast<u8>(pad_index), 0, 0, 0}}; | ||||
|         const auto port_message = Request::Create(port_info, client_id); | ||||
|         std::memcpy(&send_buffer1, &port_message, PORT_INFO_SIZE); | ||||
|         socket.send_to(boost::asio::buffer(send_buffer1), send_endpoint, {}, _ignored); | ||||
| 
 | ||||
|         // Send a request for getting pad data for the pad
 | ||||
|         Request::PadData pad_data{Request::PadData::Flags::Id, pad_index, EMPTY_MAC_ADDRESS}; | ||||
|         const Request::PadData pad_data{ | ||||
|             Request::PadData::Flags::Id, | ||||
|             static_cast<u8>(pad_index), | ||||
|             EMPTY_MAC_ADDRESS, | ||||
|         }; | ||||
|         const auto pad_message = Request::Create(pad_data, client_id); | ||||
|         std::memcpy(send_buffer2.data(), &pad_message, PAD_DATA_SIZE); | ||||
|         socket.send_to(boost::asio::buffer(send_buffer2), send_endpoint, {}, _ignored); | ||||
| @ -112,7 +116,7 @@ private: | ||||
|     udp::socket socket; | ||||
| 
 | ||||
|     u32 client_id{}; | ||||
|     u8 pad_index{}; | ||||
|     std::size_t pad_index{}; | ||||
| 
 | ||||
|     static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>); | ||||
|     static constexpr std::size_t PAD_DATA_SIZE = sizeof(Message<Request::PadData>); | ||||
| @ -133,7 +137,7 @@ static void SocketLoop(Socket* socket) { | ||||
| Client::Client() { | ||||
|     LOG_INFO(Input, "Udp Initialization started"); | ||||
|     for (std::size_t client = 0; client < clients.size(); client++) { | ||||
|         u8 pad = client % 4; | ||||
|         const auto pad = client % 4; | ||||
|         StartCommunication(client, Settings::values.udp_input_address, | ||||
|                            Settings::values.udp_input_port, pad, 24872); | ||||
|         // Set motion parameters
 | ||||
| @ -166,9 +170,9 @@ std::vector<Common::ParamPackage> Client::GetInputDevices() const { | ||||
| bool Client::DeviceConnected(std::size_t pad) const { | ||||
|     // Use last timestamp to detect if the socket has stopped sending data
 | ||||
|     const auto now = std::chrono::system_clock::now(); | ||||
|     u64 time_difference = | ||||
|     const auto time_difference = static_cast<u64>( | ||||
|         std::chrono::duration_cast<std::chrono::milliseconds>(now - clients[pad].last_motion_update) | ||||
|             .count(); | ||||
|             .count()); | ||||
|     return time_difference < 1000 && clients[pad].active == 1; | ||||
| } | ||||
| 
 | ||||
| @ -177,9 +181,9 @@ void Client::ReloadUDPClient() { | ||||
|         ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, client); | ||||
|     } | ||||
| } | ||||
| void Client::ReloadSocket(const std::string& host, u16 port, u8 pad_index, u32 client_id) { | ||||
| void Client::ReloadSocket(const std::string& host, u16 port, std::size_t pad_index, u32 client_id) { | ||||
|     // client number must be determined from host / port and pad index
 | ||||
|     std::size_t client = pad_index; | ||||
|     const std::size_t client = pad_index; | ||||
|     clients[client].socket->Stop(); | ||||
|     clients[client].thread.join(); | ||||
|     StartCommunication(client, host, port, pad_index, client_id); | ||||
| @ -194,8 +198,8 @@ void Client::OnPortInfo(Response::PortInfo data) { | ||||
| } | ||||
| 
 | ||||
| void Client::OnPadData(Response::PadData data) { | ||||
|     // client number must be determined from host / port and pad index
 | ||||
|     std::size_t client = data.info.id; | ||||
|     // Client number must be determined from host / port and pad index
 | ||||
|     const std::size_t client = data.info.id; | ||||
|     LOG_TRACE(Input, "PadData packet received"); | ||||
|     if (data.packet_counter == clients[client].packet_sequence) { | ||||
|         LOG_WARNING( | ||||
| @ -207,11 +211,12 @@ void Client::OnPadData(Response::PadData data) { | ||||
|     clients[client].active = data.info.is_pad_active; | ||||
|     clients[client].packet_sequence = data.packet_counter; | ||||
|     const auto now = std::chrono::system_clock::now(); | ||||
|     u64 time_difference = std::chrono::duration_cast<std::chrono::microseconds>( | ||||
|                               now - clients[client].last_motion_update) | ||||
|                               .count(); | ||||
|     const auto time_difference = | ||||
|         static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>( | ||||
|                              now - clients[client].last_motion_update) | ||||
|                              .count()); | ||||
|     clients[client].last_motion_update = now; | ||||
|     Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw}; | ||||
|     const Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw}; | ||||
|     clients[client].motion.SetAcceleration({data.accel.x, -data.accel.z, data.accel.y}); | ||||
|     // Gyroscope values are not it the correct scale from better joy.
 | ||||
|     // Dividing by 312 allows us to make one full turn = 1 turn
 | ||||
| @ -237,9 +242,11 @@ void Client::OnPadData(Response::PadData data) { | ||||
|             const u16 min_y = clients[client].status.touch_calibration->min_y; | ||||
|             const u16 max_y = clients[client].status.touch_calibration->max_y; | ||||
| 
 | ||||
|             x = (std::clamp(static_cast<u16>(data.touch_1.x), min_x, max_x) - min_x) / | ||||
|             x = static_cast<float>(std::clamp(static_cast<u16>(data.touch_1.x), min_x, max_x) - | ||||
|                                    min_x) / | ||||
|                 static_cast<float>(max_x - min_x); | ||||
|             y = (std::clamp(static_cast<u16>(data.touch_1.y), min_y, max_y) - min_y) / | ||||
|             y = static_cast<float>(std::clamp(static_cast<u16>(data.touch_1.y), min_y, max_y) - | ||||
|                                    min_y) / | ||||
|                 static_cast<float>(max_y - min_y); | ||||
|         } | ||||
| 
 | ||||
| @ -253,8 +260,8 @@ void Client::OnPadData(Response::PadData data) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Client::StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index, | ||||
|                                 u32 client_id) { | ||||
| void Client::StartCommunication(std::size_t client, const std::string& host, u16 port, | ||||
|                                 std::size_t pad_index, u32 client_id) { | ||||
|     SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, | ||||
|                             [this](Response::PortInfo info) { OnPortInfo(info); }, | ||||
|                             [this](Response::PadData data) { OnPadData(data); }}; | ||||
| @ -264,9 +271,9 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16 | ||||
| } | ||||
| 
 | ||||
| void Client::Reset() { | ||||
|     for (std::size_t client = 0; client < clients.size(); client++) { | ||||
|         clients[client].socket->Stop(); | ||||
|         clients[client].thread.join(); | ||||
|     for (auto& client : clients) { | ||||
|         client.socket->Stop(); | ||||
|         client.thread.join(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -325,7 +332,7 @@ const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() cons | ||||
|     return pad_queue; | ||||
| } | ||||
| 
 | ||||
| void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
| void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id, | ||||
|                        std::function<void()> success_callback, | ||||
|                        std::function<void()> failure_callback) { | ||||
|     std::thread([=] { | ||||
| @ -346,7 +353,7 @@ void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 clie | ||||
| } | ||||
| 
 | ||||
| CalibrationConfigurationJob::CalibrationConfigurationJob( | ||||
|     const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
|     const std::string& host, u16 port, std::size_t pad_index, u32 client_id, | ||||
|     std::function<void(Status)> status_callback, | ||||
|     std::function<void(u16, u16, u16, u16)> data_callback) { | ||||
| 
 | ||||
| @ -366,7 +373,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob( | ||||
|                                         current_status = Status::Ready; | ||||
|                                         status_callback(current_status); | ||||
|                                     } | ||||
|                                     if (!data.touch_1.is_active) { | ||||
|                                     if (data.touch_1.is_active == 0) { | ||||
|                                         return; | ||||
|                                     } | ||||
|                                     LOG_DEBUG(Input, "Current touch: {} {}", data.touch_1.x, | ||||
|  | ||||
| @ -84,8 +84,8 @@ public: | ||||
| 
 | ||||
|     bool DeviceConnected(std::size_t pad) const; | ||||
|     void ReloadUDPClient(); | ||||
|     void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760, u8 pad_index = 0, | ||||
|                       u32 client_id = 24872); | ||||
|     void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760, | ||||
|                       std::size_t pad_index = 0, u32 client_id = 24872); | ||||
| 
 | ||||
|     std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue(); | ||||
|     const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue() const; | ||||
| @ -99,7 +99,7 @@ private: | ||||
|         DeviceStatus status; | ||||
|         std::thread thread; | ||||
|         u64 packet_sequence = 0; | ||||
|         u8 active; | ||||
|         u8 active = 0; | ||||
| 
 | ||||
|         // Realtime values
 | ||||
|         // motion is initalized with PID values for drift correction on joycons
 | ||||
| @ -113,8 +113,8 @@ private: | ||||
|     void OnVersion(Response::Version); | ||||
|     void OnPortInfo(Response::PortInfo); | ||||
|     void OnPadData(Response::PadData); | ||||
|     void StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index, | ||||
|                             u32 client_id); | ||||
|     void StartCommunication(std::size_t client, const std::string& host, u16 port, | ||||
|                             std::size_t pad_index, u32 client_id); | ||||
|     void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, | ||||
|                             const Common::Vec3<float>& gyro, bool touch); | ||||
| 
 | ||||
| @ -139,7 +139,7 @@ public: | ||||
|      * @param status_callback Callback for job status updates | ||||
|      * @param data_callback Called when calibration data is ready | ||||
|      */ | ||||
|     explicit CalibrationConfigurationJob(const std::string& host, u16 port, u8 pad_index, | ||||
|     explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index, | ||||
|                                          u32 client_id, std::function<void(Status)> status_callback, | ||||
|                                          std::function<void(u16, u16, u16, u16)> data_callback); | ||||
|     ~CalibrationConfigurationJob(); | ||||
| @ -149,7 +149,7 @@ private: | ||||
|     Common::Event complete_event; | ||||
| }; | ||||
| 
 | ||||
| void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
| void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id, | ||||
|                        std::function<void()> success_callback, | ||||
|                        std::function<void()> failure_callback); | ||||
| 
 | ||||
|  | ||||
| @ -2,8 +2,6 @@ | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <atomic> | ||||
| #include <list> | ||||
| #include <mutex> | ||||
| #include <utility> | ||||
| #include "common/assert.h" | ||||
| @ -15,8 +13,8 @@ namespace InputCommon { | ||||
| 
 | ||||
| class UDPMotion final : public Input::MotionDevice { | ||||
| public: | ||||
|     UDPMotion(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_) | ||||
|         : ip(ip_), port(port_), pad(pad_), client(client_) {} | ||||
|     explicit UDPMotion(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) | ||||
|         : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} | ||||
| 
 | ||||
|     Input::MotionStatus GetStatus() const override { | ||||
|         return client->GetPadState(pad).motion_status; | ||||
| @ -25,7 +23,7 @@ public: | ||||
| private: | ||||
|     const std::string ip; | ||||
|     const int port; | ||||
|     const int pad; | ||||
|     const u32 pad; | ||||
|     CemuhookUDP::Client* client; | ||||
|     mutable std::mutex mutex; | ||||
| }; | ||||
| @ -40,11 +38,11 @@ UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_) | ||||
|  *     - "port": the nth jcpad on the adapter | ||||
|  */ | ||||
| std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) { | ||||
|     const std::string ip = params.Get("ip", "127.0.0.1"); | ||||
|     const int port = params.Get("port", 26760); | ||||
|     const int pad = params.Get("pad_index", 0); | ||||
|     auto ip = params.Get("ip", "127.0.0.1"); | ||||
|     const auto port = params.Get("port", 26760); | ||||
|     const auto pad = static_cast<u32>(params.Get("pad_index", 0)); | ||||
| 
 | ||||
|     return std::make_unique<UDPMotion>(ip, port, pad, client.get()); | ||||
|     return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get()); | ||||
| } | ||||
| 
 | ||||
| void UDPMotionFactory::BeginConfiguration() { | ||||
| @ -79,7 +77,7 @@ Common::ParamPackage UDPMotionFactory::GetNextInput() { | ||||
| 
 | ||||
| class UDPTouch final : public Input::TouchDevice { | ||||
| public: | ||||
|     UDPTouch(std::string ip_, int port_, int pad_, CemuhookUDP::Client* client_) | ||||
|     explicit UDPTouch(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) | ||||
|         : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} | ||||
| 
 | ||||
|     std::tuple<float, float, bool> GetStatus() const override { | ||||
| @ -89,7 +87,7 @@ public: | ||||
| private: | ||||
|     const std::string ip; | ||||
|     const int port; | ||||
|     const int pad; | ||||
|     const u32 pad; | ||||
|     CemuhookUDP::Client* client; | ||||
|     mutable std::mutex mutex; | ||||
| }; | ||||
| @ -104,11 +102,11 @@ UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_) | ||||
|  *     - "port": the nth jcpad on the adapter | ||||
|  */ | ||||
| std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) { | ||||
|     const std::string ip = params.Get("ip", "127.0.0.1"); | ||||
|     const int port = params.Get("port", 26760); | ||||
|     const int pad = params.Get("pad_index", 0); | ||||
|     auto ip = params.Get("ip", "127.0.0.1"); | ||||
|     const auto port = params.Get("port", 26760); | ||||
|     const auto pad = static_cast<u32>(params.Get("pad_index", 0)); | ||||
| 
 | ||||
|     return std::make_unique<UDPTouch>(ip, port, pad, client.get()); | ||||
|     return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get()); | ||||
| } | ||||
| 
 | ||||
| void UDPTouchFactory::BeginConfiguration() { | ||||
|  | ||||
| @ -193,7 +193,7 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() { | ||||
|     udp_test_in_progress = true; | ||||
|     InputCommon::CemuhookUDP::TestCommunication( | ||||
|         ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), | ||||
|         static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872, | ||||
|         static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872, | ||||
|         [this] { | ||||
|             LOG_INFO(Frontend, "UDP input test success"); | ||||
|             QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Lioncash
						Lioncash