فهرست منبع

input_common: Move touch and analog from button. Move udp protocol

german77 4 سال پیش
والد
کامیت
4c6f2c2547

+ 6 - 6
src/input_common/CMakeLists.txt

@@ -1,8 +1,12 @@
 add_library(input_common STATIC
-    analog_from_button.cpp
-    analog_from_button.h
     keyboard.cpp
     keyboard.h
+    helpers/stick_from_buttons.cpp
+    helpers/stick_from_buttons.h
+    helpers/touch_from_buttons.cpp
+    helpers/touch_from_buttons.h
+    helpers/udp_protocol.cpp
+    helpers/udp_protocol.h
     input_engine.cpp
     input_engine.h
     input_mapping.cpp
@@ -15,8 +19,6 @@ add_library(input_common STATIC
     motion_from_button.h
     motion_input.cpp
     motion_input.h
-    touch_from_button.cpp
-    touch_from_button.h
     gcadapter/gc_adapter.cpp
     gcadapter/gc_adapter.h
     gcadapter/gc_poller.cpp
@@ -33,8 +35,6 @@ add_library(input_common STATIC
     tas/tas_poller.h
     udp/client.cpp
     udp/client.h
-    udp/protocol.cpp
-    udp/protocol.h
     udp/udp.cpp
     udp/udp.h
 )

+ 87 - 55
src/input_common/analog_from_button.cpp → src/input_common/helpers/stick_from_buttons.cpp

@@ -2,32 +2,38 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include <atomic>
 #include <chrono>
 #include <cmath>
-#include <thread>
 #include "common/math_util.h"
 #include "common/settings.h"
-#include "input_common/analog_from_button.h"
+#include "input_common/helpers/stick_from_buttons.h"
 
 namespace InputCommon {
 
-class Analog final : public Input::AnalogDevice {
+class Stick final : public Input::InputDevice {
 public:
-    using Button = std::unique_ptr<Input::ButtonDevice>;
+    using Button = std::unique_ptr<Input::InputDevice>;
 
-    Analog(Button up_, Button down_, Button left_, Button right_, Button modifier_,
-           float modifier_scale_, float modifier_angle_)
+    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<bool> callbacks{
-            [this]([[maybe_unused]] bool status) { UpdateStatus(); }};
-        up->SetCallback(callbacks);
-        down->SetCallback(callbacks);
-        left->SetCallback(callbacks);
-        right->SetCallback(callbacks);
-        modifier->SetCallback(callbacks);
+        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 {
@@ -123,13 +129,38 @@ public:
         }
     }
 
+    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->GetStatus() ? modifier_scale : 1.0f;
+        const float coef = modifier_status ? modifier_scale : 1.0f;
 
-        bool r = right->GetStatus();
-        bool l = left->GetStatus();
-        bool u = up->GetStatus();
-        bool d = down->GetStatus();
+        bool r = right_status;
+        bool l = left_status;
+        bool u = up_status;
+        bool d = down_status;
 
         // Eliminate contradictory movements
         if (r && l) {
@@ -162,49 +193,42 @@ public:
         }
 
         last_update = now;
+        Input::CallbackStatus status{
+            .type = Input::InputType::Stick,
+            .stick_status = GetStatus(),
+        };
+        TriggerOnChange(status);
     }
 
-    std::tuple<float, float> GetStatus() const override {
+    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);
-            return std::make_tuple(std::cos(angle_) * amplitude, std::sin(angle_) * amplitude);
+            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->GetStatus()) {
+        if (right_status) {
             ++x;
         }
-        if (left->GetStatus()) {
+        if (left_status) {
             --x;
         }
-        if (up->GetStatus()) {
+        if (up_status) {
             ++y;
         }
-        if (down->GetStatus()) {
+        if (down_status) {
             --y;
         }
-        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));
-    }
-
-    Input::AnalogProperties GetAnalogProperties() const override {
-        return {modifier_scale, 1.0f, 0.5f};
-    }
-
-    bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {
-        switch (direction) {
-        case Input::AnalogDirection::RIGHT:
-            return right->GetStatus();
-        case Input::AnalogDirection::LEFT:
-            return left->GetStatus();
-        case Input::AnalogDirection::UP:
-            return up->GetStatus();
-        case Input::AnalogDirection::DOWN:
-            return down->GetStatus();
-        }
-        return false;
+        const float coef = modifier_status ? modifier_scale : 1.0f;
+        status.x.raw_value = static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF);
+        status.y.raw_value = static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF);
+        return status;
     }
 
 private:
@@ -218,21 +242,29 @@ private:
     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<std::chrono::steady_clock> last_update;
 };
 
