JoyStick for android2.3 遊戲手柄功能開發

來源:互聯網
上載者:User

買了個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 <linux/input.h>#include <linux/joystick.h>int main(void) {int js_fd;struct js_event js;int n, type = 0;int axis_value, button_value;int number_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(struct js_event));if (n < 0 || n != sizeof(struct js_event)) {printf("read data failed");usleep(10 * 1000);continue;}type = js.type & (~JS_EVENT_INIT);switch (type) {case JS_EVENT_AXIS:number_of_axis = js.number;axis_value = js.value;printf("number:%2d:value:%6d\n", number_of_axis, axis_value);break;case JS_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);}return 0;}


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;struct js_event jse;axis = (int*)calloc(number_of_axes,sizeof(int));button = (int*)calloc(number_of_btns,sizeof(int);read(fd,&jse,sizeof(struct js_event));switch(jse.type & ~JS_EVENT_INIT){case JS_EVENT_AXIS:if ((jse->number & 1) == 0) {axes[jse.number / 2].x = jse.value;}else {axes[jse.number / 2].y = jse.value;}break;case JS_EVENT_BUTTON:if (jse->value) {buttons_state |= (1 << jse->number);}else {buttons_state &= ~(1 << jse->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) {    case EV_ABS: {        ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);        if (index >= 0) {            Axis& axis = mAxes.editValueAt(index);            float newValue, highNewValue;            switch (axis.axisInfo.mode) {            case AxisInfo::MODE_INVERT:                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)                        * axis.scale + axis.offset;                highNewValue = 0.0f;                break;            case AxisInfo::MODE_SPLIT:                if (rawEvent->value < axis.axisInfo.splitValue) {                    newValue = (axis.axisInfo.splitValue - rawEvent->value)                            * axis.scale + axis.offset;                    highNewValue = 0.0f;                } else if (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;    }    case EV_SYN:        switch (rawEvent->scanCode) {        case SYN_REPORT:            sync(rawEvent->when, false /*force*/);            break;        }        break;    }}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.