gc_adapter.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2014 Dolphin Emulator Project
  2. // Licensed under GPLv2+
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <algorithm>
  6. #include <functional>
  7. #include <mutex>
  8. #include <thread>
  9. #include <unordered_map>
  10. #include "common/common_types.h"
  11. #include "common/threadsafe_queue.h"
  12. #include "input_common/main.h"
  13. struct libusb_context;
  14. struct libusb_device;
  15. struct libusb_device_handle;
  16. namespace GCAdapter {
  17. enum class PadButton {
  18. PAD_BUTTON_LEFT = 0x0001,
  19. PAD_BUTTON_RIGHT = 0x0002,
  20. PAD_BUTTON_DOWN = 0x0004,
  21. PAD_BUTTON_UP = 0x0008,
  22. PAD_TRIGGER_Z = 0x0010,
  23. PAD_TRIGGER_R = 0x0020,
  24. PAD_TRIGGER_L = 0x0040,
  25. PAD_BUTTON_A = 0x0100,
  26. PAD_BUTTON_B = 0x0200,
  27. PAD_BUTTON_X = 0x0400,
  28. PAD_BUTTON_Y = 0x0800,
  29. PAD_BUTTON_START = 0x1000,
  30. // Below is for compatibility with "AxisButton" type
  31. PAD_STICK = 0x2000,
  32. };
  33. extern const std::array<PadButton, 12> PadButtonArray;
  34. enum class PadAxes : u8 {
  35. StickX,
  36. StickY,
  37. SubstickX,
  38. SubstickY,
  39. TriggerLeft,
  40. TriggerRight,
  41. Undefined,
  42. };
  43. struct GCPadStatus {
  44. u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
  45. std::array<u8, 6> axis_values{}; // Triggers and sticks, following indices defined in PadAxes
  46. static constexpr u8 THRESHOLD = 50; // Threshold for axis press for polling
  47. u8 port{};
  48. PadAxes axis{PadAxes::Undefined};
  49. u8 axis_value{255};
  50. };
  51. struct GCState {
  52. std::unordered_map<int, bool> buttons;
  53. std::unordered_map<u32, u16> axes;
  54. };
  55. enum class ControllerTypes { None, Wired, Wireless };
  56. class Adapter {
  57. public:
  58. /// Initialize the GC Adapter capture and read sequence
  59. Adapter();
  60. /// Close the adapter read thread and release the adapter
  61. ~Adapter();
  62. /// Used for polling
  63. void BeginConfiguration();
  64. void EndConfiguration();
  65. std::vector<Common::ParamPackage> GetInputDevices() const;
  66. InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const;
  67. InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const;
  68. /// Returns true if there is a device connected to port
  69. bool DeviceConnected(std::size_t port) const;
  70. std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue();
  71. const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const;
  72. std::array<GCState, 4>& GetPadState();
  73. const std::array<GCState, 4>& GetPadState() const;
  74. int GetOriginValue(u32 port, u32 axis) const;
  75. private:
  76. GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload);
  77. void Read();
  78. /// Resets status of device connected to port
  79. void ResetDeviceType(std::size_t port);
  80. /// Returns true if we successfully gain access to GC Adapter
  81. bool CheckDeviceAccess(libusb_device* device);
  82. /// Captures GC Adapter endpoint address,
  83. void GetGCEndpoint(libusb_device* device);
  84. /// For shutting down, clear all data, join all threads, release usb
  85. void Reset();
  86. /// For use in initialization, querying devices to find the adapter
  87. void Setup();
  88. libusb_device_handle* usb_adapter_handle = nullptr;
  89. std::thread adapter_input_thread;
  90. bool adapter_thread_running;
  91. libusb_context* libusb_ctx;
  92. u8 input_endpoint = 0;
  93. u8 output_endpoint = 0;
  94. bool configuring = false;
  95. std::array<GCState, 4> state;
  96. std::array<bool, 4> get_origin;
  97. std::array<GCPadStatus, 4> origin_status;
  98. std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
  99. std::array<ControllerTypes, 4> adapter_controllers_status{};
  100. };
  101. } // namespace GCAdapter