原址:http://blog.csdn.net/andyhuabing/article/details/7099592
买了个Logitech 的游戏手柄Gamepad F310需要移植到Android系统中,所以花了两天时间详细预研一下需要主要开发的逻辑过程。

1、首先在pc和Linux上测试:

pc上需要安装Logitech公司的驱动程序

针对普通linux平台上安装情况:

ubuntu 下使用游戏手柄:
1, 安装手柄驱动:
# modprobe joydev
2. 安装手柄测试软件:
# sudo apt-get install joystick
3. 测试手柄:
# jstest /dev/js0
或者
# jstest /dev/input/js0

2、使用usb直连方式,首先必须能够检测到设备,使用linux kernel2.6.35版本,配置如下:

make menuconfig

General setup --->

Device Drivers --->

Input  device support -->

主要配置如下:

最重要的配置是: JoyStick interface

这里最重要是是X-Box gamepad support

基本上加了如上的一些配置后,插上usb joystick 可以工作了,我的工作log如下:

修改了kernel配置,目前可以正常工作了:
$ usb 1-2.2: new full speed USB device using hiusb-ehci and address 4
usb 1-2.2: New USB device found, idVendor=046d, idProduct=c21d
usb 1-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-2.2: Product: Gamepad F310
usb 1-2.2: Manufacturer: Logitech
usb 1-2.2: SerialNumber: 991241BC
input: Generic X-Box pad as /devices/platform/hiusb-ehci.0/usb1/1-2/1-2.2/1-2.2:1.0/input/input1

插上时:
$ ls -l
crw-rw---- root     input     13,  65 1970-01-02 08:02 event1
crw-rw---- root     input     13,   0 1970-01-02 08:02 js0
crw-rw---- root     input     13,  64 1970-01-01 08:00 event0
crw-rw---- root     input     13,  32 1970-01-01 08:00 mouse0
crw-rw---- root     input     13,  63 1970-01-01 08:00 mice

拔掉以后:
$ ls -l
crw-rw---- root     input     13,  64 1970-01-01 08:00 event0
crw-rw---- root     input     13,  32 1970-01-01 08:00 mouse0
crw-rw---- root     input     13,  63 1970-01-01 08:00 mice

明显多了两个设备结点js0及event1 ,这此就是针对joystick设备的读取结点名称

在android中可以使用getevent使用getevent可以最直接地获得按键的扫描码,对于Android系统中用户输入设备的调试,可以从源头确定底层输入设备传递上来的信息。

代码在/system/core/toolbox/getevent.c代码中

# getevent
getevent
add device 1: /dev/input/event1
  name:     "Generic X-Box pad"
could not get driver version for /dev/input/js0, Invalid argument
add device 2: /dev/input/event0
  name:     "Hi3716_keypad"
could not get driver version for /dev/input/mouse0, Not a typewriter
could not get driver version for /dev/input/mice, Not a typewriter

node       type code  value

EV_KEY + key code + up/down
/dev/input/event1: 0001 0133 00000001   // X button
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0133 00000000
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0001 0134 00000001   // Y button
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0134 00000000   
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0001 0131 00000001 // E button
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0131 00000000
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0001 0130 00000001   // A button
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0130 00000000
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0001 0116 00000001   // Back button
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0116 00000000
/dev/input/event1: 0000 0000 00000000

dev/input/event1: 0001 013b 00000001   // Start button
dev/input/event1: 0000 0000 00000000
dev/input/event1: 0001 013b 00000000
dev/input/event1: 0000 0000 00000000

EV_ABS + scan code + axis 
/dev/input/event1: 0003 0001 ffff8000   // 上
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0001 ffffff7f
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0003 0001 00007fff   // 下
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0001 ffffff7f
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0003 0000 ffff8000   // 左
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0000 00000080
/dev/input/event1: 0000 0000 00000000

/dev/input/event1: 0003 0000 00007fff   // 右
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0000 00000080
/dev/input/event1: 0000 0000 00000000

简音的测试case代码:

[cpp] view plaincopy print?
  1. #include <linux/input.h>
  2. #include <linux/joystick.h>
  3. int main(void) {
  4. int js_fd;
  5. struct js_event js;
  6. int n, type = 0;
  7. int axis_value, button_value;
  8. int number_of_axis, number_of_buttons;
  9. js_fd = open("/dev/input/js0", O_RDONLY); //打开 设备文件
  10. if (js_fd == NULL) {
  11. printf("open joystick device failed");
  12. return -1;
  13. }
  14. while (1) {
  15. n = read(js_fd, &js, sizeof(struct js_event));
  16. if (n < 0 || n != sizeof(struct js_event)) {
  17. printf("read data failed");
  18. usleep(10 * 1000);
  19. continue;
  20. }
  21. type = js.type & (~JS_EVENT_INIT);
  22. switch (type) {
  23. case JS_EVENT_AXIS:
  24. number_of_axis = js.number;
  25. axis_value = js.value;
  26. printf("number:%2d:value:%6d\n", number_of_axis, axis_value);
  27. break;
  28. case JS_EVENT_BUTTON:
  29. number_of_buttons = js.number;
  30. button_value = js.value;
  31. printf("number:%2d:value:%2d\n", number_of_buttons, button_value);
  32. break;
  33. }
  34. usleep(10 * 1000);
  35. }
  36. return 0;
  37. }

