3DS掌机 InputRedirection 报文协议

InputRedirection 是 Luma3DS 的 Rosalina menu 中的一个功能,允许你将控制器输入重定向至3DS,从而实现3DS外接手柄的功能。
 InputRedirectionClient-Qt 使用 QtGamepad 对 3DS 进行输入重定向客户端操作,用这个软件可以让手柄连接电脑,电脑再通过网络控制3DS。
 以下信息由AI解析  InputRedirectionClient-Qt 中的 sendFrame 函数而得,可能信息不准确,报文示例中已手动验证过。

1. 传输层信息

  • 传输协议:UDP

  • 目标端口:4950(3DS 端默认监听的输入重定向端口)

  • 数据包长度:固定 20 字节(QByteArray ba(20, 0))

  • 字节序:小端序(Little-Endian,使用 qToLittleEndian 写入)


2. 报文结构总览(Offset 0~19)

偏移量 (Byte) 长度 (Byte) 字段名 说明
0 4 hidPad 标准按键状态(ABXY、十字键、LR、Start/Select)
4 4 touchScreenState 触摸屏状态(含坐标)
8 4 circlePadState 左摇杆(Circle Pad)状态(含坐标)
12 4 cppState 右摇杆(C-Stick / New 3DS) + IR 按钮状态
16 4 interfaceButtons 扩展界面按钮(自定义标志位/元数据)

3. 字段详细解析

字段 1:hidPad(4 字节,32 位)

  • 初始值:0x00000FFF(即低 12 位全为 1)。

  • 逻辑:低电平有效(按下的按钮会将对应的位清零,未按下保持为 1)。

  • 位映射表(低位在前,Bit 0~11):

Bit 默认按钮
0 A
1 B
2 SELECT 键
3 START 键
4 十字键 →(右)
5 十字键 ←(左)
6 十字键 ↑(上)
7 十字键 ↓(下)
8 R 键
9 L 键
10 X
11 Y
12~31 保留 / 未使用

字段 2:touchScreenState(4 字节,32 位)

  • 默认值(未触摸):0x02000000(二进制 Bit 25 置位)。

  • 方向:触摸屏左上角为原点,向下为+Y,向右为+X 。

  • 触摸时构造:(1 << 24) | (Y << 12) | X

    • Bit 24:触摸标志(1 表示正在触摸)。注意触摸后 Bit 25 应被自动清零。

    • Bit 25:未触摸标志(1表示未触摸)。此时 Bit 24 应清零。

    • Bits 23 ~ 12:Y 坐标(12 位有效,范围 0x000 ~ 0xFFF,对应屏幕高度)。

    • Bits 11 ~ 0:X 坐标(12 位有效,范围 0x000 ~ 0xFFF,对应屏幕宽度)。


字段 3:circlePadState(4 字节,32 位)

  • 默认值(回中):0x007FF7FF

  • 方向: 向右为+X,向上为+Y。

  • 坐标计算:(Y << 12) | X

    • X 坐标:低 12 位(Bits 11~0),范围 0x000 ~ 0xFFF,中心值 7FF (左负右正,映射自 lx)。

    • Y 坐标:高 12 位(Bits 23~12),范围 0x000 ~ 0xFFF,中心值 7FF(下负上正,映射自 ly)。


字段 4:cppState(4 字节,32 位)—— New 3DS 右摇杆 + IR 按钮

  • 默认值:0x80800081。

  • 构造公式:(Y << 24) | (X << 16) | (IR_Buttons << 8) | 0x81

  • 按小端序存储后的字节分解(非常重要):

偏移 + 0 (Byte 12) 偏移 + 1 (Byte 13) 偏移 + 2 (Byte 14) 偏移 + 3 (Byte 15)
0x81 (常量标识) IR 按钮状态 (bits 1~2) X 坐标 (8位) Y 坐标 (8位)
  • 坐标细节:

    • X 和 Y 为 8 位无符号数(范围 0x00 ~ 0xFF),中心值为 0x80(128)。

    • 特殊处理:代码中刻意将物理输入顺时针旋转了 45°,这是为了匹配 3DS 系统对 C-Stick 的原始硬件映射。

  • IR 按钮:IR_Buttons 占用 Bit 1 和 Bit 2,左移 8 位后存放在 Byte 13 的低 2 位,置1为有效。Bit 1 = ZR 按下;Bit 2 = ZL 按下。


字段 5:interfaceButtons(4 字节,32 位)

  • 默认值:0x00000000。

  • 逻辑:高电平有效(按下的按钮会将对应的位置1,未按下保持为 0)。

  • 位映射表(低位在前,Bit 0~11):

Bit 默认按钮
0 HOME
1 电源键
2 电源键(长按)

4. 关键特殊逻辑总结(供 PC 模拟端参考)

  1. AB / XY 反转:代码支持动态交换 A/B 和 X/Y 键位,适配不同地区手柄习惯。

  2. C-Stick 旋转:发送给 3DS 的 C-Stick 数据必须预先进行 45° 旋转变换,否则方向会在游戏中错乱。

  3. 触摸默认值:未触摸时 Bit 25 为 1(0x2000000),触摸后 Bit 24 为 1 且 Bit 25 为 0,请勿搞反。

  4. 摇杆死区:坐标超出边界(如 > 0xFFF)会被钳位到边界值(0 或 0xFFF)。