-std::unique_ptr<Input::AnalogDevice> AnalogFromButton::Create(const Common::ParamPackage& params) {
+std::unique_ptr<Input::InputDevice> StickFromButton::Create(const Common::ParamPackage& params) {
     const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
-    auto up = Input::CreateDevice<Input::ButtonDevice>(params.Get("up", null_engine));
-    auto down = Input::CreateDevice<Input::ButtonDevice>(params.Get("down", null_engine));
-    auto left = Input::CreateDevice<Input::ButtonDevice>(params.Get("left", null_engine));
-    auto right = Input::CreateDevice<Input::ButtonDevice>(params.Get("right", null_engine));
-    auto modifier = Input::CreateDevice<Input::ButtonDevice>(params.Get("modifier", null_engine));
+    auto up = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("up", null_engine));
+    auto down = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("down", null_engine));
+    auto left = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("left", null_engine));
+    auto right =
+        Input::CreateDeviceFromString<Input::InputDevice>(params.Get("right", null_engine));
+    auto modifier =
+        Input::CreateDeviceFromString<Input::InputDevice>(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<Analog>(std::move(up), std::move(down), std::move(left),
-                                    std::move(right), std::move(modifier), modifier_scale,
-                                    modifier_angle);
+    return std::make_unique<Stick>(std::move(up), std::move(down), std::move(left),
+                                   std::move(right), std::move(modifier), modifier_scale,
+                                   modifier_angle);
 }
 
 } // namespace InputCommon

+ 4 - 4
src/input_common/analog_from_button.h → src/input_common/helpers/stick_from_buttons.h

@@ -1,11 +1,11 @@
+
 // Copyright 2017 Citra Emulator Project
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
 #pragma once
 
