summaryrefslogtreecommitdiffstats
path: root/src/input_common/gcadapter/gc_adapter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/gcadapter/gc_adapter.h')
-rw-r--r--src/input_common/gcadapter/gc_adapter.h145
1 files changed, 97 insertions, 48 deletions
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index 05ee73c65..3d5c41f9a 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -8,6 +8,9 @@
#include <mutex>
#include <libusb.h>
#include "common/common_types.h"
+#include "common/threadsafe_queue.h"
+
+namespace GCAdapter {
enum {
PAD_USE_ORIGIN = 0x0080,
@@ -33,29 +36,38 @@ enum PadButton {
};
-enum PadAxes { STICK_X, STICK_Y, SUBSTICK_X, SUBSTICK_Y, TRIGGER_LEFT, TRIGGER_RIGHT };
+enum class PadAxes : u8 {
+ StickX,
+ StickY,
+ SubstickX,
+ SubstickY,
+ TriggerLeft,
+ TriggerRight,
+ Undefined,
+};
+const struct GCPadConstants {
+ const u8 MAIN_STICK_CENTER_X = 0x80;
+ const u8 MAIN_STICK_CENTER_Y = 0x80;
+ const u8 MAIN_STICK_RADIUS = 0x7f;
+ const u8 C_STICK_CENTER_X = 0x80;
+ const u8 C_STICK_CENTER_Y = 0x80;
+ const u8 C_STICK_RADIUS = 0x7f;
+
+ const u8 TRIGGER_CENTER = 20;
+ const u8 THRESHOLD = 10;
+} pad_constants;
struct GCPadStatus {
- u16 button; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
- u8 stickX; // 0 <= stickX <= 255
- u8 stickY; // 0 <= stickY <= 255
- u8 substickX; // 0 <= substickX <= 255
- u8 substickY; // 0 <= substickY <= 255
- u8 triggerLeft; // 0 <= triggerLeft <= 255
- u8 triggerRight; // 0 <= triggerRight <= 255
- bool isConnected{true};
-
- static const u8 MAIN_STICK_CENTER_X = 0x80;
- static const u8 MAIN_STICK_CENTER_Y = 0x80;
- static const u8 MAIN_STICK_RADIUS = 0x7f;
- static const u8 C_STICK_CENTER_X = 0x80;
- static const u8 C_STICK_CENTER_Y = 0x80;
- static const u8 C_STICK_RADIUS = 0x7f;
-
- static const u8 TRIGGER_CENTER = 20;
- static const u8 THRESHOLD = 10;
+ u16 button; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
+ u8 stick_x; // 0 <= stick_x <= 255
+ u8 stick_y; // 0 <= stick_y <= 255
+ u8 substick_x; // 0 <= substick_x <= 255
+ u8 substick_y; // 0 <= substick_y <= 255
+ u8 trigger_left; // 0 <= trigger_left <= 255
+ u8 trigger_right; // 0 <= trigger_right <= 255
+
u8 port;
- u8 axis_which = 255;
+ PadAxes axis = PadAxes::Undefined;
u8 axis_value = 255;
};
@@ -64,51 +76,88 @@ struct GCState {
std::unordered_map<int, u16> axes;
};
-namespace GCAdapter {
-enum ControllerTypes { CONTROLLER_NONE = 0, CONTROLLER_WIRED = 1, CONTROLLER_WIRELESS = 2 };
+enum class ControllerTypes { None, Wired, Wireless };
enum {
NO_ADAPTER_DETECTED = 0,
ADAPTER_DETECTED = 1,
};
-// Current adapter status: detected/not detected/in error (holds the error code)
-static int current_status = NO_ADAPTER_DETECTED;
+/// Singleton Adapter class
+class Adapter {
+public:
+ /// For retreiving the singleton instance
+ static Adapter* GetInstance();
+
+ /// Used for polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue();
+ std::array<GCState, 4>& GetPadState();
+
+private:
+ /// Singleton instance.
+ static Adapter* adapter_instance;
+
+ /// Initialize the GC Adapter capture and read sequence
+ Adapter();
-GCPadStatus CheckStatus(int port, u8 adapter_payload[37]);
-/// Initialize the GC Adapter capture and read sequence
-void Init();
+ /// Close the adapter read thread and release the adapter
+ ~Adapter();
-/// Close the adapter read thread and release the adapter
-void Shutdown();
+ GCPadStatus CheckStatus(int port, u8 adapter_payload[37]);
-/// Begin scanning for the GC Adapter.
-void StartScanThread();
+ void PadToState(GCPadStatus pad, GCState& state);
-/// Stop scanning for the adapter
-void StopScanThread();
+ void Read();
+ void ScanThreadFunc();
+ /// Begin scanning for the GC Adapter.
+ void StartScanThread();
-/// Returns true if there is a device connected to port
-bool DeviceConnected(int port);
+ /// Stop scanning for the adapter
+ void StopScanThread();
-/// Resets status of device connected to port
-void ResetDeviceType(int port);
+ /// Returns true if there is a device connected to port
+ bool DeviceConnected(int port);
-/// Returns true if we successfully gain access to GC Adapter
-bool CheckDeviceAccess(libusb_device* device);
+ /// Resets status of device connected to port
+ void ResetDeviceType(int port);
-/// Captures GC Adapter endpoint address,
-void GetGCEndpoint(libusb_device* device);
+ /// Returns true if we successfully gain access to GC Adapter
+ bool CheckDeviceAccess(libusb_device* device);
-/// For shutting down, clear all data, join all threads, release usb
-void Reset();
+ /// Captures GC Adapter endpoint address,
+ void GetGCEndpoint(libusb_device* device);
-/// For use in initialization, querying devices to find the adapter
-void Setup();
+ /// For shutting down, clear all data, join all threads, release usb
+ void Reset();
-/// Used for polling
-void BeginConfiguration();
+ /// For use in initialization, querying devices to find the adapter
+ void Setup();
-void EndConfiguration();
+ int current_status = NO_ADAPTER_DETECTED;
+ libusb_device_handle* usb_adapter_handle = nullptr;
+ ControllerTypes adapter_controllers_status[4] = {ControllerTypes::None, ControllerTypes::None,
+ ControllerTypes::None, ControllerTypes::None};
+
+ std::mutex s_mutex;
+
+ std::thread adapter_input_thread;
+ bool adapter_thread_running;
+
+ std::mutex initialization_mutex;
+ std::thread detect_thread;
+ bool detect_thread_running = false;
+
+ libusb_context* libusb_ctx;
+
+ u8 input_endpoint = 0;
+
+ bool configuring = false;
+
+ std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
+ std::array<GCState, 4> state;
+};
} // end of namespace GCAdapter