gc_adapter.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2014 Dolphin Emulator Project
  2. // Licensed under GPLv2+
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <memory>
  7. #include <stop_token>
  8. #include <string>
  9. #include <thread>
  10. #include "input_common/input_engine.h"
  11. struct libusb_context;
  12. struct libusb_device;
  13. struct libusb_device_handle;
  14. namespace InputCommon {
  15. class LibUSBContext;
  16. class LibUSBDeviceHandle;
  17. class GCAdapter : public InputEngine {
  18. public:
  19. explicit GCAdapter(std::string input_engine_);
  20. ~GCAdapter() override;
  21. Common::Input::VibrationError SetRumble(
  22. const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
  23. /// Used for automapping features
  24. std::vector<Common::ParamPackage> GetInputDevices() const override;
  25. ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
  26. AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
  27. Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
  28. bool IsStickInverted(const Common::ParamPackage& params) override;
  29. private:
  30. enum class PadButton {
  31. Undefined = 0x0000,
  32. ButtonLeft = 0x0001,
  33. ButtonRight = 0x0002,
  34. ButtonDown = 0x0004,
  35. ButtonUp = 0x0008,
  36. TriggerZ = 0x0010,
  37. TriggerR = 0x0020,
  38. TriggerL = 0x0040,
  39. ButtonA = 0x0100,
  40. ButtonB = 0x0200,
  41. ButtonX = 0x0400,
  42. ButtonY = 0x0800,
  43. ButtonStart = 0x1000,
  44. };
  45. enum class PadAxes : u8 {
  46. StickX,
  47. StickY,
  48. SubstickX,
  49. SubstickY,
  50. TriggerLeft,
  51. TriggerRight,
  52. Undefined,
  53. };
  54. enum class ControllerTypes {
  55. None,
  56. Wired,
  57. Wireless,
  58. };
  59. struct GCController {
  60. ControllerTypes type = ControllerTypes::None;
  61. PadIdentifier identifier{};
  62. bool enable_vibration = false;
  63. u8 rumble_amplitude{};
  64. std::array<u8, 6> axis_origin{};
  65. u8 reset_origin_counter{};
  66. };
  67. using AdapterPayload = std::array<u8, 37>;
  68. void UpdatePadType(std::size_t port, ControllerTypes pad_type);
  69. void UpdateControllers(const AdapterPayload& adapter_payload);
  70. void UpdateStateButtons(std::size_t port, u8 b1, u8 b2);
  71. void UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_payload);
  72. void AdapterInputThread(std::stop_token stop_token);
  73. void AdapterScanThread(std::stop_token stop_token);
  74. bool IsPayloadCorrect(const AdapterPayload& adapter_payload, s32 payload_size);
  75. /// For use in initialization, querying devices to find the adapter
  76. bool Setup();
  77. /// Returns true if we successfully gain access to GC Adapter
  78. bool CheckDeviceAccess();
  79. /// Captures GC Adapter endpoint address
  80. /// Returns true if the endpoint was set correctly
  81. bool GetGCEndpoint(libusb_device* device);
  82. /// Returns true if there is a device connected to port
  83. bool DeviceConnected(std::size_t port) const;
  84. /// For shutting down, clear all data, join all threads, release usb
  85. void Reset();
  86. void UpdateVibrations();
  87. /// Updates vibration state of all controllers
  88. void SendVibrations();
  89. Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const;
  90. std::unique_ptr<LibUSBDeviceHandle> usb_adapter_handle;
  91. std::array<GCController, 4> pads;
  92. std::jthread adapter_input_thread;
  93. std::jthread adapter_scan_thread;
  94. bool restart_scan_thread{};
  95. std::unique_ptr<LibUSBContext> libusb_ctx;
  96. u8 input_endpoint{0};
  97. u8 output_endpoint{0};
  98. u8 input_error_counter{0};
  99. u8 output_error_counter{0};
  100. int vibration_counter{0};
  101. bool rumble_enabled{true};
  102. bool vibration_changed{true};
  103. };
  104. } // namespace InputCommon