Joystick for android2.3 game controller function development

Source: Internet
Author: User
Tags usleep

The gamepad f310 game controller of Logitech needs to be transplanted to the Android system, so it took two days to detail the main development logic process.

1. First test on PC and Linux:

Install the Logitech driver on the PC.

For general Linux platform installation:

Use the gamepad in Ubuntu:
1. Install the handle DRIVER:
# Modprobe joydev
2. Install the handle testing software:
# Sudo apt-Get install joystick
3. Test handle:
# Jstest/dev/js0
Or
# Jstest/dev/input/js0

2. To use USB direct connection, you must first detect the device and use Linux kernel2.6.35. The configuration is as follows:

Make menuconfig

General setup --->

Device Drivers --->

Input Device Support -->

The main configuration is as follows:

 

The most important configuration is: joystick Interface




The most important here is X-Box gamepad support


After some of the above configurations are added, plug in USB joystick to work. My job log is as follows:


The Kernel configuration has been modified and can work properly now:
$ 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 = c30d
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

During plug-in:
$ 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

After unplugging:
$ 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


There are obviously two more device nodes: js0 and event1. This is the name of the read node for the joystick device.


In Android, you can use getevent to obtain the scan code of the key most directly. for debugging of the device input in Android, you can determine the information transmitted by the underlying input device from the source.

The code is in the/system/CORE/toolbox/getevent. C code.

# Getevent
Getevent
Add device 1:/dev/input/event1
Name: "generic X-Box pad"
Cocould not get driver version for/dev/input/js0, invalid argument
Add device 2:/dev/input/event0
Name: "hi3716_keypad"
Cocould not get driver version for/dev/input/mouse0, not a typewriter
Cocould 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 running 7fff //
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0001 ffffff7f
/Dev/input/event1: 0000 0000 00000000

/Dev/input/event1: 0003 0000 ffff8000 // left
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 00000080
/Dev/input/event1: 0000 0000 00000000

/Dev/input/event1: 0003 0000 running 7fff // right
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 00000080
/Dev/input/event1: 0000 0000 00000000


Test Case code:

# 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); // open the device file 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. Modify framework code

You can refer to the android4.0 code. This version fully supports this function. Just port the main eventhub. cpp file and joystickinputmapper in inputreader:

As follows:

// 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;
}
}
}


Generally, the key button follows the keyboardinputmapper process. This joystickinputmapper is used only for Axis () of ev_abs.


Note:

1. Obtain some additional parameters of the handle:

IOCTL (FD, jsiocgaxes, & number_of_axes); // Number of game axes. The default value is 0, 1, and 2, indicating the X axis, Y axis, and Z axis.

IOCTL (FD, jsiocgbuttons, & number_of_btns); // Number of game buttons

IOCTL (FD, jsiocgname (sizeof (js_name_str), js_name_str); // game handle name


2. Numeric value:

Axis value range:-32767 ~ 32767

For example:

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. Read eventx -- value generated by the joystick device:


Ev_abs + code + axis

The analysis is as follows:

First, it indicates the absolute value of type = ev_abs. The code value represents the X axis (0), the Y axis (1), the Z axis value (2), and the value represents the coordinate value, here the corresponding value conversion problem will be involved, taking the amotion_event_action_move route.

The core code is as follows:

    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;    }}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.