Andrew Huang 转载请注明作者及出处 (http://bluedrum.cnblog.cn)
为了演示开发板上嵌入式应用和Linux下一些概念的使用,我写了几个不同版本的坦克对战的小游戏,分别用VT100全屏,FrameBuffer绘屏,也有学生用SDL来实现。
因为程序要在开发板的ARM-Liux上和PC机上运行。其中键盘输入采用输入子系统的的/dev/input/eventN.
在具体的使用中,有一个头痛的问题就是不同环境下,键盘或者开发板上的按键对应的event结点不同。如果每次都直接修改程序相当麻烦,而且USB键盘还有一个问题是在不同环境下,因为驱动加载顺序不同。结点文件名也不一样。这样应用起来相当麻烦。
因此我根据SDL类似代码,写了一个自动扫描所有输入设备结点,并且正确找出键盘对应的结点的通用函数。
一.工作原理
这个函数的功能是从/dev/input/event0 依次扫描到/dev/input/event254 各个结点。每个接点调用ioctl的 EVIOCGBIT命令取得输入驱动的事件支持列表和按键支持列表。如果支持EV_KEY事件,并且支持一些游戏所需要特殊健值,即可认为这个结点就是按键驱动文件.
这个函数如果找到键盘,则在dev_name返回设备结点名字,并且返回值不是空指针。如果返回值为空表示系统中没有键盘
- #define test_bit(nr, addr) \
-
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
-
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
-
-
#define PRINT_INT(e) fprintf(stderr,"%s=%d\n",#e,e)
-
-
char * scan_kbd_device(char * dev_name,int size)
-
{
-
int i,fd;
-
int ret1,ret2;
-
-
-
unsigned long evbit[NBITS(EV_MAX)] = {0};
-
unsigned long keybit[NBITS(EV_MAX)] = {0};
-
-
//fprintf(stderr,"evbit size %d,keybit size %d\n",sizeof(evbit),sizeof(keybit));
-
-
for(i=0; i<255;i++)
-
{
-
snprintf(dev_name,size,"/dev/input/event%d",i);
-
-
-
fd = open(dev_name,O_RDWR);
-
if(fd == -1)
-
continue;
-
-
-
ret1= ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit);
-
ret2= ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit);
-
-
close(fd);
-
-
if ( (ret1< 0) || (ret2 < 0) ) {
-
-
continue;
-
}
-
-
-
- /* 检测是否支持按键和ENTER和ESC键*/
-
-
if(test_bit(EV_KEY,evbit) && test_bit(KEY_ENTER,keybit)
-
&& test_bit(KEY_ESC,keybit) )
-
{
-
return dev_name;
-
}
-
-
}
-
return NULL;
-
}
二。需要改进的地方
这个程序在实际程序使用中相当方便,但是还是需要有一些改进。一是发现对于功能键如 KEY_UP/KEY_LEFT等怎么都是测试失败.
二是需要对键值列表,应该用一个数组动态传入,以方便不同游戏的所需健的支的测试
阅读(3296) | 评论(0) | 转发(1) |