Core Interfaces and Data Types
Core Interfaces
Section titled “Core Interfaces”Gamepad Template Base Class
Section titled “Gamepad Template Base Class”Gamepad<KeysType> is the template base class for all gamepads, responsible for UDP data receiving thread management and callback mechanisms.
Construction Example
Section titled “Construction Example”Gamepad(int port = kDefaultPort); ///< Specify UDP listening port, default 12121Main Interfaces
Section titled “Main Interfaces”void StartDataThread(); ///< Start data receiving threadvoid StopDataThread(); ///< Stop data receiving threadKeysType& GetKeys(); ///< Get latest button data (thread-safe)void SetUpdateCallback(const std::function<void(uint32_t)>& cb); ///< Register data update callbackuint16_t CalculateCrc16(const uint8_t* data, size_t length); ///< CRC-16 checksum calculationCallback Mechanism
Section titled “Callback Mechanism”Each time valid data is received and buttons are updated, the SDK calls the registered callback function with the cumulative update count as parameter:
rc.SetUpdateCallback([](uint32_t count) { // count is the number of valid data updates since startup});You can also directly assign the updateCallback_ member:
rc.updateCallback_ = [&](uint32_t count) { std::cout << "update count: " << count << std::endl;};Retroid Gamepad Implementation
Section titled “Retroid Gamepad Implementation”RetroidGamepad inherits Gamepad<RetroidKeys> and is the concrete implementation for the Retroid gamepad.
Construction Example
Section titled “Construction Example”RetroidGamepad rc(12121); ///< Create Retroid gamepad instance, listening on port 12121rc.StartDataThread(); ///< Start data receivingData Reading Example
Section titled “Data Reading Example”RetroidKeys keys = rc.GetKeys();std::cout << "A button: " << keys.A << std::endl;std::cout << "Left axis X: " << keys.left_axis_x << std::endl;Skydroid Gamepad Implementation
Section titled “Skydroid Gamepad Implementation”SkydroidGamepad inherits Gamepad<SkydroidKeys> and is the concrete implementation for the Skydroid gamepad.
Construction Example
Section titled “Construction Example”SkydroidGamepad rc(12121); ///< Create Skydroid gamepad instance, listening on port 12121rc.StartDataThread(); ///< Start data receivingData Reading Example
Section titled “Data Reading Example”SkydroidKeys keys = rc.GetKeys();std::cout << "A button: " << keys.A << std::endl;std::cout << "SW1: " << keys.sw1 << std::endl;UDP Receiver
Section titled “UDP Receiver”UdpReceiver encapsulates the low-level UDP Socket creation, binding, and receiving logic.
Interface Example
Section titled “Interface Example”UdpReceiver receiver(12121); ///< Create and bind portstd::vector<uint8_t> data = receiver.ReceiveData(); ///< Block and receive one frame of dataReceiveData() is a blocking call that returns raw bytes when a UDP packet is received.
Data Type Definitions
Section titled “Data Type Definitions”All data types are defined in gamepad_keys.h.
RetroidKeys — Retroid Gamepad Button Data
Section titled “RetroidKeys — Retroid Gamepad Button Data”struct RetroidKeys { double time_stamp; ///< Timestamp (ms, relative to startup time) union { uint16_t value; ///< Bitmask of all buttons struct { uint8_t R1 : 1; uint8_t L1 : 1; uint8_t start : 1; uint8_t select : 1; uint8_t R2 : 1; uint8_t L2 : 1; uint8_t A : 1; uint8_t B : 1; uint8_t X : 1; uint8_t Y : 1; uint8_t left : 1; uint8_t right : 1; uint8_t up : 1; uint8_t down : 1; uint8_t left_axis_button : 1; uint8_t right_axis_button : 1; }; }; union { float axis_values[4]; struct { float left_axis_x; ///< Left joystick X axis (-1.0 ~ 1.0) float left_axis_y; ///< Left joystick Y axis (-1.0 ~ 1.0) float right_axis_x; ///< Right joystick X axis (-1.0 ~ 1.0) float right_axis_y; ///< Right joystick Y axis (-1.0 ~ 1.0) }; };};SkydroidKeys — Skydroid Gamepad Button Data
Section titled “SkydroidKeys — Skydroid Gamepad Button Data”struct SkydroidKeys { double time_stamp; ///< Timestamp (ms, relative to startup time) union { uint8_t keys_value; struct { uint8_t C : 1; uint8_t right : 1; uint8_t D : 1; uint8_t E : 1; uint8_t F : 1; uint8_t reserved : 1; uint8_t A : 1; uint8_t B : 1; }; }; union { uint8_t switch_keys[4]; struct { uint8_t sw1; ///< Toggle switch 1 uint8_t sw2; ///< Toggle switch 2 uint8_t sw3; ///< Toggle switch 3 uint8_t sw4; ///< Toggle switch 4 }; }; union { float axis_values[4]; struct { float left_axis_x; ///< Left joystick X axis (-1.0 ~ 1.0) float left_axis_y; ///< Left joystick Y axis (-1.0 ~ 1.0) float right_axis_x; ///< Right joystick X axis (-1.0 ~ 1.0) float right_axis_y; ///< Right joystick Y axis (-1.0 ~ 1.0) }; };};Button Value Description
Section titled “Button Value Description”| Value | Meaning |
|---|---|
0 | Button released (KeyStatus::kReleased) |
1 | Button pressed (KeyStatus::kPressed) |
Joystick Value Description
Section titled “Joystick Value Description”Raw joystick data ranges from -1000 ~ 1000. The SDK divides by kJoystickRange (1000) internally to normalize to -1.0 ~ 1.0 floating-point values.
| Direction | Minimum | Maximum |
|---|---|---|
| X axis | -1.0 (far left) | 1.0 (far right) |
| Y axis | -1.0 (far bottom) | 1.0 (far top) |
Retroid Gamepad Button Layout
Section titled “Retroid Gamepad Button Layout”| Button | Description |
|---|---|
A / B / X / Y | Four action buttons |
L1 / R1 | Left/right shoulder buttons |
L2 / R2 | Left/right trigger buttons |
start / select | Start/select buttons |
up / down / left / right | Directional pad |
left_axis_button / right_axis_button | Left/right joystick press |
Skydroid Gamepad Button Layout
Section titled “Skydroid Gamepad Button Layout”| Button | Description |
|---|---|
A / B / C / D / E / F | Action buttons |
right | Directional pad (right) |
sw1 / sw2 / sw3 / sw4 | Four toggle switches |
Protocol Frame Structure
Section titled “Protocol Frame Structure”RetroidGamepadData
Section titled “RetroidGamepadData”struct RetroidGamepadData { uint8_t stx[2]; ///< Frame header 0x55 0x66 uint8_t ctrl; ///< Control byte uint16_t data_len; ///< Data area length uint16_t seq; ///< Sequence number uint8_t id; ///< Device ID (1 = Retroid) uint16_t crc16; ///< CRC-16 checksum union { uint8_t data[32]; ///< Raw data area struct { uint16_t buttons[10]; ///< 10 button channels int16_t left_axis_x; ///< Left joystick X int16_t left_axis_y; ///< Left joystick Y int16_t right_axis_x; ///< Right joystick X int16_t right_axis_y; ///< Right joystick Y uint16_t axis_buttons[2]; ///< Joystick buttons }; };};SkydroidGamepadData
Section titled “SkydroidGamepadData”struct SkydroidGamepadData { uint8_t stx[2]; ///< Frame header 0x55 0x66 uint8_t ctrl; ///< Control byte uint16_t data_len; ///< Data area length uint16_t seq; ///< Sequence number uint8_t id; ///< Device ID (2 = Skydroid) uint16_t crc16; ///< CRC-16 checksum union { uint8_t data[32]; ///< Raw data area struct { int16_t right_axis_x; ///< Right joystick X int16_t right_axis_y; ///< Right joystick Y int16_t left_axis_y; ///< Left joystick Y int16_t left_axis_x; ///< Left joystick X uint16_t switch_keys[4]; ///< 4 toggle switches uint16_t buttons[8]; ///< 8 button channels }; };};Note: The joystick data ordering in the protocol frame differs between the two gamepads. The SDK handles the mapping automatically.