rob*_*nes 7 c linux input gamepad
我正在开发一个C语言程序,它使用USB SNES控制器输入基于RPM的分发.是否存在任何人都知道的库使得这更容易与之交互,或者某些工具(joydev?)允许从设备中正确读取输入?我不需要整个游戏引擎; 它仅用于来自角色设备的输入.
如果有一个库已经为我做了这个,那将是非常好的(我可以看看库自己做了什么),这可以通过一个链接关闭; 否则,如果我必须自己这样做,我有几个具体的问题:
简而言之,pseduo-C,这样的事情?
struct gamepad {
int fd;
};
void get_input(struct gamepad *gamepad)
{
char *buf;
read(gamepad->fd, buf, 48);
switch(buf)
{
/* insert cases about handling differing buttons */
}
}
Run Code Online (Sandbox Code Playgroud)
据我所见,我可以清楚地看到设备正确注册:
$ dmesg | tail
[198564.517068] usb 1-1: USB disconnect, device number 17
[198566.154324] usb 1-1: new low-speed USB device number 18 using xhci_hcd
[198566.323309] usb 1-1: New USB device found, idVendor=12bd, idProduct=d015
[198566.323312] usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[198566.323313] usb 1-1: Product: 2Axes 11Keys Game Pad
[198566.323792] usb 1-1: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 microframes
[198566.328692] input: 2Axes 11Keys Game Pad as /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/input/input20
[198566.329036] hid-generic 0003:12BD:D015.0006: input,hidraw2: USB HID v1.10 Gamepad [2Axes 11Keys Game Pad] on usb-0000:00:14.0-1/input0
Run Code Online (Sandbox Code Playgroud)
如果我从设备读取,我可以看到它接收到一个中断并且设备输入只是使用hexdump:
$ ls -lattr /dev/input/by-id/usb-12bd_2Axes_11Keys_Game_Pad-event-joystick
lrwxrwxrwx. 1 root root 10 Jan 20 15:56 /dev/input/by-id/usb-12bd_2Axes_11Keys_Game_Pad-event-joystick -> ../event17
Run Code Online (Sandbox Code Playgroud)
当我按下一个键(不释放)时,它看起来像预期的那样工作,虽然我无法解释从没有上下文的缓冲区返回的内容:
$ hexdump /dev/input/event17
0000000 f53a 569f 0000 0000 ac6c 000c 0000 0000
0000010 0003 0000 007f 0000 f53a 569f 0000 0000
0000020 ac6c 000c 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
在释放按钮时,您会收到类似的输出:
0000030 f53c 569f 0000 0000 8be3 0007 0000 0000
0000040 0003 0001 007f 0000 f53c 569f 0000 0000
0000050 8be3 0007 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
这就是上方按下并释放的"向上"按钮.
为了确定其他库如何做到这一点,我想pygame在python中做一个strace 并查看它打开的设备以及它如何读取输入,但我仍在学习如何使用它.我还看到了一些关于joydev的模糊提及,但是,再一次,还没有学会如何使用它们.我现在正在这样做,如果我学到任何有价值的东西,我会发布结果.
除此之外,通过ASCII和hexdump观看按钮按下,我注意到他们有一个基于按钮的类似输入,但似乎我想的是上面输出结束时USB总线的中断计数(0xf53a到0xf53c).这似乎总是增加,并且,为了我的目的,可能会被丢弃.
还有可能我只是没有正确安装设备,因为我缺少一些模块或包(再次考虑一下joydev以及它应该做什么).我根本没有经常使用USB,所以这种类型的设备处理对我来说是新的.
搜索一下,我没有看到任何显示我正在寻找的东西,但我很乐意接受重定向到其他问题/主题阅读.
先感谢您!
Linux 中的 USB 输入设备通常由 HID 驱动程序(人机接口设备)处理,然后将其转换为输入设备。
您可以将它们作为原始 USB 设备读取,但这通常不是一个好主意,因为它是一个非常低级的协议。
/dev/input/*如果您有适当的权限,您可以读取设备。通常它们只能由 root 读取。如果您不想读取原始字节,则有一些库(例如libinput)可以为您完成这项工作。
但是如果您的游戏在 XWindows 中运行(最有可能),那么您应该管理 XInput 设备。您可以使用原始 X 调用来做到这一点,但使用一些库(例如SDL )可能会更好。实际上 SDL 是pygame在幕后使用的,所以我会先尝试一下。
关于如何识别正确的设备,每个输入设备都有一个名称,有些甚至有一个序列号(你看到那些作为符号链接的/dev/input/by-id这些通常足以识别设备,而不是输入编号。
如果你想阅读原始输入设备,让我解释一下你的十六进制转储。您正在读取input*设备,因此您将获得类型值struct input_event(请参阅 参考资料/usr/include/linux/input.h):
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
Run Code Online (Sandbox Code Playgroud)
例如,在您的第一个转储中:
0000000 f53a 569f 0000 0000 ac6c 000c 0000 0000
0000010 0003 0000 007f 0000 f53a 569f 0000 0000
0000020 ac6c 000c 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
实际上有两个input_events。第一个是:
f53a 569f 0000 0000 ac6c 000c 0000 0000 0003 0000 007f 0000
Run Code Online (Sandbox Code Playgroud)
前 64 个字节是时间戳。然后,0003 (EV_ABS)表示绝对轴的移动,0000 (ABS_X)是轴索引,是该轴0000007f的位置。绝对轴有时用于表示油门、操纵杆等(有时键盘作为操纵杆而不是 4 个按钮发送),并且您在第一次读取时就知道控件的位置,即使您不移动它。
第二个事件是:
f53a 569f 0000 0000 ac6c 000c 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
前 64 字节是时间戳(同上。then0000 (EV_SYN)表示同步事件。带EV_SYN,其他字段未使用。EV_SYN用于将单个事件的不同值组合在一起,例如鼠标的水平和垂直轴或操纵杆。
您的另一个转储类似,但对于AXIS_Y.
我的猜测是键盘被视为数字操纵杆,两个轴ABS_X和ABS_Y,作为0x7F中间点(范围从0x00到0xFF)。您收到的消息只是中间点,即没有按下键盘按钮。也许您的hexdump输出正在缓冲?
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |