diff options
Diffstat (limited to 'src/input_common/drivers')
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 23 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.h | 12 | ||||
| -rw-r--r-- | src/input_common/drivers/touch_screen.cpp | 89 | ||||
| -rw-r--r-- | src/input_common/drivers/touch_screen.h | 52 | 
4 files changed, 143 insertions, 33 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index a5c63e74a..1a14ef10b 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en              using namespace std::chrono_literals;              while (initialized) {                  SDL_PumpEvents(); +                SendVibrations();                  std::this_thread::sleep_for(1ms);              }          }); @@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble(          .type = Common::Input::VibrationAmplificationType::Exponential,      }; -    if (!joystick->RumblePlay(new_vibration)) { -        return Common::Input::VibrationError::Unknown; +    if (vibration.type == Common::Input::VibrationAmplificationType::Test) { +        if (!joystick->RumblePlay(new_vibration)) { +            return Common::Input::VibrationError::Unknown; +        } +        return Common::Input::VibrationError::None;      } +    vibration_queue.Push(VibrationRequest{ +        .identifier = identifier, +        .vibration = new_vibration, +    }); +      return Common::Input::VibrationError::None;  } +void SDLDriver::SendVibrations() { +    while (!vibration_queue.Empty()) { +        VibrationRequest request; +        vibration_queue.Pop(request); +        const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(), +                                                   static_cast<int>(request.identifier.port)); +        joystick->RumblePlay(request.vibration); +    } +} +  Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,                                                                   s32 axis, float value) const {      Common::ParamPackage params{}; diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index dcd0d1e64..c82632506 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -12,6 +12,7 @@  #include <SDL.h>  #include "common/common_types.h" +#include "common/threadsafe_queue.h"  #include "input_common/input_engine.h"  union SDL_Event; @@ -64,12 +65,20 @@ public:          const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;  private: +    struct VibrationRequest { +        PadIdentifier identifier; +        Common::Input::VibrationStatus vibration; +    }; +      void InitJoystick(int joystick_index);      void CloseJoystick(SDL_Joystick* sdl_joystick);      /// Needs to be called before SDL_QuitSubSystem.      void CloseJoysticks(); +    /// Takes all vibrations from the queue and sends the command to the controller +    void SendVibrations(); +      Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,                                                            float value = 0.1f) const;      Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, @@ -107,6 +116,9 @@ private:      /// Returns true if the button is on the left joycon      bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; +    /// Queue of vibration request to controllers +    Common::SPSCQueue<VibrationRequest> vibration_queue; +      /// Map of GUID of a list of corresponding virtual Joysticks      std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;      std::mutex joystick_map_mutex; diff --git a/src/input_common/drivers/touch_screen.cpp b/src/input_common/drivers/touch_screen.cpp index 8acbe4584..1753e0893 100644 --- a/src/input_common/drivers/touch_screen.cpp +++ b/src/input_common/drivers/touch_screen.cpp @@ -14,38 +14,93 @@ constexpr PadIdentifier identifier = {  TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) {      PreSetController(identifier); +    ReleaseAllTouch();  } -void TouchScreen::TouchMoved(float x, float y, std::size_t finger) { -    if (finger >= 16) { +void TouchScreen::TouchMoved(float x, float y, std::size_t finger_id) { +    const auto index = GetIndexFromFingerId(finger_id); +    if (!index) { +        // Touch doesn't exist handle it as a new one +        TouchPressed(x, y, finger_id);          return;      } -    TouchPressed(x, y, finger); +    const auto i = index.value(); +    fingers[i].is_active = true; +    SetButton(identifier, static_cast<int>(i), true); +    SetAxis(identifier, static_cast<int>(i * 2), x); +    SetAxis(identifier, static_cast<int>(i * 2 + 1), y);  } -void TouchScreen::TouchPressed(float x, float y, std::size_t finger) { -    if (finger >= 16) { +void TouchScreen::TouchPressed(float x, float y, std::size_t finger_id) { +    if (GetIndexFromFingerId(finger_id)) { +        // Touch already exist. Just update the data +        TouchMoved(x, y, finger_id);          return;      } -    SetButton(identifier, static_cast<int>(finger), true); -    SetAxis(identifier, static_cast<int>(finger * 2), x); -    SetAxis(identifier, static_cast<int>(finger * 2 + 1), y); +    const auto index = GetNextFreeIndex(); +    if (!index) { +        // No free entries. Ignore input +        return; +    } +    const auto i = index.value(); +    fingers[i].is_enabled = true; +    fingers[i].finger_id = finger_id; +    TouchMoved(x, y, finger_id);  } -void TouchScreen::TouchReleased(std::size_t finger) { -    if (finger >= 16) { +void TouchScreen::TouchReleased(std::size_t finger_id) { +    const auto index = GetIndexFromFingerId(finger_id); +    if (!index) {          return;      } -    SetButton(identifier, static_cast<int>(finger), false); -    SetAxis(identifier, static_cast<int>(finger * 2), 0.0f); -    SetAxis(identifier, static_cast<int>(finger * 2 + 1), 0.0f); +    const auto i = index.value(); +    fingers[i].is_enabled = false; +    SetButton(identifier, static_cast<int>(i), false); +    SetAxis(identifier, static_cast<int>(i * 2), 0.0f); +    SetAxis(identifier, static_cast<int>(i * 2 + 1), 0.0f); +} + +std::optional<std::size_t> TouchScreen::GetIndexFromFingerId(std::size_t finger_id) const { +    for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) { +        const auto& finger = fingers[index]; +        if (!finger.is_enabled) { +            continue; +        } +        if (finger.finger_id == finger_id) { +            return index; +        } +    } +    return std::nullopt; +} + +std::optional<std::size_t> TouchScreen::GetNextFreeIndex() const { +    for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) { +        if (!fingers[index].is_enabled) { +            return index; +        } +    } +    return std::nullopt; +} + +void TouchScreen::ClearActiveFlag() { +    for (auto& finger : fingers) { +        finger.is_active = false; +    } +} + +void TouchScreen::ReleaseInactiveTouch() { +    for (const auto& finger : fingers) { +        if (!finger.is_active) { +            TouchReleased(finger.finger_id); +        } +    }  }  void TouchScreen::ReleaseAllTouch() { -    for (int index = 0; index < 16; ++index) { -        SetButton(identifier, index, false); -        SetAxis(identifier, index * 2, 0.0f); -        SetAxis(identifier, index * 2 + 1, 0.0f); +    for (const auto& finger : fingers) { +        if (finger.is_enabled) { +            TouchReleased(finger.finger_id); +        }      }  } diff --git a/src/input_common/drivers/touch_screen.h b/src/input_common/drivers/touch_screen.h index 193478ead..f46036ffd 100644 --- a/src/input_common/drivers/touch_screen.h +++ b/src/input_common/drivers/touch_screen.h @@ -3,41 +3,65 @@  #pragma once +#include <optional> +  #include "input_common/input_engine.h"  namespace InputCommon {  /** - * A button device factory representing a keyboard. It receives keyboard events and forward them - * to all button devices it created. + * A touch device factory representing a touch screen. It receives touch events and forward them + * to all touch devices it created.   */  class TouchScreen final : public InputEngine {  public:      explicit TouchScreen(std::string input_engine_);      /** -     * Signals that mouse has moved. -     * @param x the x-coordinate of the cursor -     * @param y the y-coordinate of the cursor -     * @param center_x the x-coordinate of the middle of the screen -     * @param center_y the y-coordinate of the middle of the screen +     * Signals that touch has moved and marks this touch point as active +     * @param x new horizontal position +     * @param y new vertical position +     * @param finger_id of the touch point to be updated       */ -    void TouchMoved(float x, float y, std::size_t finger); +    void TouchMoved(float x, float y, std::size_t finger_id);      /** -     * Sets the status of all buttons bound with the key to pressed -     * @param key_code the code of the key to press +     * Signals and creates a new touch point with this finger id +     * @param x starting horizontal position +     * @param y starting vertical position +     * @param finger_id to be assigned to the new touch point       */ -    void TouchPressed(float x, float y, std::size_t finger); +    void TouchPressed(float x, float y, std::size_t finger_id);      /** -     * Sets the status of all buttons bound with the key to released -     * @param key_code the code of the key to release +     * Signals and resets the touch point related to the this finger id +     * @param finger_id to be released       */ -    void TouchReleased(std::size_t finger); +    void TouchReleased(std::size_t finger_id); + +    /// Resets the active flag for each touch point +    void ClearActiveFlag(); + +    /// Releases all touch that haven't been marked as active +    void ReleaseInactiveTouch();      /// Resets all inputs to their initial value      void ReleaseAllTouch(); + +private: +    static constexpr std::size_t MAX_FINGER_COUNT = 16; + +    struct TouchStatus { +        std::size_t finger_id{}; +        bool is_enabled{}; +        bool is_active{}; +    }; + +    std::optional<std::size_t> GetIndexFromFingerId(std::size_t finger_id) const; + +    std::optional<std::size_t> GetNextFreeIndex() const; + +    std::array<TouchStatus, MAX_FINGER_COUNT> fingers{};  };  } // namespace InputCommon  | 
