Updated to latest revision.
This commit is contained in:
parent
41260ee546
commit
7c4c886938
1 changed files with 450 additions and 141 deletions
|
@ -1,49 +1,71 @@
|
||||||
Users Guide to Joystick Usage Under FlightGear Flight Simulator
|
Users Guide to FGInput - Joystick And Keyboard Bindings For FlightGear
|
||||||
version 0.4 03/06/2001
|
Or
|
||||||
|
"The document formerly know as The Users Guide to Joystick Usage Under
|
||||||
|
FlightGear Flight Simulator"
|
||||||
|
|
||||||
|
version 0.7.7.1 06/25/2001
|
||||||
Author John Check <j4strngs@rockfish.net>
|
Author John Check <j4strngs@rockfish.net>
|
||||||
|
|
||||||
This document is written with versions of FlightGear 0.7.5 and greater
|
This document is written with versions of FlightGear 0.7.7 and greater
|
||||||
in mind. It assumes a working joystick present on your system. While it
|
in mind. It assumes a working joystick present on your system. It
|
||||||
is written from the point of view of a Linux user, the cross platform
|
is written from the perspective a Linux user, but the information presented
|
||||||
nature of FGFS should ensure the information presented is useful on other
|
is valid on other platforms. The most current version can be found at:
|
||||||
platforms. I'd like to say thanks to all the developers who make FGFS happen
|
|
||||||
and forgive me for not giving credit with regard to the property
|
http://rockfish.net/shell/aboutFGInput.txt
|
||||||
manager and js_demo. Corrections and additions are encouraged.
|
|
||||||
The most current version can be found at http://rockfish.net/shell/aboutjoy.txt
|
Thanks to David Megginson, who aside from actually implementing FGFS XML
|
||||||
|
features, lets me rip off his descriptions of how stuff works so I can look
|
||||||
|
smart.
|
||||||
|
|
||||||
Some History:
|
Some History:
|
||||||
|
------------
|
||||||
Earlier versions of FGFS had assignments of joystick axis/buttons
|
Earlier versions of FGFS had assignments of joystick axis/buttons
|
||||||
hard coded. If you had a joystick that did not use the default channel
|
and key bindings hard coded. If you had a joystick that did not use
|
||||||
assignments, you had to edit the source code and recompile.
|
the default channel assignments, or wanted different key bindings
|
||||||
Fortunately, around about v0.7.4/0.7.5 a "property manager" was
|
you had to edit the source code and recompile.
|
||||||
implemented, allowing, among other things, runtime access to some of the FGFS
|
|
||||||
internals, which facilitated being able to set the parameters for the
|
|
||||||
joystick at runtime.
|
|
||||||
|
|
||||||
About runtime options:
|
Fortunately, around about v0.7.5 a "property manager" was implemented,
|
||||||
FGFS has always had a plethora of available runtime options. Starting
|
which facilitated being able to set the parameters for the joystick at runtime.
|
||||||
point, altitude, direction, time of day and other aspects of the
|
Version 0.7.7 saw an expanded role for the property manager and the
|
||||||
simulated environment were always well represented. However there
|
addition of a "command manager" that allows for binding of events to commands.
|
||||||
were also a number of options and features that were not well documented.
|
The code that does this is known as FGInput and is used to configure
|
||||||
Among these was the ability to use a runtime configuration file (.fgfsrc)
|
keyboard command bindings as well as joysticks.
|
||||||
to control the default operation. The .fgfsrc file is not created at runtime
|
|
||||||
and must be created manually. Fortunately, the format of the file is
|
|
||||||
straightforward. All one need do is place the commandline options one would
|
|
||||||
like in a plain ASCII text file in the users home directory. System wide
|
|
||||||
defaults can be place in $FG_ROOT/system.fgfsrc.
|
|
||||||
|
|
||||||
With the advent of the property manager it became possible to add a number
|
Storing alternate keyboard or joystick bindings can be done in a variety of ways.
|
||||||
of additional runtime options to the .fgfsrc file including joystick channel
|
The order of precedence for options is thus:
|
||||||
assignments. Basically, anything* that is reported by the property manager
|
|
||||||
can now be tweaked without having to recompile the binary.
|
|
||||||
|
|
||||||
*see mini-doc/properties.txt for exceptions
|
Source Location Format Scope
|
||||||
|
------ -------- ------ -----
|
||||||
|
command line STDIN see examples session
|
||||||
|
.fgfsrc Users home directory. command line options single user
|
||||||
|
system.fgfsrc $FG_ROOT command line options system wide
|
||||||
|
joystick.xml $FG_ROOT XML property list system wide
|
||||||
|
keyboard.xml $FG_ROOT XML property list system wide
|
||||||
|
|
||||||
|
First Things First
|
||||||
|
------------------
|
||||||
|
I will cover joysticks first and save the keyboard stuff for later.
|
||||||
|
FGInput treats things in a generic enough way that the line between
|
||||||
|
joystick buttons and keyboard events starts to blur.
|
||||||
|
|
||||||
|
About XML
|
||||||
|
---------
|
||||||
|
In case you were wondering, XML stands for eXtensible Markup Language.
|
||||||
|
It looks a lot like HTML, except you get to define your own tags. Well,
|
||||||
|
in the case of FGFS we defined the tags you need to configure things.
|
||||||
|
It is well suited for describing hierarchically organized structures, such as
|
||||||
|
the property tree FGFS uses to expose the it's innards to external applications.
|
||||||
|
Your XML configuration files for FGFS must start and end with the following
|
||||||
|
pair of tags.
|
||||||
|
<PropertyList>
|
||||||
|
<!-- this is a comment, See I told you it was like HTML -->
|
||||||
|
</PropertyList>
|
||||||
|
|
||||||
Determining your joystick output:
|
Determining your joystick output:
|
||||||
|
--------------------------------
|
||||||
Included with FlightGear is a utility called js_demo. It will report
|
FlightGear ships with a utility called js_demo. It will report
|
||||||
the number of joysticks attached to a system and their capabilites.
|
the number of joysticks attached to a system and their capabilites.
|
||||||
By observing the output of js_demo while working our joystick we can
|
By observing the output of js_demo while working your joystick you can
|
||||||
determine what controls are where.
|
determine what controls are where.
|
||||||
It should be noted that, at least on UNIX, numbering generally starts with
|
It should be noted that, at least on UNIX, numbering generally starts with
|
||||||
zero. In the following example the system has 1 joystick (js0) connected.
|
zero. In the following example the system has 1 joystick (js0) connected.
|
||||||
|
@ -54,7 +76,7 @@ Typical output of js_demo:
|
||||||
|
|
||||||
Joystick test program.
|
Joystick test program.
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Joystick 1 not detected
|
Joystick 1 not detected <!-- remember we start at 0 -->
|
||||||
Joystick 2 not detected
|
Joystick 2 not detected
|
||||||
+---------------JS.0-----------------+
|
+---------------JS.0-----------------+
|
||||||
| Btns Ax:0 Ax:1 Ax:2 |
|
| Btns Ax:0 Ax:1 Ax:2 |
|
||||||
|
@ -79,29 +101,41 @@ but this number is displayed on the screen in hexadecimal notation, so:
|
||||||
|
|
||||||
|
|
||||||
Default Joystick properties:
|
Default Joystick properties:
|
||||||
|
----------------------------
|
||||||
|
|
||||||
Axis 0 = Aileron
|
Axis 0 = Aileron
|
||||||
Axis 1 = Elevator
|
Axis 1 = Elevator
|
||||||
Axis 2 = Rudder
|
Axis 2 = Rudder
|
||||||
Axis 3 = Throttle
|
Axis 3 = Throttle
|
||||||
Button 0 = All brakes
|
Button 0 = All brakes
|
||||||
Button 1 = Left brake
|
Button 1 = Elevator trim (up)
|
||||||
Button 2 = Right brake
|
Button 2 = Elevator trim (down)
|
||||||
Button 3 = Elevator trim (up)
|
|
||||||
Button 4 = Elevator trim (down)
|
|
||||||
Button 5 = Flaps (down)
|
|
||||||
Button 6 = Flaps (up)
|
|
||||||
|
|
||||||
|
|
||||||
In addition to the channel assignments there are other properties
|
Okay, Now what?
|
||||||
for tuning the joystick. These values work together in a particular order.
|
---------------
|
||||||
They should always be written as a 'float', or decimal number.
|
Now that you know what the output of the devices connected to the joystick
|
||||||
|
port (or USB port joystick devices) is, you probably want to dive straight
|
||||||
|
in and to start connecting to FGInput. If you are familiar with configuring
|
||||||
|
the joystick on versions of FGFS prior to 0.7.7 you can skip down to the
|
||||||
|
section "The Command Manager".
|
||||||
|
If you are a new FGFS user, you should at least skim the next bit since it
|
||||||
|
explains some concepts you may or may not know. It also covers some legacy
|
||||||
|
joystick options which have not been implemented yet in the context of the
|
||||||
|
command manager.
|
||||||
|
|
||||||
|
|
||||||
|
Modifiers For Raw Joystick Values
|
||||||
|
---------------------------------
|
||||||
|
These concepts are expressed by supplying arguments to the joystick bindings.
|
||||||
|
The raw values coming from the joystick axes may not be suitable to use directly.
|
||||||
|
For that matter not all joysticks are created equal so understanding the basic
|
||||||
|
concepts should save you some time when experimenting to get the best performance.
|
||||||
|
|
||||||
The full order of precedence for axis properties is
|
The full order of precedence for axis properties is
|
||||||
|
|
||||||
1. The raw axis value ...
|
1. The raw axis value ...
|
||||||
2. is adjusted to dead-band, ...
|
2. is adjusted to dead-band, ... deadband is implemented outside the command manager
|
||||||
3. then adjusted to offset, ...
|
3. then adjusted to offset, ...
|
||||||
4. then multiplied by factor, which ...
|
4. then multiplied by factor, which ...
|
||||||
5. is assigned to the FlightGear control property.
|
5. is assigned to the FlightGear control property.
|
||||||
|
@ -127,7 +161,9 @@ for noise or potentiometers of dubious quality by creating a threshold
|
||||||
below which any signal is ignored.
|
below which any signal is ignored.
|
||||||
|
|
||||||
The default of 0.1 for elevators and ailerons is very forgiving. A lower
|
The default of 0.1 for elevators and ailerons is very forgiving. A lower
|
||||||
number results in a tighter feel. Throttle defaults to 0.0
|
number results in a tighter feel. In some cases such as throttle you may
|
||||||
|
wish to not set a deadband. Use a value of 0.0 in this case.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
offset
|
offset
|
||||||
|
@ -148,102 +184,375 @@ Controls sensitivity of an axis. If the factor is too low it results in
|
||||||
control not reaching its maximum possible limit. Negating the number will result in
|
control not reaching its maximum possible limit. Negating the number will result in
|
||||||
the control moving counter to the default. The default value is 1.0, think unity gain.
|
the control moving counter to the default. The default value is 1.0, think unity gain.
|
||||||
|
|
||||||
In my case, throttle behaviour was inverted from what I preferred.
|
In my case, throttle behavior was inverted from what I preferred.
|
||||||
I set this value to -1.0 and everything was groovy.
|
I set this value to -1.0 and everything was groovy.
|
||||||
|
|
||||||
|
|
||||||
|
The Command Manager
|
||||||
|
-------------------
|
||||||
|
Previous versions of FGFS allowed joystick output to be bound directly
|
||||||
|
to the property manager. This has changed for FGFS v0.7.7 and now events
|
||||||
|
are bound to commands. Commands *must* be specified for a binding to have
|
||||||
|
an effect. The current list of commands is broken down here into two
|
||||||
|
categories, mainly for my convenience.
|
||||||
|
|
||||||
Button properties
|
Visual And File Related:
|
||||||
|
|
||||||
switch
|
command options used for
|
||||||
A button designated a switch is either on or off. While the button is
|
------- ------- --------
|
||||||
held in the switch is engaged. Brakes are described as a switch and take
|
null none useful for clearing a previous binding
|
||||||
additional parameters [ step, repeatable ]
|
exit none Exiting FGFS
|
||||||
|
load file name* Load a saved flight
|
||||||
|
save file name* Save current flight
|
||||||
|
load-panel path ** Change/reload panel
|
||||||
|
load-preferences path ** Load preferences ***
|
||||||
|
screen-capture none Save a screenshot to ./fgfs-screen.ppm
|
||||||
|
view-cycle none Change the direction of the pilots view
|
||||||
|
|
||||||
adjust
|
*Saved/loaded relative to current working directory.
|
||||||
A button designated adjust is for controls that have a range
|
**The path includes the filename you wish to load and is relative to $FG_ROOT,
|
||||||
of settings, for example elevator trim and flaps. These are found
|
which is the location of the installed base package. The default for load-panel
|
||||||
in pairs having opposing values for the parameter 'step'.
|
is the value of /sim/panel/path (from preferences.xml) or if that is unset
|
||||||
The 'repeatable' parameter should be appropriate to the type of control.
|
Panel/Default/default.xml. The default for load preferences is preferences.xml.
|
||||||
|
***This might make a good first binding to experiment with, since it's not currently
|
||||||
|
bound to anything. Reloading preferences will allow you to test settings
|
||||||
|
without having to sit through a restart of FGFS for every edit. You can
|
||||||
|
always (re)move it later.
|
||||||
|
|
||||||
step
|
Flight Control:
|
||||||
This defines how much adjustment is applied when the button is activated
|
command options effect
|
||||||
Default values are 1.0 for brakes (full on), 0.001 / -0.001 for
|
------- ------- ------
|
||||||
elevator trim and -0.34 / 0.34 for flaps
|
property-toggle property toggle the property full on
|
||||||
|
property-assign "" "", value targets a property for action
|
||||||
|
property-adjust "" "", step Increment size for changes
|
||||||
|
property-swap "" ""[0], "" ""[1] Set values in a switch
|
||||||
|
property-scale "" "", offset, factor Processes the raw joystick value
|
||||||
|
|
||||||
repeatable
|
|
||||||
In this case repeatable means when the button is held down the value continues
|
|
||||||
to increment. repeatable is a true / false value. The default for brakes is
|
|
||||||
false. This is appropriate since by default brakes are a switch that are full
|
|
||||||
on. Elevator trim on the other hand defaults to true. Holding down the
|
|
||||||
button for elevator trim will cause a continuous adjustment until the button
|
|
||||||
is released. Being a fine adjustment this is appropriate behaviour. Flaps
|
|
||||||
on the otherhand default to false. Clicking the flaps button will cause the
|
|
||||||
flaps to be extended to the first detent, subsequent clicks will extend or
|
|
||||||
retract by one increment. Being a large adjustment with a major impact on a
|
|
||||||
planes handling this is a good thing.
|
|
||||||
|
|
||||||
Syntax for properties in .fgfsrc
|
Bindings
|
||||||
|
--------
|
||||||
|
A command may have more than one binding. By default, the examples below
|
||||||
|
use just /binding or <binding>, but /binding[0] or <binding n="0"> is implied.
|
||||||
|
When bindings are specified in XML the indices are created automagically. If
|
||||||
|
you wish to avoid XML you must supply the index number for multiple bindings
|
||||||
|
in your command line formatted options.
|
||||||
|
Multiple properties in a single binding must have the index specified. For
|
||||||
|
example if you build a switch that loads alternate panels the XML form
|
||||||
|
must be written thusly:
|
||||||
|
|
||||||
Here is a listing of the defaults as they would appear in .fgfsrc
|
<command>property-swap</command>
|
||||||
You only need entries where the defaults aren't what you want.
|
<property n="0">/sim/panel/path=foo</property>
|
||||||
In my case I had to make entries to put the throttle on axis2.
|
<property n="1">/sim/panel/path=bar</property>
|
||||||
|
|
||||||
// Default axis 0 to aileron
|
|
||||||
--prop:/input/js0/axis0/control=/controls/aileron
|
|
||||||
--prop:/input/js0/axis0/dead-band=0.1
|
|
||||||
|
|
||||||
// Default axis 1 to elevator
|
|
||||||
--prop:/input/js0/axis1/control=/controls/elevator
|
|
||||||
--prop:/input/js0/axis1/dead-band=0.1
|
|
||||||
--prop:/input/js0/axis1/factor=-1.0
|
|
||||||
|
|
||||||
// Default axis 2 to rudder
|
Joystick Axes
|
||||||
--prop:/input/js0/axis2/control=/controls/rudder
|
-------------
|
||||||
--prop:/input/js0/axis2/dead-band=0.1
|
|
||||||
|
|
||||||
// Default axis 3 to throttle
|
Here's a sample Joystick axis declaration in XML:
|
||||||
--prop:/input/js0/axis3/control=/controls/throttle
|
|
||||||
--prop:/input/js0/axis3/dead-band=0.0
|
|
||||||
--prop:/input/js0/axis3/offset=-1.0
|
|
||||||
--prop:/input/js0/axis3/factor=-0.5
|
|
||||||
|
|
||||||
// Default button 0 to all brakes
|
<axis n="0"> <!-- target an axis -->
|
||||||
--prop:/input/js0/button0/action=switch
|
<desc>Aileron</desc> <!-- descriptive name (optional) -->
|
||||||
--prop:/input/js0/button0/control=/controls/brakes/all
|
<binding> <!-- open a container for the binding -->
|
||||||
--prop:/input/js0/button0/step=1.0
|
<command>property-scale</command> <!-- pick a command -->
|
||||||
--prop:/input/js0/button0/repeatable=false
|
<property>/controls/aileron</property> <!-- target a property -->
|
||||||
|
</binding> <!-- closing tag for binding -->
|
||||||
|
</axis> <!-- closing tag for axis -->
|
||||||
|
|
||||||
// Default button 1 to left brake.
|
Remember how I said the property tree was a hierarchy? Thoughtful readers
|
||||||
--prop:/input/js0/button1/action=switch
|
will notice how the nested tags keep things organized.
|
||||||
--prop:/input/js0/button1/control=/controls/brakes/left
|
This binding appears in the context /input/joysticks/js/, so the
|
||||||
--prop:/input/js0/button1/step=1.0
|
command-line option equivalent of this declaration (leaving out the
|
||||||
--prop:/input/js0/button1/repeatable=false
|
'desc', which isn't strictly necessary), is
|
||||||
|
|
||||||
// Default button 2 to right brake.
|
--prop:/input/joysticks/js[0]/axis[0]/binding/command=property-scale
|
||||||
--prop:/input/js0/button2/action=switch
|
--prop:/input/joysticks/js[0]/axis[0]/binding/property=/controls/aileron
|
||||||
--prop:/input/js0/button2/control=/controls/brakes/right
|
|
||||||
--prop:/input/js0/button2/step=1.0
|
|
||||||
--prop:/input/js0/button2/repeatable=false
|
|
||||||
|
|
||||||
// Default buttons 3 and 4 to elevator trim
|
Do you see how the command line versions uses a path to represent the hierarchy?
|
||||||
--prop:/input/js0/button3/action=adjust
|
Cool! You should read README.xmlpanel next, working with FGFS XML configuration
|
||||||
--prop:/input/js0/button3/control=/controls/elevator-trim
|
system is easy and it's fun for the whole family! ( not sold in stores. excludes
|
||||||
--prop:/input/js0/button3/step=0.001
|
tax and title. void where prohibited by law.)
|
||||||
--prop:/input/js0/button3/repeatable=true
|
|
||||||
|
|
||||||
--prop:/input/js0/button4/action=adjust
|
Ok, back to business. The 'property-scale' command also recognizes 'offset' and
|
||||||
--prop:/input/js0/button4/control=/controls/elevator-trim
|
'factor' arguments. The "type" arguments shown in the following example are
|
||||||
--prop:/input/js0/button4/step=-0.001
|
specifying a double precision floating point number. A double has more discrete
|
||||||
--prop:/input/js0/button4/repeatable=true
|
steps and gives a smoother action than a plain float.
|
||||||
|
|
||||||
// Default buttons 5 and 6 to flaps
|
<axis n="2">
|
||||||
--prop:/input/js0/button5/action=adjust
|
<desc>Throttle</desc>
|
||||||
--prop:/input/js0/button5/control=/controls/flaps
|
<!-- See important note about dead-band below -->
|
||||||
--prop:/input/js0/button5/step=-0.34
|
<binding>
|
||||||
--prop:/input/js0/button5/repeatable=false
|
<command>property-scale</command>
|
||||||
|
<property>/controls/throttle</property>
|
||||||
|
<offset type="double">-1.0</offset>
|
||||||
|
<factor type="double">-0.5</factor>
|
||||||
|
</binding>
|
||||||
|
</axis>
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
--prop:/input/joysticks/js[0]/axis[2]/binding/command=property-scale
|
||||||
|
--prop:/input/joysticks/js[0]/axis[2]/binding/property=/controls/throttle
|
||||||
|
--prop:/input/joysticks/js[0]/axis[2]/binding/offset=-1.0
|
||||||
|
--prop:/input/joysticks/js[0]/axis[2]/binding/factor=-0.5
|
||||||
|
|
||||||
|
*Important Note About dead-band*
|
||||||
|
--------------------------------
|
||||||
|
You may recall from the section about raw axis value modifiers that dead-band
|
||||||
|
is implemented outside the command manager. This means that if you want to apply
|
||||||
|
a dead-band, the tag *must* precede the binding tag. If you are using the command
|
||||||
|
line format you must omit the 'binding' part like so:
|
||||||
|
|
||||||
|
--prop:/input/joysticks/js[0]/axis[2]/dead-band=0.005
|
||||||
|
|
||||||
|
Joystick Button Properties
|
||||||
|
--------------------------
|
||||||
|
Buttons, being boolean by nature, can use a little help. By this I mean that there
|
||||||
|
are times when you need momentary action, times where you need a repeating action
|
||||||
|
and sometimes you just want a plain old toggle. In order to facilitate this need
|
||||||
|
we have some tags that modify the actions of buttons.
|
||||||
|
|
||||||
|
<repeatable>
|
||||||
|
<!-- Will be either true or false. If it is true, holding down a button (or key) will
|
||||||
|
cause repeated events, say, for moving the trim; if false (the default), pressing
|
||||||
|
a key will cause only a single event. -->
|
||||||
|
|
||||||
|
<step>
|
||||||
|
<!-- The property-adjust command takes a 'step' argument specifying the
|
||||||
|
amount of the adjustment for each event. In the following example, the elevator
|
||||||
|
trim moves 0.1% for each event (without automatic repetition, you'd
|
||||||
|
have a pretty sore finger). -->
|
||||||
|
|
||||||
|
<value>
|
||||||
|
<!-- Use value on non-repeatables to supply the value for each consecutive press-->
|
||||||
|
|
||||||
|
<mod-up>
|
||||||
|
<!-- This stands for "modifier up", my favorite I think. This is used to set up a binding
|
||||||
|
for when you *release* a key. As you'll see, it comes in handy -->
|
||||||
|
|
||||||
|
Here's a sample joystick button declaration in XML:
|
||||||
|
|
||||||
|
<button n="1"> <!-- target a button -->
|
||||||
|
<desc>Elevator trim up</desc> <!-- optional description -->
|
||||||
|
<repeatable>true</repeatable> <!-- Ok, repeatable is outside the command manager too -->
|
||||||
|
<binding> <!-- Open the "binding" node of the tree-->
|
||||||
|
<command>property-adjust</command> <!-- pick a command type to bind -->
|
||||||
|
<property>/controls/elevator-trim</property> <!-- target a property -->
|
||||||
|
<step type="double">0.001</step>
|
||||||
|
</binding>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
In command-line option syntax, this would appear as
|
||||||
|
|
||||||
|
--prop:/input/joysticks/js[0]/button[1]/repeatable=true <!-- See? no 'binding' -->
|
||||||
|
--prop:/input/joysticks/js[0]/button[1]/binding/command=property-adjust
|
||||||
|
--prop:/input/joysticks/js[0]/button[1]/binding/property=/controls/elevator-trim
|
||||||
|
--prop:/input/joysticks/js[0]/button[1]/binding//step=0.001
|
||||||
|
|
||||||
|
|
||||||
|
Here's a slightly fancier declaration, that applies the left (differential) brakes
|
||||||
|
when button 4 is pressed, and releases them automatically when the user releases the
|
||||||
|
button:
|
||||||
|
|
||||||
|
<button n="4">
|
||||||
|
<desc>Left brake</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">1.0</value> <!-- brakes are a toggle so 1.0 represents on -->
|
||||||
|
</binding>
|
||||||
|
<mod-up> <!-- it's not a parking brake so we need to release it -->
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">0.0</value> <!-- 1.0 is on so 0.0 is off, right? -->
|
||||||
|
</binding>
|
||||||
|
</mod-up>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
The first binding is straight-forward: when the button is pressed, the
|
||||||
|
'property-assign' command assigns the value 1.0 (i.e. full) to the left brake
|
||||||
|
property. The second binding, however, is nested inside a 'mod-up' element,
|
||||||
|
it will be fired when the user *releases* the button, and will use the
|
||||||
|
'property-assign' command to assign the value 0.0 (i.e. none) to the left brake
|
||||||
|
property. Repetition is left at the default value of false, so that the same
|
||||||
|
value will not be assigned over and over again.
|
||||||
|
|
||||||
|
Here's the command-line equivalent:
|
||||||
|
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/binding/command=property-assign
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/binding/property=/controls/brakes[0]
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/binding/value=1.0
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/mod-up/binding/command=property-assign
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/mod-up/binding/property=/controls/brakes[0]
|
||||||
|
--prop:/input/joysticks/js[0]/button[4]/mod-up/binding/value=0.0
|
||||||
|
|
||||||
|
Remember that more than one binding can be included in each context. Here's a
|
||||||
|
very hairy example from the default bindings that fires all three brakes when
|
||||||
|
button 0 is pressed, and releases all three when button 0 is released:
|
||||||
|
|
||||||
|
<button n="0">
|
||||||
|
<desc>Brakes</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">1.0</value>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[1]</property>
|
||||||
|
<value type="double">1.0</value>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[2]</property>
|
||||||
|
<value type="double">1.0</value>
|
||||||
|
</binding>
|
||||||
|
<mod-up>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">0.0</value>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[1]</property>
|
||||||
|
<value type="double">0.0</value>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[2]</property>
|
||||||
|
<value type="double">0.0</value>
|
||||||
|
</binding>
|
||||||
|
</mod-up>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
For people who take pleasure in avoiding XML, here's the command-line
|
||||||
|
equivalent (note the subscripts to distinguish multiple bindings; the
|
||||||
|
XML will handle this automatically):
|
||||||
|
|
||||||
|
--prop:/input/joysticks/button[0]/binding[0]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/binding[0]/property=/controls/brakes[0]
|
||||||
|
--prop:/input/joysticks/button[0]/binding[0]/value=1.0
|
||||||
|
--prop:/input/joysticks/button[0]/binding[1]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/binding[1]/property=/controls/brakes[1]
|
||||||
|
--prop:/input/joysticks/button[0]/binding[1]/value=1.0
|
||||||
|
--prop:/input/joysticks/button[0]/binding[2]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/binding[2]/property=/controls/brakes[2]
|
||||||
|
--prop:/input/joysticks/button[0]/binding[2]/value=1.0
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[0]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[0]/property=brakes[0]
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[0]/value=0.0
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[1]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[1]/property=brakes[1]
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[1]/value=0.0
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[2]/command=property-assign
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[2]/property=brakes[2]
|
||||||
|
--prop:/input/joysticks/button[0]/mod-up/binding[2]/value=0.0
|
||||||
|
|
||||||
|
|
||||||
|
This is a good time to remind you that command line formatted options are used
|
||||||
|
in your .fgfsrc file. You can put them in $FG_ROOT/system.fgfsrc to make them
|
||||||
|
global.
|
||||||
|
|
||||||
|
|
||||||
|
Keyboard Bindings
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Keyboard bindings are almost exactly identical to joystick-button
|
||||||
|
bindings, as in the following example (the context is
|
||||||
|
/input/keyboard):
|
||||||
|
|
||||||
|
<key n="1">
|
||||||
|
<name>Ctrl-A</name>
|
||||||
|
<desc>Toggle autopilot altitude lock.</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-toggle</command>
|
||||||
|
<property>/autopilot/locks/altitude</property>
|
||||||
|
</binding>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
There are a few gotcha's though. First, the index of the key
|
||||||
|
specifies the key code that you're binding; in the above example, '1'
|
||||||
|
corresponds to Ctrl-A (as mentioned in the friendly comment). Regular
|
||||||
|
key codes go up to 255; codes from 256 up represent special keys like
|
||||||
|
function and arrow keys (you can get the value from include/GL/glut.h,
|
||||||
|
but adding 256 to the special key code). Here is the command-line
|
||||||
|
equivalent of the above, leaving out the documentation properties:
|
||||||
|
|
||||||
|
--prop:/input/keyboard/key[1]/binding/command=property-toggle
|
||||||
|
--prop:/input/keyboard/key[1]/binding/property=/autopilot/locks/altitude
|
||||||
|
|
||||||
|
(The 'property-toggle' command switches a boolean value between true and
|
||||||
|
false, so it needs no arguments except for the property name.) DON'T
|
||||||
|
LEAVE OUT THE INDEX!!!
|
||||||
|
|
||||||
|
The second gotcha is that keys can take more modifiers than joystick
|
||||||
|
buttons. In addition to mod-up (representing the key release), a key
|
||||||
|
may use any combination of nested 'mod-alt', 'mod-ctrl', and
|
||||||
|
'mod-shift' modifiers, as in the following example:
|
||||||
|
|
||||||
|
<key n="49">
|
||||||
|
<name>1</name>
|
||||||
|
<mod-shift>
|
||||||
|
<desc>Look back left</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/sim/view/goal-offset</property>
|
||||||
|
<value type="double">135</value>
|
||||||
|
</binding>
|
||||||
|
</mod-shift>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
In this example, the '1' key combined with shift causes the view to
|
||||||
|
switch to back left. Note that this will work only with the keypad 1,
|
||||||
|
since pressing shift+1 on the regular keyboard will give a '!'
|
||||||
|
character instead.
|
||||||
|
|
||||||
|
The input module tries to be smart about supplying control and shift
|
||||||
|
modifiers automatically where they make sense -- note that it wasn't
|
||||||
|
necessary to use a nested 'mod-ctrl' element for the ctrl-A binding
|
||||||
|
earlier, since a keycode less that 32 implies a control character
|
||||||
|
anyway.
|
||||||
|
|
||||||
|
With the new input module, the key-up events can also be detected for
|
||||||
|
the keyboard, so it's possible to have touch-sensitive brakes (etc.)
|
||||||
|
just as with the joystick:
|
||||||
|
|
||||||
|
<key n="44">
|
||||||
|
<name>,</name>
|
||||||
|
<desc>Left brake</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">1.0</value>
|
||||||
|
</binding>
|
||||||
|
<mod-up>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
<value type="double">0.0</value>
|
||||||
|
</binding>
|
||||||
|
</mod-up>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
Now here is a different way to bind a brake. In this example, there is
|
||||||
|
no <mod-up> tag, so it *does* work like a parking brake.
|
||||||
|
|
||||||
|
<key n="66">
|
||||||
|
<name>B</name>
|
||||||
|
<desc>Toggle parking brake on or off</desc>
|
||||||
|
<binding>
|
||||||
|
<command>property-toggle</command>
|
||||||
|
<property>/controls/brakes[0]</property>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-toggle</command>
|
||||||
|
<property>/controls/brakes[1]</property>
|
||||||
|
</binding>
|
||||||
|
<binding>
|
||||||
|
<command>property-toggle</command>
|
||||||
|
<property>/controls/brakes[2]</property>
|
||||||
|
</binding>
|
||||||
|
</key>
|
||||||
|
|
||||||
--prop:/input/js0/button6/action=adjust
|
|
||||||
--prop:/input/js0/button6/control=/controls/flaps
|
|
||||||
--prop:/input/js0/button6/step=0.34
|
|
||||||
--prop:/input/js0/button6/repeatable=false
|
|
||||||
|
|
Loading…
Reference in a new issue