3、框架代码修改

可参考android4.0代码,这个版本已经完整的支持这个功能了,移植主要的eventhub.cpp文件及inputreader中的JoystickInputMapper 即可:

如下:

// See if this device is a joystick.
    // Assumes that joysticks always have gamepad buttons in order to distinguish them
    // from other devices such as accelerometers that also have absolute axes.
    if (haveGamepadButtons) {
        uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK;
        for (int i = 0; i <= ABS_MAX; i++) {
            if (test_bit(i, device->absBitmask)
                    && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) {
                device->classes = assumedClasses;
                break;
            }
        }
    }

一般的按键button走KeyboardInputMapper流程,只有对于EV_ABS的Axis() 使用这个JoystickInputMapper处理。

补充说明:

1、获取手柄的一些额外参数:

ioctl(fd, JSIOCGAXES, &number_of_axes);  //游戏轴数目,默认情况下轴0,1,2代表x轴,y轴,z轴

ioctl(fd, JSIOCGBUTTONS, &number_of_btns); // 游戏按扭数目

ioctl(fd, JSIOCGNAME(sizeof(js_name_str)), js_name_str); // 游戏手柄名称

2、数值,读取jsX时轴值:

轴值范围: -32767 ~ 32767

比如:

[cpp] view plaincopy print?
  1. int *axis = NULL;
  2. int *button = NULL;
  3. struct js_event jse;
  4. axis = (int*)calloc(number_of_axes,sizeof(int));
  5. button = (int*)calloc(number_of_btns,sizeof(int);
  6. read(fd,&jse,sizeof(struct js_event));
  7. switch(jse.type & ~JS_EVENT_INIT)
  8. {
  9. case JS_EVENT_AXIS:
  10. if ((jse->number & 1) == 0) {
  11. axes[jse.number / 2].x = jse.value;
  12. }
  13. else {
  14. axes[jse.number / 2].y = jse.value;
  15. }
  16. break;
  17. case JS_EVENT_BUTTON:
  18. if (jse->value) {
  19. buttons_state |= (1 << jse->number);
  20. }
  21. else {
  22. buttons_state &= ~(1 << jse->number);
  23. }
  24. break;
  25. default:
  26. break;
  27. }

3、读取eventX -- 由joystick设备产生的数值:

EV_ABS + code + axis

分析如下:

首先表示其type = EV_ABS 绝对值 , code值代表x轴(0),y轴(1),z轴值(2),value代表坐标值,这里会涉及到相应的值转换问题,走AMOTION_EVENT_ACTION_MOVE路线。

核心代码如下:

[cpp] view plaincopy print?
  1. <span style="font-size:18px;">    switch (rawEvent->type) {
  2. case EV_ABS: {
  3. ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
  4. if (index >= 0) {
  5. Axis& axis = mAxes.editValueAt(index);
  6. float newValue, highNewValue;
  7. switch (axis.axisInfo.mode) {
  8. case AxisInfo::MODE_INVERT:
  9. newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
  10. * axis.scale + axis.offset;
  11. highNewValue = 0.0f;
  12. break;
  13. case AxisInfo::MODE_SPLIT:
  14. if (rawEvent->value < axis.axisInfo.splitValue) {
  15. newValue = (axis.axisInfo.splitValue - rawEvent->value)
  16. * axis.scale + axis.offset;
  17. highNewValue = 0.0f;
  18. } else if (rawEvent->value > axis.axisInfo.splitValue) {
  19. newValue = 0.0f;
  20. highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
  21. * axis.highScale + axis.highOffset;
  22. } else {
  23. newValue = 0.0f;
  24. highNewValue = 0.0f;
  25. }
  26. break;
  27. default:
  28. newValue = rawEvent->value * axis.scale + axis.offset;
  29. highNewValue = 0.0f;
  30. break;
  31. }
  32. axis.newValue = newValue;
  33. axis.highNewValue = highNewValue;
  34. }
  35. break;
  36. }
  37. case EV_SYN:
  38. switch (rawEvent->scanCode) {
  39. case SYN_REPORT:
  40. sync(rawEvent->when, false /*force*/);
  41. break;
  42. }
  43. break;
  44. }
  45. }</span>

