摘要:在淘宝上买到的游戏手柄/USB卖家只给了Windows下的驱动,本来以为Ubuntu下没有驱动,没想到网上早已经有人用cpp开发出了USB手柄的驱动,搜索很多博客的方法终于从手柄拿到数据。
Linux真给力!!
cat 是一个文本文件查看和连接工具。查看一个文件的内容,用cat比较简单,就是cat 后面直接接文件名,如cat linuxyw.txt
cat –help可以查看cat帮助信息,如各种参数使用方法,当然也可以用man cat来查看,建议大家养成遇到命令不懂用法时,用–help或man来查看帮助信息,养成好习惯。filename为文件名,即系统中需要查看的文件名字。
与这个命令相似功能的命令有:tac,less,tail,more
options:
-b:--number-nonblank 对非空输出行编号,即在每行前显示所在行号
-n:--number 对输出的所有行编号,即在每行前显示所在行号
注:cat命令
hexdump命令一般用来查看“二进制”文件的十六进制编码,但实际上它能查看任何文件,而不只限于二进制文件。
hexdump [选项] [文件]...
options:
-n length 只格式化输入文件的前length个字节。
-C 输出规范的十六进制和ASCII码。
-b 单字节八进制显示。
-c 单字节字符显示。
-d 双字节十进制显示。
-o 双字节八进制显示。
-x 双字节十六进制显示。
-s 从偏移量开始输出。
-e 指定格式字符串,格式字符串包含在一对单引号中,格式字符串形如:'a/b "format1" "format2"'。
注:hexdump命令
在插入设备时,linux系统会使用input子系统,操作系统会为每一个设备分配event号,先插上的为event0,后插上的为event1,首先获取linux系统为游戏手柄分配的event号。
当游戏手柄插入电脑时,需要找到手柄的even号:
cat /proc/bus/input/devices
注:或者可以使用>
将输出写入一个txt文档
cat /proc/bus/input/devices >log1.txt
获得如下输出
I: Bus=0003 Vendor=11ff Product=001c Version=0111
N: Name="PXN-V3II"
P: Phys=usb-0000:00:14.0-11/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11:1.0/0003:11FF:001C.0009/input/input29
U: Uniq=
H: Handlers=event21 js0
B: PROP=0
B: EV=1b
B: KEY=1fff000000000000 0 0 0 0
B: ABS=30027
B: MSC=10
在端口处找到设备名字“PXN-V3II”,event21/js0我们的手柄的接口。
开始的时候有时候找不到,是手柄中的版本不对,根据产品说明书需要由X-input转换到D-input模式。(长按home键3秒)
X -input适用于XBOX360移植到PC上的即插即玩的游戏,D-input适用于早期单机游戏如极品飞车1-12等。——要不是要在unbuntu下开发哪来这么多幺蛾子。。。
查看输入
ls /dev/input
可以看见js0和event21,使用以下代码查看端口输出:
cat /dev/input/js0 | hexdump
或
cat /dev/input/event21 | hexdump
测试手柄命令
jstest /dev/input/js0
参照参考3,新建文件夹与cpp文件,实现jstest功能:
cpp文件建立执行参照
gedit first.cpp
g++ first.cpp -o test
./test
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define XBOX_TYPE_BUTTON 0x01
#define XBOX_TYPE_AXIS 0x02
#define XBOX_BUTTON_A 0x00
#define XBOX_BUTTON_B 0x01
#define XBOX_BUTTON_X 0x02
#define XBOX_BUTTON_Y 0x03
#define XBOX_BUTTON_LB 0x04
#define XBOX_BUTTON_RB 0x05
#define XBOX_BUTTON_START 0x06
#define XBOX_BUTTON_BACK 0x07
#define XBOX_BUTTON_HOME 0x08
#define XBOX_BUTTON_LO 0x09 /* 左摇杆按键 */
#define XBOX_BUTTON_RO 0x0a /* 右摇杆按键 */
#define XBOX_BUTTON_ON 0x01
#define XBOX_BUTTON_OFF 0x00
#define XBOX_AXIS_LX 0x00 /* 左摇杆X轴 */
#define XBOX_AXIS_LY 0x01 /* 左摇杆Y轴 */
#define XBOX_AXIS_RX 0x03 /* 右摇杆X轴 */
#define XBOX_AXIS_RY 0x04 /* 右摇杆Y轴 */
#define XBOX_AXIS_LT 0x02
#define XBOX_AXIS_RT 0x05
#define XBOX_AXIS_XX 0x06 /* 方向键X轴 */
#define XBOX_AXIS_YY 0x07 /* 方向键Y轴 */
#define XBOX_AXIS_VAL_UP -32767
#define XBOX_AXIS_VAL_DOWN 32767
#define XBOX_AXIS_VAL_LEFT -32767
#define XBOX_AXIS_VAL_RIGHT 32767
#define XBOX_AXIS_VAL_MIN -32767
#define XBOX_AXIS_VAL_MAX 32767
#define XBOX_AXIS_VAL_MID 0x00
typedef struct xbox_map
{
int time;
int a;
int b;
int x;
int y;
int lb;
int rb;
int start;
int back;
int home;
int lo;
int ro;
int lx;
int ly;
int rx;
int ry;
int lt;
int rt;
int xx;
int yy;
}xbox_map_t;
int xbox_open(const char *file_name)
{
int xbox_fd;
xbox_fd = open(file_name, O_RDONLY);
if (xbox_fd < 0)
{
perror("open");
return -1;
}
return xbox_fd;
}
int xbox_map_read(int xbox_fd, xbox_map_t *map)
{
int len, type, number, value;
struct js_event js;
len = read(xbox_fd, &js, sizeof(struct js_event));
if (len < 0)
{
perror("read");
return -1;
}
type = js.type;
number = js.number;
value = js.value;
map->time = js.time;
if (type == JS_EVENT_BUTTON)
{
switch (number)
{
case XBOX_BUTTON_A:
map->a = value;
break;
case XBOX_BUTTON_B:
map->b = value;
break;
case XBOX_BUTTON_X:
map->x = value;
break;
case XBOX_BUTTON_Y:
map->y = value;
break;
case XBOX_BUTTON_LB:
map->lb = value;
break;
case XBOX_BUTTON_RB:
map->rb = value;
break;
case XBOX_BUTTON_START:
map->start = value;
break;
case XBOX_BUTTON_BACK:
map->back = value;
break;
case XBOX_BUTTON_HOME:
map->home = value;
break;
case XBOX_BUTTON_LO:
map->lo = value;
break;
case XBOX_BUTTON_RO:
map->ro = value;
break;
default:
break;
}
}
else if (type == JS_EVENT_AXIS)
{
switch(number)
{
case XBOX_AXIS_LX:
map->lx = value;
break;
case XBOX_AXIS_LY:
map->ly = value;
break;
case XBOX_AXIS_RX:
map->rx = value;
break;
case XBOX_AXIS_RY:
map->ry = value;
break;
case XBOX_AXIS_LT:
map->lt = value;
break;
case XBOX_AXIS_RT:
map->rt = value;
break;
case XBOX_AXIS_XX:
map->xx = value;
break;
case XBOX_AXIS_YY:
map->yy = value;
break;
default:
break;
}
}
else
{
/* Init do nothing */
}
return len;
}
void xbox_close(int xbox_fd)
{
close(xbox_fd);
return;
}
int main(void)
{
int xbox_fd ;
xbox_map_t map;
int len, type;
int axis_value, button_value;
int number_of_axis, number_of_buttons ;
memset(&map, 0, sizeof(xbox_map_t));
xbox_fd = xbox_open("/dev/input/js0");
if(xbox_fd < 0)
{
return -1;
}
while(1)
{
len = xbox_map_read(xbox_fd, &map);
if (len < 0)
{
usleep(10*1000);
continue;
}
printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d start:%d back:%d home:%d LO:%d RO:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d",
map.time, map.a, map.b, map.x, map.y, map.lb, map.rb, map.start, map.back, map.home, map.lo, map.ro,
map.xx, map.yy, map.lx, map.ly, map.rx, map.ry, map.lt, map.rt);
fflush(stdout);
}
xbox_close(xbox_fd);
return 0;
}
如果代码报错:
解决方案:比较合理的办法是把参数类型修改为const char *
参考:https://blog.csdn.net/xyy410874116/article/details/6397549
1.ubuntu下使用USB手柄
2.在UBUNTU中使用北通USB游戏手柄
3.Linux获取/dev/input目录下的event对应的设备
4.树莓派 使用xbox360手柄