sdl_driver.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // SPDX-FileCopyrightText: 2018 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include <mutex>
  6. #include <thread>
  7. #include <unordered_map>
  8. #include <SDL.h>
  9. #include "common/common_types.h"
  10. #include "common/threadsafe_queue.h"
  11. #include "input_common/input_engine.h"
  12. union SDL_Event;
  13. using SDL_GameController = struct _SDL_GameController;
  14. using SDL_Joystick = struct _SDL_Joystick;
  15. using SDL_JoystickID = s32;
  16. namespace InputCommon {
  17. class SDLJoystick;
  18. using ButtonBindings =
  19. std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 18>;
  20. using ZButtonBindings =
  21. std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>;
  22. class SDLDriver : public InputEngine {
  23. public:
  24. /// Initializes and registers SDL device factories
  25. explicit SDLDriver(std::string input_engine_);
  26. /// Unregisters SDL device factories and shut them down.
  27. ~SDLDriver() override;
  28. void PumpEvents() const;
  29. /// Handle SDL_Events for joysticks from SDL_PollEvent
  30. void HandleGameControllerEvent(const SDL_Event& event);
  31. /// Get the nth joystick with the corresponding GUID
  32. std::shared_ptr<SDLJoystick> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id);
  33. /**
  34. * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so
  35. * tie it to a SDLJoystick with the same guid and that port
  36. */
  37. std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const Common::UUID& guid, int port);
  38. std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port);
  39. std::vector<Common::ParamPackage> GetInputDevices() const override;
  40. ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
  41. AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
  42. MotionMapping GetMotionMappingForDevice(const Common::ParamPackage& params) override;
  43. Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
  44. std::string GetHatButtonName(u8 direction_value) const override;
  45. u8 GetHatButtonId(const std::string& direction_name) const override;
  46. bool IsStickInverted(const Common::ParamPackage& params) override;
  47. Common::Input::VibrationError SetVibration(
  48. const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
  49. bool IsVibrationEnabled(const PadIdentifier& identifier) override;
  50. private:
  51. struct VibrationRequest {
  52. PadIdentifier identifier;
  53. Common::Input::VibrationStatus vibration;
  54. };
  55. void InitJoystick(int joystick_index);
  56. void CloseJoystick(SDL_Joystick* sdl_joystick);
  57. /// Needs to be called before SDL_QuitSubSystem.
  58. void CloseJoysticks();
  59. /// Takes all vibrations from the queue and sends the command to the controller
  60. void SendVibrations();
  61. Common::ParamPackage BuildAnalogParamPackageForButton(int port, const Common::UUID& guid,
  62. s32 axis, float value = 0.1f) const;
  63. Common::ParamPackage BuildButtonParamPackageForButton(int port, const Common::UUID& guid,
  64. s32 button) const;
  65. Common::ParamPackage BuildHatParamPackageForButton(int port, const Common::UUID& guid, s32 hat,
  66. u8 value) const;
  67. Common::ParamPackage BuildMotionParam(int port, const Common::UUID& guid) const;
  68. Common::ParamPackage BuildParamPackageForBinding(
  69. int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const;
  70. Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x,
  71. int axis_y, float offset_x,
  72. float offset_y) const;
  73. /// Returns the default button bindings list for generic controllers
  74. ButtonBindings GetDefaultButtonBinding() const;
  75. /// Returns the default button bindings list for nintendo controllers
  76. ButtonBindings GetNintendoButtonBinding(const std::shared_ptr<SDLJoystick>& joystick) const;
  77. /// Returns the button mappings from a single controller
  78. ButtonMapping GetSingleControllerMapping(const std::shared_ptr<SDLJoystick>& joystick,
  79. const ButtonBindings& switch_to_sdl_button,
  80. const ZButtonBindings& switch_to_sdl_axis) const;
  81. /// Returns the button mappings from two different controllers
  82. ButtonMapping GetDualControllerMapping(const std::shared_ptr<SDLJoystick>& joystick,
  83. const std::shared_ptr<SDLJoystick>& joystick2,
  84. const ButtonBindings& switch_to_sdl_button,
  85. const ZButtonBindings& switch_to_sdl_axis) const;
  86. /// Returns true if the button is on the left joycon
  87. bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
  88. /// Queue of vibration request to controllers
  89. Common::SPSCQueue<VibrationRequest> vibration_queue;
  90. /// Map of GUID of a list of corresponding virtual Joysticks
  91. std::unordered_map<Common::UUID, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
  92. std::mutex joystick_map_mutex;
  93. bool start_thread = false;
  94. std::atomic<bool> initialized = false;
  95. std::thread vibration_thread;
  96. };
  97. } // namespace InputCommon