Author Topic: Code to map joystick axis to buttons  (Read 3474 times)

0 Members and 1 Guest are viewing this topic.

Offline pflumm

  • 22
Code to map joystick axis to buttons
After I installed a new Ubuntu recently, I wanted to have fs2 running on it and get rid of the WinXP version. So far so good, compilation went o.k. and everything seems to work, except my Saitek Cyborg Evo Force.

Well, it somehow worked, but not so well. After some digging, I found out that SDL thinks it has 29 axes and that the hat is mapped to axes 6 and 7, which is not good if you want to use the hat as buttons. Also, throttle and bank are axes 8/9. I read a thread here about a similar problem, but no SDL_LINUX_JOYSTICK variable helped. I then decided that the linux joystick driver is buggy (it should detect my joystick correctly, shouldn't it?) and that linux drivers are a bit too heavy for me to correct. So I had to code a workaround into fs2_open. First, I changed JOY_NUM_AXES in code/joy.h to 10, so that I can use bank/throttle. Next problem: How to bind the Hat to useful functions (like target next hostile) that usually don't take an axis as input? Well, below is my solution, which has to go into code/osapi/osapi_unix.cpp, into the function unix_process(). It maps the 6/7 axes (the hat) to joystick buttons 15-18. In a first test, it seems to work fine...

As others might have a similar problem, this little code change might give the flexibility to make virtually any joystick hat working. Perhaps someone who knows more about the code and actually has more than a few hours time could give this idea a decent face (some configuration file which contains axes/buttons mapping) and put it in CVS? Sadly, I have no idea if this might have some negative side effects (performance for example), but I'll try it out in the next few weeks.

Christof

...
      case SDL_JOYHATMOTION:
         joy_set_hat_state( event.jhat.value );
         break;

      case SDL_JOYAXISMOTION:
           if (event.jaxis.axis == 6) {
             if (event.jaxis.value < 0) {
               joy_set_button_state(15, 1);
//                fprintf(stderr, "Hat left\n");
             } else if (event.jaxis.value > 0) {
               joy_set_button_state(16, 1);
//                fprintf(stderr, "Hat right\n");
             } else {
               joy_set_button_state(15, 0);
               joy_set_button_state(16, 0);
//                fprintf(stderr, "Hat left-right neutral\n");
             }
           }
           if (event.jaxis.axis == 7) {
             if (event.jaxis.value < 0) {
               joy_set_button_state(17, 1);
//                fprintf(stderr, "Hat up\n");
             } else if (event.jaxis.value > 0) {
               joy_set_button_state(18, 1);
//                fprintf(stderr, "Hat down\n");
             } else {
               joy_set_button_state(17, 0);
               joy_set_button_state(18, 0);
//                fprintf(stderr, "Hat up-down neutral\n");
             }
           }
           break;
       

 

Offline taylor

  • Super SCP/Linux Guru
  • Moderator
  • 212
    • http://www.icculus.org/~taylor
Re: Code to map joystick axis to buttons
Changing JOY_NUM_AXES will break pilot files so you pretty much doomed this patch right there. :)  Regardless though, this type of hack has no business in the game code since it's not a game bug.  The hat needs to send hat events and not axis events so this needs to be taken care of either in the joystick driver or SDL.

What SDL_LINUX_JOYSTICK settings did you try?

  

Offline pflumm

  • 22
Re: Code to map joystick axis to buttons
Changing JOY_NUM_AXES will break pilot files so you pretty much doomed this patch right there. :)  Regardless though, this type of hack has no business in the game code since it's not a game bug.  The hat needs to send hat events and not axis events so this needs to be taken care of either in the joystick driver or SDL.

What SDL_LINUX_JOYSTICK settings did you try?

Hm, breaking pilot files is no good!  :(

I tried a few things for SDL_LINUX_JOYSTICK. The only value that seems to give correct hat response is "'Saitek Cyborg Evo Force' 6 1 0". (I tried hat response with a self written test program). Problem is that the throttle/bank axes are mapped to 8/9 with this setting.

Seems I have to take the time at some point to find out more about Linux joystick drivers...