-#include <memory>
-#include "core/frontend/input.h"
+#include "common/input.h"
 
 namespace InputCommon {
 
@@ -13,7 +13,7 @@ namespace InputCommon {
  * An analog device factory that takes direction button devices and combines them into a analog
  * device.
  */
-class AnalogFromButton final : public Input::Factory<Input::AnalogDevice> {
+class StickFromButton final : public Input::Factory<Input::InputDevice> {
 public:
     /**
      * Creates an analog device from direction button devices
@@ -25,7 +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<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
+    std::unique_ptr<Input::InputDevice> Create(const Common::ParamPackage& params) override;
 };
 
 } // namespace InputCommon

+ 70 - 0
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 <algorithm>
+#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<Input::InputDevice>;
+    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<Input::InputDevice> TouchFromButton::Create(const Common::ParamPackage& params) {
+    const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
+    auto button =
+        Input::CreateDeviceFromString<Input::InputDevice>(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<TouchFromButtonDevice>(std::move(button), touch_id, x, y);
+}
+
+} // namespace InputCommon

+ 3 - 4
src/input_common/touch_from_button.h → src/input_common/helpers/touch_from_buttons.h

@@ -4,20 +4,19 @@
 
 #pragma once
 
-#include <memory>
-#include "core/frontend/input.h"
+#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 TouchFromButtonFactory final : public Input::Factory<Input::TouchDevice> {
+class TouchFromButton final : public Input::Factory<Input::InputDevice> {
 public:
     /**
      * Creates a touch device from a list of button devices
      */
-    std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
+    std::unique_ptr<Input::InputDevice> Create(const Common::ParamPackage& params) override;
 };
 
 } // namespace InputCommon

+ 1 - 1
src/input_common/udp/protocol.cpp → src/input_common/helpers/udp_protocol.cpp

@@ -5,7 +5,7 @@
 #include <cstddef>
 #include <cstring>
 #include "common/logging/log.h"
-#include "input_common/udp/protocol.h"
+#include "input_common/helpers/udp_protocol.h"
 
 namespace InputCommon::CemuhookUDP {
 

+ 0 - 0
src/input_common/udp/protocol.h → src/input_common/helpers/udp_protocol.h


+ 0 - 8
src/input_common/main.cpp

@@ -6,7 +6,6 @@
 #include <thread>
 #include "common/param_package.h"
 #include "common/settings.h"
-#include "input_common/analog_from_button.h"
 #include "input_common/gcadapter/gc_adapter.h"
 #include "input_common/gcadapter/gc_poller.h"
 #include "input_common/keyboard.h"
@@ -16,7 +15,6 @@
 #include "input_common/mouse/mouse_poller.h"
 #include "input_common/tas/tas_input.h"
 #include "input_common/tas/tas_poller.h"
-#include "input_common/touch_from_button.h"
 #include "input_common/udp/client.h"
 #include "input_common/udp/udp.h"
 #ifdef HAVE_SDL2
@@ -37,12 +35,8 @@ struct InputSubsystem::Impl {
 
         keyboard = std::make_shared<Keyboard>();
         Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
-        Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
-                                                    std::make_shared<AnalogFromButton>());
         Input::RegisterFactory<Input::MotionDevice>("keyboard",
                                                     std::make_shared<MotionFromButton>());
-        Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
-                                                   std::make_shared<TouchFromButtonFactory>());
 
 #ifdef HAVE_SDL2
         sdl = SDL::Init();
@@ -75,8 +69,6 @@ struct InputSubsystem::Impl {
         Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
         Input::UnregisterFactory<Input::MotionDevice>("keyboard");
         keyboard.reset();
-        Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
-        Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
 #ifdef HAVE_SDL2
         sdl.reset();
 #endif

+ 0 - 53
src/input_common/touch_from_button.cpp

@@ -1,53 +0,0 @@
-// Copyright 2020 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include "common/settings.h"
-#include "core/frontend/framebuffer_layout.h"
-#include "input_common/touch_from_button.h"
-
-namespace InputCommon {
-
-class TouchFromButtonDevice final : public Input::TouchDevice {
-public:
-    TouchFromButtonDevice() {
-        const auto button_index =
-            static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
-        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),
-                std::clamp(package.Get("x", 0), 0, static_cast<int>(Layout::ScreenUndocked::Width)),
-                std::clamp(package.Get("y", 0), 0,
-                           static_cast<int>(Layout::ScreenUndocked::Height)));
-        }
-    }
-
-    Input::TouchStatus GetStatus() const override {
-        Input::TouchStatus touch_status{};
-        for (std::size_t id = 0; id < map.size() && id < touch_status.size(); ++id) {
-            const bool state = std::get<0>(map[id])->GetStatus();
-            if (state) {
-                const float x = static_cast<float>(std::get<1>(map[id])) /
-                                static_cast<int>(Layout::ScreenUndocked::Width);
-                const float y = static_cast<float>(std::get<2>(map[id])) /
-                                static_cast<int>(Layout::ScreenUndocked::Height);
-                touch_status[id] = {x, y, true};
-            }
-        }
-        return touch_status;
-    }
-
-private:
-    // A vector of the mapped button, its x and its y-coordinate
-    std::vector<std::tuple<std::unique_ptr<Input::ButtonDevice>, int, int>> map;
-};
-
-std::unique_ptr<Input::TouchDevice> TouchFromButtonFactory::Create(const Common::ParamPackage&) {
-    return std::make_unique<TouchFromButtonDevice>();
-}
-
-} // namespace InputCommon

+ 1 - 1
src/input_common/udp/client.cpp

@@ -11,7 +11,7 @@
 #include "common/logging/log.h"
 #include "common/settings.h"
 #include "input_common/udp/client.h"
-#include "input_common/udp/protocol.h"
+#include "input_common/helpers/udp_protocol.h"
 
 using boost::asio::ip::udp;