SUSE Linux iTOps Tube

Friday, June 29, 2012

USB PSX joystick adaptor and kernel modifications

Hi, I bought an USB adaptor for the PSX Joystick. As I expected it didn't work quite well so I started researching but with no solution. Since it seemed that there were no solution for my particular problem I decided to start working with it as I know a little bit of C (but enough to understand more or less what's going on).



This is the problem: I get a lot of axis showing up (even though I plugged the classic digital pad) and 13 keys instead of 15. Every key except for circle, square and cross are detected as buttons and also as axis. The non-working keys are just identified as axis. After reading a workaround for a dancing mat I managed to modify the joydev.c code in order to convert the axis information to keys. And it works but only in jstest. Now every key has an axis and button except for cross, circle and square which are now buttons only. This may be a little confusing so I'll post the modification of the code




Code:


static void joydev_event(struct input_handle *handle,

                        unsigned int type, unsigned int code, int value)

{

#define CIRCULO    19

#define CRUZ      20

#define CUADRADO  21

#define VAL_MAX    32767

#define VAL_MIN    -32767

        struct joydev *joydev = handle->private;

        struct joydev_client *client;

        struct js_event event;



        switch (type) {



        case EV_KEY:

                if (code < BTN_MISC || value == 2)

                        return;

                event.type = JS_EVENT_BUTTON;

                event.number = joydev->keymap[code - BTN_MISC];

                event.value = value;

                break;



        case EV_ABS:

                event.type = JS_EVENT_AXIS;

                event.number = joydev->absmap[ code ];

                event.value = joydev_correct(value,

                                        &joydev->corr[event.number]);

                printk("event.value = %i\n", event.value);

                if (event.number == CIRCULO) {                        // Modification starts here

                        event.type = JS_EVENT_BUTTON;

                        event.number = 13;

                        if ( event.value == VAL_MAX )

                                event.value = 1;

                        if ( event.value == VAL_MIN )

                                event.value = 0;

                }

                if (event.number == CUADRADO) {

                        event.type = JS_EVENT_BUTTON;

                        event.number = 15;

                        if ( event.value == VAL_MAX )

                                event.value = 1;

                        if ( event.value == VAL_MIN )

                                event.value = 0;

                }

                if (event.number == CRUZ) {

                        event.type = JS_EVENT_BUTTON;

                        event.number = 14;

                        if ( event.value == VAL_MAX )

                                event.value = 1;

                        if ( event.value == VAL_MIN )

                                event.value = 0;

                }                                                      // End.

                if (event.value == joydev->abs[event.number])

                        return;

                joydev->abs[event.number] = event.value;

                break;



        default:

                return;

        }



        event.time = jiffies_to_msecs(jiffies);



        rcu_read_lock();

        list_for_each_entry_rcu(client, &joydev->client_list, node)

                joydev_pass_event(client, &event);

        rcu_read_unlock();



        wake_up_interruptible(&joydev->wait);

}


Where the comments show the modifications inside the joydev_event.



So my question is: does anyone knows how applications (such as wine, snes9x, mednafen) interact with the joysticks? By the way, I also tested the joystick with input-event (but this time I think it's reading /dev/input/event5 instead of /dev/input/js0. However they seem to be the same) and I get a complete different result. The buttons are still identified as EV_ABS (I assume that means axis) instead of EV_KEY.



Thanks :)











No comments:

Post a Comment