如果您需要基于此协议编写 PC 端发送程序,只需按照上述小端序填充这 20 个字节,并通过 UDP 发送至 3DS 的 IP 地址即可。

5. 报文示例

已验证(20260704)
释放所有按键(默认包):

FF0F000000000002FFF77F008100808000000000

ABXY 按键:

// A
FE0F000000000002FFF77F008100808000000000
// B
FD0F000000000002FFF77F008100808000000000
// X
FF0B000000000002FFF77F008100808000000000
// Y
FF07000000000002FFF77F008100808000000000

十字键:

// 上
BF0F000000000002FFF77F008100808000000000
// 下
7F0F000000000002FFF77F008100808000000000
// 左
DF0F000000000002FFF77F008100808000000000
// 右
EF0F000000000002FFF77F008100808000000000

肩键:

// L
FF0D000000000002FFF77F008100808000000000
// ZL
FF0F000000000002FFF77F008104808000000000
// R
FF0E000000000002FFF77F008100808000000000
// ZR
FF0F000000000002FFF77F008102808000000000

左摇杆(上下左右):

// 上
FF0F000000000002FFF7FF008100808000000000
// 下
FF0F000000000002FFF70F008100808000000000
// 左
FF0F000000000002FFF07F008100808000000000
// 右
FF0F000000000002FFFF7F008100808000000000

右摇杆(上下左右):

// 上
FF0F000000000002FFF77F008100FFFF00000000
// 下
FF0F000000000002FFF77F008100000000000000
// 左
FF0F000000000002FFF77F00810000FF00000000
// 右
FF0F000000000002FFF77F008100FF0000000000

触摸屏:

// 左上角
FF0F000000000001FFF77F008100808000000000
// 右上角
FF0F0000FF0F0001FFF77F008100808000000000
// 左下角
FF0F000000F0FF01FFF77F008100808000000000
// 右下角
FF0F0000FFFFFF01FFF77F008100808000000000 

SELECT 和 START:

FB0F000000000002FFF77F008100808000000000
F70F000000000002FFF77F008100808000000000

特殊键:

// HOME
FF0F000000000002FFF77F008100808001000000
// 电源键
FF0F000000000002FFF77F008100808002000000
// 电源键(长按)
FF0F000000000002FFF77F008100808004000000

3DS上按住 L+DOWN+SELECT 进如 Rosalina menu, 连接 WiFi 后在 Miscellaneous options 中开启 Start InputRedirection,提示 OK 开启成功。
3DS 打开 3DSident 软件,在 Exit 页面中同时按 L+R 可以进入按键测试页面。
打开 netassist,复制相应的报文,粘贴到 UDP 调试工具的 HEX 发送框中,设置好 IP 和 端口,发送报文即可验证效果。
以下文本复制到一个 cfg 文件中,打开 netassist 右边的工具面板,在快捷指令中右键导入 cfg 文件,即可快捷发送报文。

[SHORTCUT]
释放按键=1|0|0|FF0F000000000002FFF77F008100808000000000
A=1|0|1|FE0F000000000002FFF77F008100808000000000
B=1|0|2|FD0F000000000002FFF77F008100808000000000
X=1|0|3|FF0B000000000002FFF77F008100808000000000
Y=1|0|4|FF07000000000002FFF77F008100808000000000
上=1|0|5|BF0F000000000002FFF77F008100808000000000
下=1|0|6|7F0F000000000002FFF77F008100808000000000
左=1|0|7|DF0F000000000002FFF77F008100808000000000
右=1|0|8|EF0F000000000002FFF77F008100808000000000
L=1|0|9|FF0D000000000002FFF77F008100808000000000
ZL=1|0|10|FF0F000000000002FFF77F008104808000000000
R=1|0|11|FF0E000000000002FFF77F008100808000000000
ZR=1|0|12|FF0F000000000002FFF77F008102808000000000
左摇杆上=1|0|13|FF0F000000000002FFF7FF008100808000000000
左摇杆下=1|0|14|FF0F000000000002FF0700008100808000000000
左摇杆左=1|0|15|FF0F00000000000200F07F008100808000000000
左摇杆右=1|0|16|FF0F000000000002FFFF7F008100808000000000
右摇杆上=1|0|17|FF0F000000000002FFF77F008100FFFF00000000
右摇杆下=1|0|18|FF0F000000000002FFF77F008100000000000000
右摇杆左=1|0|19|FF0F000000000002FFF77F00810000FF00000000
右摇杆右=1|0|20|FF0F000000000002FFF77F008100FF0000000000
触摸左上角=1|0|21|FF0F000000000001FFF77F008100808000000000
触摸右上角=1|0|22|FF0F0000FF0F0001FFF77F008100808000000000
触摸左下角=1|0|23|FF0F000000F0FF01FFF77F008100808000000000
触摸右下角=1|0|24|FF0F0000FFFFFF01FFF77F008100808000000000
SELECT=1|0|25|FB0F000000000002FFF77F008100808000000000
START=1|0|26|F70F000000000002FFF77F008100808000000000
HOME=1|0|27|FF0F000000000002FFF77F008100808001000000
POWER=1|0|28|FF0F000000000002FFF77F008100808002000000
POWER LONG=1|0|29|FF0F000000000002FFF77F008100808004000000

image

image

posted @ 2026-06-23 20:25  newdio  阅读(22)  评论(0)    收藏  举报