Extended controls system will allow aircraft/vehicle scripts to register for and handle generic and custom input actions, that can come either from keys or HID buttons/axes bound in iomap.cfg files, or from clicking/dragging a 3D cockpit element (later), or even from external plugins in case of cockpit makers.
Script registers an action handler like this:
this.register_button("air/starters/engage", handler, options)
Where the handler is a JS function that gets invoked on value change, and options define some extra properties. Later it will also define 3D mapping so that when user clicks on the cockpit element, the same handler is invoked as well. The action name doesn't actually have to exist in the configuration at all, but if it does (user adds it), it will become also possible to invoke the action via keyboard/HID binding. This way it will be possible to customize bindings by the user even for special addons that would otherwise not be able to handle custom mappings.
So, vehicle script specifies the following when asking to receive an input action:
- hierarchic action name (doesn't have to exist in config files, in which case it won't be linked but mouse clicks will still work)
- handler, a JS function(value, channel, dt)
- options: min (initial) and max rate of value change, in other words how fast the value changes from 0 to 1/-1 when user presses a key, which is useful when you want to tie this value to a steering wheel angle, for example
- options: centering rate - how quick the value goes back to zero after being released (can be 0 to remain)
- number of steps for key/button bindings that increment or decrement value in discrete steps, rather than smoothly adjusting it
- 3D cockpit elements or model-space areas bound to action modes, usable in clickable cockpit
- action group, which can be used to enable/disable groups of input actions, for example on switching seat when one may want different controls bound
In config files, controls are arranged in groups, as in the existing iomap config. Each control action has a name, which is used to reference it, in the format cfgname/group/action, e.g "air/engines/throttle". Cfgname is the name of the config file, in this case air.iomap.cfg; you can also have different configs for different vehicle types and the config name is used as the prefix.
For each control action you can have multiple bindings, keys or buttons or joy axis that set the value of the control that is received in event handlers. You can have multiple bindings with different modes, where the mode tells how the button changes the value. For example, you can bind keys with modes that set the target value to 1, 0 or -1, or increment/decrement it in steps. There are also some advanced modes like a toggle (still respecting the ramp parameters) or "combo", which allows you to bind a single key that normally functions as a toggle, but with a shift it sets the target value to 1, with ctrl to -1 (or 0 if an volume range was asked), and ctrl+shift+key resets the value to 0.
Script can also ask to receive symmetric (-1..1) or unsigned range (0..1). Note that button press handlers completely avoid all this and just invoke the handler when the key/button is pressed.
This allowed us to reduce the number of control actions considerably. For example where X-plane has various _on/_off/_toggle/_reset varieties, here it's just a single control action that can have different keys with different modes bound. Some people will be good just with a toggle, some can have on/off mode keys or buttons, or all of them.
Inc/dec key modes allow adjusting the value in steps given by the script.
Additionally, each bound control can specify a channel id. For example, if you have multiple engines, you can bind separate keys for each, all done in the same control action but with binding specifying a channel id. ID 0 (or no id specified) is assumed to be the global action, like turn (on/off/toggle) all engines. Aircraft scripts should always handle the default one, in case people do not have the specific controls bound, and then any extended channels they want to handle.
Some open questions:
- should we split the config files into multiple ones, like having one for common aircraft controls and then separate ones with extra controls for turboprops and jets, or should all aircraft stuff be in one file
- what should the default control set be?
- note that most of the controls will be unbound, but we want to have a good base set so that people do not have to invent custom ones, ending up with many different names for the same action
- on the other hand, there's probably no need for some rare ones, or ones that will almost solely be accessed via clickable cockpits - how to transition from current system:
- for aircraft there are default event handlers that can be enabled as groups (for planes or helis), which directly set JSBSim properties without script intervention. It will be good to have this preserved, not having to bind each basic action in every aircraft script, but we also need to have possibility to disable it.
- for vehicles, present temporary extended key system will probably have to be removed, since it's not very compatible
Current WIP aircraft command list is attached below.