Changing repeat rate of joystick buttons

From FlightGear wiki
Jump to navigation Jump to search


If you are new to writing Nasal functions for joysticks, read Using a Nasal file with a joystick first.

Background

Sometimes the repeat rate of joystick buttons is too high. The value changes so fast that you can't set it accurately. In your joystick xml file you could use

  <desc>whatever</desc>
  <interval-sec>x.xx</interval-sec>

where x.xx is the time between button action repeats. This has the problem that the delay is implemented at the start of the button press, as well as between repeats. It is also not as versatile as using this method.


Changes (additions) to the Nasal file

You must have set up everything according to Using a Nasal file with a joystick so that your joystick button calls a routine in a Nasal file, as per the next paragraph.


Assume that the button in question is labelled "C". The property we want to change with the button is /mythical/telescope-colour. Our nas file is called mynasfile.nas. We will use a flag called busyTelescope to control the repeat rate.


Start off by adding the function for the button

  var buttonC = func {
        if (getprop("/busyTelescope")) return;
  
        setprop("/busyTelescope", 1);
  
        # ... Your code to adjust telescope property goes here  ..
    
}

Now when the button is pressed the busy flag will be set, the code will be called. As soon as FG repeats the button, the set state of the busy flag will make the routine return. So far so good.

We still need to create the busy flag, set the repeat rate we want, and clear the busy flag between (our) repeats.

At the top of the nas file add

  var buttonRate = 0.1;

This is the number of seconds we want between repeats. In this case it is 100 milliseconds.


Then we need to create the busy flag. This must be done in an init routine. Add to the init routine

  props.globals.getNode("/busyTelescope", 1);
  setprop("/busyTelescope", 0);

We now have the flag, and it is cleared.

We still need to clear it at our required repeat rate. Add to the init routine

  setlistener("/busyTelescopy", func 
  { 
   if (getprop("/mythical/busyTelescope")) 
    settimer(busyTelescopeClear, buttonRate, 1); 
  } #end of anonymous function
); #end of setlistener

and add this function

  var busyTelescopeClear = func {
        setprop("/busyTelescope", 0);
  }


Now, whenever the button is pressed, the flag gets set. The listener detects this and starts a timer, with delay buttonRate. When the delay elapses, busyTelescopeClear is called, which clears the flag, and the button will repeat.

We now can control the repeat rate of the button.

Making the code safe

To avoid the busy flag possibly getting stuck in the true state, make the mod-up of your joystick call mynasfile.buttonCUp().

Then add this to the nas file

  var buttonCUp = func {
        busyTelescopeClear();
  }

Other uses

It is of course possible to use this technique for adding a delay in any nasal code, with appropriate changes.