核心接口与数据类型
手柄模板基类
Section titled “手柄模板基类”Gamepad<KeysType> 是所有手柄的模板基类,负责 UDP 数据接收线程管理和回调机制。
Gamepad(int port = kDefaultPort); ///< 指定 UDP 监听端口,默认 12121void StartDataThread(); ///< 启动数据接收线程void StopDataThread(); ///< 停止数据接收线程KeysType& GetKeys(); ///< 获取最新按键数据(线程安全)void SetUpdateCallback(const std::function<void(uint32_t)>& cb); ///< 注册数据更新回调uint16_t CalculateCrc16(const uint8_t* data, size_t length); ///< CRC-16 校验计算每次收到有效数据并更新按键后,SDK 会调用注册的回调函数,参数为累计更新次数:
rc.SetUpdateCallback([](uint32_t count) { // count 为自启动以来的有效数据更新次数});也可以直接赋值 updateCallback_ 成员:
rc.updateCallback_ = [&](uint32_t count) { std::cout << "update count: " << count << std::endl;};Retroid 手柄实现
Section titled “Retroid 手柄实现”RetroidGamepad 继承 Gamepad<RetroidKeys>,是 Retroid 手柄的具体实现。
RetroidGamepad rc(12121); ///< 创建 Retroid 手柄实例,监听 12121 端口rc.StartDataThread(); ///< 启动数据接收数据读取示例
Section titled “数据读取示例”RetroidKeys keys = rc.GetKeys();std::cout << "A button: " << keys.A << std::endl;std::cout << "Left axis X: " << keys.left_axis_x << std::endl;Skydroid 手柄实现
Section titled “Skydroid 手柄实现”SkydroidGamepad 继承 Gamepad<SkydroidKeys>,是 Skydroid 手柄的具体实现。
SkydroidGamepad rc(12121); ///< 创建 Skydroid 手柄实例,监听 12121 端口rc.StartDataThread(); ///< 启动数据接收数据读取示例
Section titled “数据读取示例”SkydroidKeys keys = rc.GetKeys();std::cout << "A button: " << keys.A << std::endl;std::cout << "SW1: " << keys.sw1 << std::endl;UDP 接收器
Section titled “UDP 接收器”UdpReceiver 封装了底层 UDP Socket 的创建、绑定和接收逻辑。
UdpReceiver receiver(12121); ///< 创建并绑定端口std::vector<uint8_t> data = receiver.ReceiveData(); ///< 阻塞接收一帧数据ReceiveData() 为阻塞调用,直到收到一个 UDP 数据包后返回原始字节流。
数据类型定义
Section titled “数据类型定义”所有数据类型定义在 gamepad_keys.h 中。
RetroidKeys — Retroid 手柄按键数据
Section titled “RetroidKeys — Retroid 手柄按键数据”struct RetroidKeys { double time_stamp; ///< 时间戳(ms,相对于启动时间) union { uint16_t value; ///< 所有按键的位掩码 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; ///< 左摇杆 X 轴(-1.0 ~ 1.0) float left_axis_y; ///< 左摇杆 Y 轴(-1.0 ~ 1.0) float right_axis_x; ///< 右摇杆 X 轴(-1.0 ~ 1.0) float right_axis_y; ///< 右摇杆 Y 轴(-1.0 ~ 1.0) }; };};SkydroidKeys — Skydroid 手柄按键数据
Section titled “SkydroidKeys — Skydroid 手柄按键数据”struct SkydroidKeys { double time_stamp; ///< 时间戳(ms,相对于启动时间) 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; ///< 拨动开关 1 uint8_t sw2; ///< 拨动开关 2 uint8_t sw3; ///< 拨动开关 3 uint8_t sw4; ///< 拨动开关 4 }; }; union { float axis_values[4]; struct { float left_axis_x; ///< 左摇杆 X 轴(-1.0 ~ 1.0) float left_axis_y; ///< 左摇杆 Y 轴(-1.0 ~ 1.0) float right_axis_x; ///< 右摇杆 X 轴(-1.0 ~ 1.0) float right_axis_y; ///< 右摇杆 Y 轴(-1.0 ~ 1.0) }; };};| 值 | 含义 |
|---|---|
0 | 按键松开(KeyStatus::kReleased) |
1 | 按键按下(KeyStatus::kPressed) |
摇杆数值说明
Section titled “摇杆数值说明”摇杆原始数据范围为 -1000 ~ 1000,SDK 内部除以 kJoystickRange(1000)后归一化为 -1.0 ~ 1.0 的浮点数。
| 方向 | 最小值 | 最大值 |
|---|---|---|
| X 轴 | -1.0(最左) | 1.0(最右) |
| Y 轴 | -1.0(最下) | 1.0(最上) |
Retroid 手柄按键布局
Section titled “Retroid 手柄按键布局”| 按键 | 说明 |
|---|---|
A / B / X / Y | 四动作按钮 |
L1 / R1 | 左/右肩键 |
L2 / R2 | 左/右扳机键 |
start / select | 开始/选择键 |
up / down / left / right | 方向键 |
left_axis_button / right_axis_button | 左/右摇杆按下 |
Skydroid 手柄按键布局
Section titled “Skydroid 手柄按键布局”| 按键 | 说明 |
|---|---|
A / B / C / D / E / F | 动作按钮 |
right | 方向键(右) |
sw1 / sw2 / sw3 / sw4 | 四路拨动开关 |
RetroidGamepadData
Section titled “RetroidGamepadData”struct RetroidGamepadData { uint8_t stx[2]; ///< 帧头 0x55 0x66 uint8_t ctrl; ///< 控制字节 uint16_t data_len; ///< 数据区长度 uint16_t seq; ///< 序列号 uint8_t id; ///< 设备 ID(1 = Retroid) uint16_t crc16; ///< CRC-16 校验 union { uint8_t data[32]; ///< 原始数据区 struct { uint16_t buttons[10]; ///< 10 个按键通道 int16_t left_axis_x; ///< 左摇杆 X int16_t left_axis_y; ///< 左摇杆 Y int16_t right_axis_x; ///< 右摇杆 X int16_t right_axis_y; ///< 右摇杆 Y uint16_t axis_buttons[2]; ///< 摇杆按键 }; };};SkydroidGamepadData
Section titled “SkydroidGamepadData”struct SkydroidGamepadData { uint8_t stx[2]; ///< 帧头 0x55 0x66 uint8_t ctrl; ///< 控制字节 uint16_t data_len; ///< 数据区长度 uint16_t seq; ///< 序列号 uint8_t id; ///< 设备 ID(2 = Skydroid) uint16_t crc16; ///< CRC-16 校验 union { uint8_t data[32]; ///< 原始数据区 struct { int16_t right_axis_x; ///< 右摇杆 X int16_t right_axis_y; ///< 右摇杆 Y int16_t left_axis_y; ///< 左摇杆 Y int16_t left_axis_x; ///< 左摇杆 X uint16_t switch_keys[4]; ///< 4 路拨动开关 uint16_t buttons[8]; ///< 8 个按键通道 }; };};注意: 两种手柄的摇杆数据在协议帧中的排列顺序不同,SDK 内部已自动处理映射。