joystick手柄驱动安卓_JoyStick for android2.3 游戏手柄功能开发
買了個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)
總結
以上是生活随笔為你收集整理的joystick手柄驱动安卓_JoyStick for android2.3 游戏手柄功能开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 钩子程序,在kill 的时候程
- 下一篇: 在Linux下安装QQ