joystick手柄驱动安卓_JoyStick for android2.3 游戏手柄功能开发

本文介绍了如何在Linux和Android系统上配置和测试Logitech Gamepad F310游戏手柄,包括在Ubuntu下安装驱动和测试软件,以及在Linux kernel 2.6.35中配置USB joystick支持。在Android系统中,通过getevent工具进行设备节点监控,并展示了读取按键和轴值的方法。文章还提供了简单的测试代码和Android框架代码的修改建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

买了个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代码:

#include 

#include 

intmain(void) {

intjs_fd;

structjs_event js;

intn, type = 0;

intaxis_value, button_value;

intnumber_of_axis, number_of_buttons;

js_fd = open("/dev/input/js0", O_RDONLY);//打开 设备文件

if(js_fd == NULL) {

printf("open joystick device failed");

return-1;

}

while(1) {

n = read(js_fd, &js, sizeof(structjs_event));

if(n 

printf("read data failed");

usleep(10 * 1000);

continue;

}

type = js.type & (~JS_EVENT_INIT);

switch(type) {

caseJS_EVENT_AXIS:

number_of_axis = js.number;

axis_value = js.value;

printf("number:%2d:value:%6d\n", number_of_axis, axis_value);

break;

caseJS_EVENT_BUTTON:

number_of_buttons = js.number;

button_value = js.value;

printf("number:%2d:value:%2d\n", number_of_buttons, button_value);

break;

}

usleep(10 * 1000);

}

return0;

}

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

比如:

int*axis = NULL;

int*button = NULL;

structjs_event jse;

axis = (int*)calloc(number_of_axes,sizeof(int));

button = (int*)calloc(number_of_btns,sizeof(int);

read(fd,&jse,sizeof(structjs_event));

switch(jse.type & ~JS_EVENT_INIT)

{

caseJS_EVENT_AXIS:

if((jse->number & 1) == 0) {

axes[jse.number / 2].x = jse.value;

}

else{

axes[jse.number / 2].y = jse.value;

}

break;

caseJS_EVENT_BUTTON:

if(jse->value) {

buttons_state |= (1 <number);

}

else{

buttons_state &= ~(1 <number);

}

break;

default:

break;

}

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

EV_ABS + code + axis

分析如下:

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

核心代码如下:

switch(rawEvent->type) {

caseEV_ABS: {

ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);

if(index >= 0) {

Axis& axis = mAxes.editValueAt(index);

floatnewValue, highNewValue;

switch(axis.axisInfo.mode) {

caseAxisInfo::MODE_INVERT:

newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)

* axis.scale + axis.offset;

highNewValue = 0.0f;

break;

caseAxisInfo::MODE_SPLIT:

if(rawEvent->value 

newValue = (axis.axisInfo.splitValue - rawEvent->value)

* axis.scale + axis.offset;

highNewValue = 0.0f;

} elseif(rawEvent->value > axis.axisInfo.splitValue) {

newValue = 0.0f;

highNewValue = (rawEvent->value - axis.axisInfo.splitValue)

* axis.highScale + axis.highOffset;

} else{

newValue = 0.0f;

highNewValue = 0.0f;

}

break;

default:

newValue = rawEvent->value * axis.scale + axis.offset;

highNewValue = 0.0f;

break;

}

axis.newValue = newValue;

axis.highNewValue = highNewValue;

}

break;

}

caseEV_SYN:

switch(rawEvent->scanCode) {

caseSYN_REPORT:

sync(rawEvent->when, false/*force*/);

break;

}

break;

}

}

(andyhuabing)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值