JoyStick for android2.3 游戏手柄功能开发相关推荐

  1. 终端软件升级功能开发_5个很棒的终端技巧可帮助您升级为开发人员

    终端软件升级功能开发 There are plenty of beginner tutorials around that help you learn command line basics, su ...

  2. Windows Phone 开发——相机功能开发

    原文:Windows Phone 开发--相机功能开发 相机功能是手机区别于PC的一大功能,在做手机应用时,如果合理的利用了拍照功能,可能会给自己的应用增色很多.使用Windows Phone的相机功 ...

  3. SNMP功能开发简介 六 snmp功能开发阶段性总结

    先说客户需求:能够通过SNMP协议获取设备信息便于管理.客户提出的需求信息转化成MIB结点都是Get类请求. 背景&方案:我们的产品业务层是使用Go语言开发的,系统层基于OpenWrt(一个嵌 ...

  4. 微信公众平台开发(24) 自定义菜单功能开发

    原文: http://www.cnblogs.com/imaker/p/5491433.html 一.简介 微信公众平台服务号以及之前成功申请内测资格的订阅号都具有自定义菜单的功能.开发者可利用该功能 ...

  5. 云炬Android开发笔记 6启动图功能开发与封装

    阅读目录 1.启动图功能开发与封装(倒计时效果) 2. 持久化 3.倒计时工具库封装 4.第一个启动页面的倒计时 5.启动图功能开发与封装(轮播效果) 5.1 轮播图片的添加 5.2 指示器的添加 6 ...

  6. 方维O2O系统 后台业务员功能开发

    方维O2O系统 后台业务员功能开发 需求如下: 开发一个管理员,叫做业务员有特别的权限,就是后台可以给业务员一个账号,然后业务员每次出去拉到团购回来,上传商户,之后,运营后能在业务员自己的账号权限内看 ...

  7. Android学习之高德地图的通用功能开发步骤(二)

    周一又来了,我就接着上次的开发步骤(一)来吧,继续把高德地图的相关简单功能分享一下 上次写到了第六步,接着写第七步吧. 第七步:定位 + 地图选点 + 路径规划 + 实时导航 以下是我的这个功能Nav ...

  8. ssm中怎么用location.href跳到controller层_聊聊自动驾驶中的功能开发

    在知乎上看过不少大牛写的自动驾驶技术介绍文章,大多谈到的是AI, Deep Learning, Computer Vision等等感知(Perception)层面的.但在各个传感器(雷达.摄像头.激光 ...

  9. Django后台项目之用户管理功能开发流程

    项目功能开发流程 1 先写列表页(加载出来数据就行) ob = User_vip.objects.filter(is_del='004001').order_by('-cts') 2 写添加功能 2. ...

最新文章

  1. 中国移动选择博科NFV软件设备来支持“互联网+”使命
  2. git 修改全局配置
  3. sonar plugin DefaultMeasure与DefaultHighlighting
  4. IntelliJ IDEA for Mac如何通过指定的关键字查找/搜索类文件
  5. 压缩图片上传到数据库
  6. Leetcode | 513. Find Bottom Left Tree Value
  7. unity 克隆_使用Unity开发Portal游戏克隆
  8. ubuntu下vim语法高亮问题
  9. 绵阳市公文写作和计算机应用,【绵阳】绵阳市事业单位公开招聘工作人员公文写作和计算机应用笔试和复习大纲...
  10. PHP 2014.5.21的总结:
  11. 未来茅台酒会怎样跌下神坛?
  12. 二维码批量生成下载工具
  13. ActiveMQ(二)——常用api、持久化、签收模式、以及常见问题
  14. c语言linux系统宏,Linux下C语言中的预定义宏
  15. [病毒分析]熊猫烧香应急处理方法
  16. 关注物业公司信息化建设
  17. 百度地图怎么不显示服务器地址,百度地图使用指南
  18. 静态分析Android程序——smali文件解析
  19. input正则邮箱_常用正则表达式—邮箱(Email)
  20. 用chrome按F12抓包 页面跳转POST一瞬间就闪没了

热门文章

  1. oracle数据库的重复数据处理
  2. 关于GCD执行任务的理解
  3. myeclipse/eclipse方法和类的自动注解
  4. 【现代机器人学】名词概念的理解
  5. 异常已存在具有相同键的条目。_从Viticis Fructus分离的环烯醚萜类化合物抑制紫杉醇诱导的小鼠机械性异常性疼痛...
  6. php 进行http请求,php模拟http请求的两种方式
  7. java先默认初始化子类吗,Java 对象初始化顺序
  8. pycharm添加python注释头_Pycharm自动添加头注释
  9. PowerDesigner设置code和name不联动的方法
  10. hdoj 3376,2686 Matrix Again 【最小费用最大流】