Added Docs directory and start populating it.
Added Files: README.Joystick README.xmlpanel
This commit is contained in:
parent
e7ef251807
commit
3c0a328e46
2 changed files with 1186 additions and 0 deletions
550
Docs/README.Joystick
Normal file
550
Docs/README.Joystick
Normal file
|
@ -0,0 +1,550 @@
|
|||
Users Guide to FGInput - Joystick And Keyboard Bindings For FlightGear
|
||||
Or
|
||||
"The document formerly know as The Users Guide to Joystick Usage Under
|
||||
FlightGear Flight Simulator"
|
||||
|
||||
version 0.7.7.2 07/02/2001
|
||||
Author John Check <j4strngs@rockfish.net>
|
||||
|
||||
This document is written with versions of FlightGear 0.7.7 and greater
|
||||
in mind. It assumes a working joystick present on your system. It
|
||||
is written from the perspective a Linux user, but the information presented
|
||||
is valid on other platforms. The most current version can be found at:
|
||||
|
||||
http://rockfish.net/shell/aboutFGInput.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:
|
||||
------------
|
||||
Earlier versions of FGFS had assignments of joystick axis/buttons
|
||||
and key bindings hard coded. If you had a joystick that did not use
|
||||
the default channel assignments, or wanted different key bindings
|
||||
you had to edit the source code and recompile.
|
||||
|
||||
Fortunately, around about v0.7.5 a "property manager" was implemented,
|
||||
which facilitated being able to set the parameters for the joystick at runtime.
|
||||
Version 0.7.7 saw an expanded role for the property manager and the
|
||||
addition of a "command manager" that allows for binding of events to commands.
|
||||
The code that does this is known as FGInput and is used to configure
|
||||
keyboard command bindings as well as joysticks.
|
||||
|
||||
Storing alternate keyboard or joystick bindings can be done in a variety of ways.
|
||||
The order of precedence for options is thus:
|
||||
|
||||
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:
|
||||
--------------------------------
|
||||
FlightGear ships with a utility called js_demo. It will report
|
||||
the number of joysticks attached to a system and their capabilites.
|
||||
By observing the output of js_demo while working your joystick you can
|
||||
determine what controls are where.
|
||||
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.
|
||||
The output shown is from an analog Gravis BlackHawk with four buttons and
|
||||
a throttle.
|
||||
|
||||
Typical output of js_demo:
|
||||
|
||||
Joystick test program.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
Joystick 1 not detected <!-- remember we start at 0 -->
|
||||
Joystick 2 not detected
|
||||
+---------------JS.0-----------------+
|
||||
| Btns Ax:0 Ax:1 Ax:2 |
|
||||
+------------------------------------+
|
||||
| 0000 +0.0 +0.0 -1.0 . . . |
|
||||
|
||||
The buttons are handled internally as a binary number in which bit 0 (the
|
||||
least significant bit) represents button 0, bit 1 represents button 1, etc.,
|
||||
but this number is displayed on the screen in hexadecimal notation, so:
|
||||
0001 => button 0 pressed
|
||||
0002 => button 1 pressed
|
||||
0004 => button 2 pressed
|
||||
0008 => button 3 pressed
|
||||
0010 => button 4 pressed
|
||||
0020 => button 5 pressed
|
||||
0040 => button 6 pressed
|
||||
... etc. up to ...
|
||||
8000 => button 15 pressed
|
||||
... and ...
|
||||
0014 => buttons 2 and 4 pressed simultaneously
|
||||
... etc.
|
||||
|
||||
|
||||
Default Joystick properties:
|
||||
----------------------------
|
||||
|
||||
Axis 0 = Aileron
|
||||
Axis 1 = Elevator
|
||||
Axis 2 = Rudder
|
||||
Axis 3 = Throttle
|
||||
Button 0 = All brakes
|
||||
Button 1 = Elevator trim (up)
|
||||
Button 2 = Elevator trim (down)
|
||||
|
||||
|
||||
Okay, Now what?
|
||||
---------------
|
||||
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
|
||||
|
||||
1. The raw axis value ...
|
||||
2. is adjusted to dead-band, ... deadband is implemented outside the command manager
|
||||
3. then adjusted to offset, ...
|
||||
4. then multiplied by factor, which ...
|
||||
5. is assigned to the FlightGear control property.
|
||||
|
||||
Put another way....
|
||||
|
||||
cooked_value = (( raw_value > dead-band ) + offset) * factor
|
||||
|
||||
|
||||
Axis properties:
|
||||
|
||||
dead-band
|
||||
|
||||
-1 0 1
|
||||
.......................
|
||||
-1 | | 1
|
||||
^
|
||||
dead-band
|
||||
|
||||
|
||||
This is an area where signals are ignored. It is used to compensate
|
||||
for noise or potentiometers of dubious quality by creating a threshold
|
||||
below which any signal is ignored.
|
||||
|
||||
The default of 0.1 for elevators and ailerons is very forgiving. A lower
|
||||
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
|
||||
|
||||
-1 0 1
|
||||
.......................
|
||||
-1 ^ 1
|
||||
offset
|
||||
|
||||
Used to maximize a controls use of it's axis, as in the case of a
|
||||
throttle where zero would be a minimum and not a center point like in the case
|
||||
of a rudder. Typical value -1.0.
|
||||
|
||||
|
||||
factor
|
||||
|
||||
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
|
||||
the control moving counter to the default. The default value is 1.0, think unity gain.
|
||||
|
||||
In my case, throttle behavior was inverted from what I preferred.
|
||||
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.
|
||||
|
||||
Visual And File Related:
|
||||
|
||||
command options used for
|
||||
------- ------- --------
|
||||
null none useful for clearing a previous binding
|
||||
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
|
||||
|
||||
*Saved/loaded relative to current working directory.
|
||||
**The path includes the filename you wish to load and is relative to $FG_ROOT,
|
||||
which is the location of the installed base package. The default for load-panel
|
||||
is the value of /sim/panel/path (from preferences.xml) or if that is unset
|
||||
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.
|
||||
|
||||
Flight Control:
|
||||
command options effect
|
||||
------- ------- ------
|
||||
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
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Joystick Axes
|
||||
-------------
|
||||
|
||||
Here's a sample Joystick axis declaration in XML:
|
||||
|
||||
<axis n="0"> <!-- target an axis -->
|
||||
<desc>Aileron</desc> <!-- descriptive name (optional) -->
|
||||
<binding> <!-- open a container for the binding -->
|
||||
<command>property-scale</command> <!-- pick a command -->
|
||||
<property>/controls/aileron</property> <!-- target a property -->
|
||||
</binding> <!-- closing tag for binding -->
|
||||
</axis> <!-- closing tag for axis -->
|
||||
|
||||
Remember how I said the property tree was a hierarchy? Thoughtful readers
|
||||
will notice how the nested tags keep things organized.
|
||||
This binding appears in the context /input/joysticks/js/, so the
|
||||
command-line option equivalent of this declaration (leaving out the
|
||||
'desc', which isn't strictly necessary), is
|
||||
|
||||
--prop:/input/joysticks/js[0]/axis[0]/binding/command=property-scale
|
||||
--prop:/input/joysticks/js[0]/axis[0]/binding/property=/controls/aileron
|
||||
|
||||
Do you see how the command line versions uses a path to represent the hierarchy?
|
||||
Cool! You should read README.xmlpanel next, working with FGFS XML configuration
|
||||
system is easy and it's fun for the whole family! ( not sold in stores. excludes
|
||||
tax and title. void where prohibited by law.)
|
||||
|
||||
Ok, back to business. The 'property-scale' command also recognizes 'offset' and
|
||||
'factor' arguments. The "type" arguments shown in the following example are
|
||||
specifying a double precision floating point number. A double has more discrete
|
||||
steps and gives a smoother action than a plain float.
|
||||
|
||||
<axis n="2">
|
||||
<desc>Throttle</desc>
|
||||
<!-- See important note about dead-band below -->
|
||||
<binding>
|
||||
<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>
|
||||
|
636
Docs/README.xmlpanel
Normal file
636
Docs/README.xmlpanel
Normal file
|
@ -0,0 +1,636 @@
|
|||
Users Guide to FlightGear panel configuration
|
||||
Version 0.7.7.1, June 23 2001
|
||||
Author: John Check <j4strngs@rockfish.net>
|
||||
|
||||
This document describes the configuration of
|
||||
FlightGear flight simulator's aircraft panel display via XML.
|
||||
The information was culled from the fgfs-devel@flightgear.org
|
||||
mailing list and my experiences making alternate panels.
|
||||
Corrections and additions are encouraged.
|
||||
|
||||
Some History:
|
||||
------------
|
||||
Older versions of FGFS had a hard coded display of instruments.
|
||||
This was a less than ideal state of affairs due to FGFS ability
|
||||
to use different aircraft models. Being primarily developed on
|
||||
UNIX type systems, a modular approach is taken towards the
|
||||
simulation. To date, most alternatives to the default
|
||||
Cessna 172 aircraft are the product of research institutions
|
||||
interested in the flight characteristics and not cosmetics.
|
||||
The result of this was that one could fly the X-15 or a Boeing 747
|
||||
but be limited to C172 instrumentation.
|
||||
|
||||
A rewrite of the panel display code was done around v0.7.5 by
|
||||
developer David Megginson allowing for configuration of the panel
|
||||
via XML to address this limitation. Some major changes and additions
|
||||
were made during the course of version 0.7.7 necessitating a rewrite
|
||||
and expansion of this document.
|
||||
|
||||
|
||||
About The Property Manager:
|
||||
--------------------------
|
||||
While intimate knowledge of the property manager is unnecessary to create
|
||||
aircraft panels, some familiarity with the concept is required.
|
||||
FlightGear provides a hierarchical representation of all aspects of
|
||||
the state of the running simulation that is known as the property tree.
|
||||
Some properties, such as velocities, are read only. Others such as the frequencies
|
||||
to which the navcom radios are tuned or the position of control surfaces
|
||||
can be set by various means.
|
||||
|
||||
FlightGear can optionally provide an interface to these properties for external
|
||||
applications such as Atlas, the moving map program, or even lowly telnet via
|
||||
a network socket. Data can even be routed to a serial port and connected to
|
||||
say, a GPS receiver.
|
||||
Aside from its usefulness in a flight training context, being able to manipulate
|
||||
the property tree on a running copy of FG allows for switching components on the fly,
|
||||
a positive boon for panel authors.
|
||||
To see the property tree start FG with the following command line:
|
||||
|
||||
fgfs --props=socket,bi,5,localhost,5500,tcp
|
||||
|
||||
Then use telnet to connect to localhost on port 5500. You can browse the
|
||||
tree as you would a filesystem.
|
||||
|
||||
XML and the Property Manager:
|
||||
----------------------------
|
||||
Panel instruments interface with the property tree to get/set values as
|
||||
appropriate. Properties for which FG doesn't yet provide a value can be
|
||||
created by simply making them up. Values can be adjusted using the telnet
|
||||
interface allowing for creation and testing of instruments while code to
|
||||
drive them is being developed.
|
||||
|
||||
If fact, the XML configuration system allows a user to combine
|
||||
components such as flight data model, aircraft exterior model,
|
||||
heads up display, and of course control panel. Furthermore,
|
||||
such a preconfigured aircraft.xml can be included into a scenario
|
||||
with specific flight conditions. These can be manually specified or
|
||||
a FG session can be saved and/or edited and reloaded later. Options specified
|
||||
in these files can be overridden on the command line. For example:
|
||||
|
||||
--prop:/sim/panel/path=Aircraft/c172/Panels/c172-panel.xml
|
||||
|
||||
passed as an option, would override a panel specified elsewhere.
|
||||
Property tree options all have the same format, specify the node
|
||||
and supply it a value.
|
||||
|
||||
The order of precedence for options is thus:
|
||||
|
||||
Source Location Format
|
||||
------ -------- ------
|
||||
command line
|
||||
.fgfsrc Users home directory. command line options
|
||||
system.fgfsrc $FG_ROOT "" ""
|
||||
preferences.xml $FG_ROOT XML property list
|
||||
|
||||
|
||||
Loading Panels on the fly:
|
||||
-------------------------
|
||||
When editing a panel configuration, pressing Shift +F3 will reload the
|
||||
panel. If your changes don't seem to be taking effect, check the console output.
|
||||
It will report the success or failure of the panel reload*. Editing textures requires
|
||||
restarting FGFS so the new textures can be loaded. Panels can be switched on the fly
|
||||
by setting the /sim/panel/path property value and reloading.
|
||||
|
||||
Regarding Window Geometry:
|
||||
-------------------------
|
||||
For the sake of simplicity the FGFS window is always considered to be 1024x768
|
||||
so all x/y values for instrument placement should relative to these dimensions.
|
||||
Since FG uses OpenGL 0,0 represents the lower left hand corner of the
|
||||
screen. Panels may have a virtual size larger than 1024x768. Vertical scrolling is accomplished
|
||||
with Shift+F5/F6. Horizontal scrolling is via Shift+F7/F8. An offset should be supplied
|
||||
to set the default visible area. It is possible to place items to overlap the 3D viewport.
|
||||
|
||||
Panel Architecture:
|
||||
-------------------
|
||||
All of the panel configuration files are XML-encoded* property lists.
|
||||
The root element of each file is always named <PropertyList>. Tags are
|
||||
almost always found in pairs, with the closing tag having a slash prefixing
|
||||
the tag name, i.e </PropertyList>. The exception is the tag representing an aliased
|
||||
property. In this case a slash is prepended to the closing angle bracket.
|
||||
(see section Aliasing)
|
||||
|
||||
The top level panel configuration file is composed of a <name>, a <background>
|
||||
texture and zero or more <instruments>.
|
||||
|
||||
[ Paths are relative to $FG_ROOT ( the installed location of FGFS data files ). ]
|
||||
[ Absolute paths may be used. Comments are bracketed with <!-- -->. ]
|
||||
|
||||
Example Top Level Panel Config:
|
||||
----------------------------------------
|
||||
<PropertyList>
|
||||
<name>Example Panel</name>
|
||||
<background>Aircraft/c172/Panels/Textures/panel-bg.rgb</background>
|
||||
<w>1024</w> <!-- virtual width -->
|
||||
<h>768</h> <!-- virtual height -->
|
||||
<y-offset>-305</y-offset> <!-- hides the bottom part -->
|
||||
<view-height>172</view-height> <!-- amount of overlap between 2D panel and 3D viewport -->
|
||||
|
||||
<instruments>
|
||||
|
||||
<instrument include="../Instruments/clock.xml">
|
||||
<name>Chronometer</name> <!-- currently optional but strongly recommended -->
|
||||
<x>150</x> <!-- required horizontal placement -->
|
||||
<y>645</y> <!-- required vertical placement -->
|
||||
<w>72</w> <!-- optional width specification -->
|
||||
<h>72</h> <!-- optional height specification -->
|
||||
</instrument>
|
||||
|
||||
</instruments>
|
||||
|
||||
</PropertyList>
|
||||
|
||||
|
||||
Indexed Properties
|
||||
------------------
|
||||
The property manager assigns incremental indices to repeated
|
||||
properties with the same parent node, so that
|
||||
|
||||
<PropertyList>
|
||||
<x>1</x>
|
||||
<x>2</x>
|
||||
<x>3</x>
|
||||
</PropertyList>
|
||||
|
||||
shows up as
|
||||
|
||||
/x[0] = 1
|
||||
/x[1] = 2
|
||||
/x[2] = 3
|
||||
|
||||
In fact, the panel I/O code insists that every instrument have the XML element
|
||||
name "instrument", every layer have the name "layer", every text chunk have the
|
||||
name "chunk", every action have the name "action", and every transformation
|
||||
have the name "transformation" -- this makes the XML more regular (so
|
||||
that it can be created in a DTD-driven tool) and also allows us to
|
||||
include other kinds of information (such as doc strings) in the lists
|
||||
without causing confusion.
|
||||
|
||||
Inclusion:
|
||||
----------
|
||||
|
||||
Inclusion means that a node can include another property list as if it
|
||||
were a part of the current file.
|
||||
To clarify how inclusion works, consider the following examples:
|
||||
|
||||
If bar.xml contains
|
||||
|
||||
<PropertyList>
|
||||
<a>1</a>
|
||||
<b>
|
||||
<c>2</c>
|
||||
</b>
|
||||
</PropertyList>
|
||||
|
||||
then the declaration
|
||||
|
||||
<foo include="../bar.xml">
|
||||
</foo>
|
||||
|
||||
is exactly equivalent to
|
||||
|
||||
<foo>
|
||||
<a>1</a>
|
||||
<b>
|
||||
<c>2</c>
|
||||
</b>
|
||||
</foo>
|
||||
|
||||
However, it is also possible to selectively override properties in the
|
||||
included file. For example, if the declaration were
|
||||
|
||||
<foo include="../bar.xml">
|
||||
<a>3</a>
|
||||
</foo>
|
||||
|
||||
then the property manager would see
|
||||
|
||||
<foo>
|
||||
<a>3</a>
|
||||
<b>
|
||||
<c>2</c>
|
||||
</b>
|
||||
</foo>
|
||||
|
||||
with the original 'a' property's value replaced with 3.
|
||||
|
||||
Inclusion allows property files to be broken up and reused
|
||||
arbitrarily -- for example, there might be separate texture cropping
|
||||
property lists for commonly-used textures or layers, to avoid
|
||||
repeating the information in each instrument file.
|
||||
|
||||
|
||||
Aliasing
|
||||
--------
|
||||
Properties can alias other properties, similar to a symbolic link
|
||||
in Unix. When the target property changes value, the new value will
|
||||
show up in the aliased property as well. For example,
|
||||
|
||||
<PropertyList>
|
||||
<foo>3</foo>
|
||||
<bar alias="/foo"/>
|
||||
</PropertyList>
|
||||
|
||||
will look the same to the application as
|
||||
|
||||
<PropertyList>
|
||||
<foo>3</foo>
|
||||
<bar>3</bar>
|
||||
</PropertyList>
|
||||
|
||||
except that when foo changes value, bar will change too.
|
||||
|
||||
*IMPORTANT*
|
||||
-----------
|
||||
The combination of inclusions and aliases is very powerful, because it
|
||||
allows for parameterized property files. However, you must keep in
|
||||
mind that when an instrument is included by reference, its root is
|
||||
*not* the root of the property tree, therefore aliases must be relative.
|
||||
The relative location of the alias' root in the property hierarchy depends
|
||||
on whether the alias is used in a layer, a switch or an action.
|
||||
In lieu of snappy mnemonic, please use the following table.
|
||||
|
||||
when alias
|
||||
is used in go up
|
||||
--------- -----
|
||||
layer 5 ( ../../../../../params/foo )
|
||||
switch 3 ( ../../../params/foo )
|
||||
action 3 ( ../../../params/foo )
|
||||
|
||||
|
||||
As an example of inclusion and aliasing, consider the XML file
|
||||
for the NAVCOM radio, which includes a parameter subtree at the start,
|
||||
like this:
|
||||
|
||||
<PropertyList>
|
||||
<params>
|
||||
<comm-freq-prop>/radios/comm1/frequencies/selected</comm-freq-prop>
|
||||
<nav-freq-prop>/radios/nav1/frequencies/selected</nav-freq-prop>
|
||||
</params>
|
||||
|
||||
...
|
||||
|
||||
<chunk>
|
||||
<type>number-value</type>
|
||||
<property alias="../../../../../params/nav-freq-prop"/>
|
||||
</chunk>
|
||||
|
||||
...
|
||||
</PropertyList>
|
||||
|
||||
The same instrument file is used for navcomm1 and navcomm2 simply by
|
||||
overriding the parameters at inclusion in the top level panel property list.
|
||||
|
||||
<instrument include="../Instruments/navcomm.xml">
|
||||
<name>NAVCOM 1 radio</name>
|
||||
<params>
|
||||
<comm-freq-prop>/radios/comm1/frequencies/selected</comm-freq-prop>
|
||||
<nav-freq-prop>/radios/nav1/frequencies/selected</nav-freq-prop>
|
||||
</params>
|
||||
.....
|
||||
</instrument>
|
||||
|
||||
<instrument include="../Instruments/navcomm.xml">
|
||||
<name>NAVCOM 2 radio</name>
|
||||
<params>
|
||||
<comm-freq-prop>/radios/comm2/frequencies/selected</comm-freq-prop>
|
||||
<nav-freq-prop>/radios/nav2/frequencies/selected</nav-freq-prop>
|
||||
</params>
|
||||
.....
|
||||
</instrument>
|
||||
|
||||
Instrument Architecture:
|
||||
-----------------------
|
||||
Instruments are defined in separate configuration files. An instrument
|
||||
consists of a base width and height, one or more stacked layers,
|
||||
and zero or more actions. Base dimensions are specified as follows:
|
||||
|
||||
<PropertyList> <!-- remember, all xml files start like this -->
|
||||
<name>Airspeed Indicator</name> <!-- names are good -->
|
||||
<w-base>128</w-base> <!-- required width spec-->
|
||||
<h-base>128</h-base> <!-- required height spec-->
|
||||
<layers> <!-- begins layers section -->
|
||||
|
||||
Height and width can be overriden in the top level panel.xml by
|
||||
specifying <w> and <h>. Transformations are caculated against the base size
|
||||
regardless of the display size. This ensures that instruments remain calibrated.
|
||||
|
||||
Textures:
|
||||
--------
|
||||
FG uses red/green/blue/alpha .rgba files for textures. Dimensions for
|
||||
texture files should be power of 2 with a maximum 8:1 aspect ratio.
|
||||
The lowest common denominator for maximum texture size is 256 pixels.
|
||||
This is due to the limitations of certain video accelerators, most notably
|
||||
those with 3Dfx chipset such as the Voodoo2.
|
||||
|
||||
Instrument Layers**:
|
||||
-------------------
|
||||
The simplest layer is a <texture>. These can be combined in <switch> layers
|
||||
|
||||
<texture>
|
||||
A texture layer looks like this:
|
||||
|
||||
<layer> <!-- creates a layer -->
|
||||
<name>face</name>
|
||||
<texture> <!-- defines it as a texture layer -->
|
||||
<path>Aircraft/c172/Instruments/Textures/faces-2.rgb</path>
|
||||
<x1>0</x1> <!-- lower boundary for texture cropping-->
|
||||
<y1>0.51</y1> <!-- left boundary for texture cropping-->
|
||||
<x2>0.49</x2> <!-- upper boundary for texture cropping-->
|
||||
<y2>1.0</y2> <!-- right boundary for texture cropping-->
|
||||
</texture> <!-- closing texure tag -->
|
||||
</layer> <!-- closing layer tag -->
|
||||
|
||||
The texture cropping specification is represented as a decimal. There is a table
|
||||
at the end of this document for converting from pixel coordinates to percentages.
|
||||
|
||||
This particular layer, being a gauge face has no transformations applied to it.
|
||||
Layers with that aren't static *must* include <w> and <h> parameters to be visible.
|
||||
|
||||
<type> May be either text or switch..
|
||||
|
||||
<type>switch</type>
|
||||
A switch layer is composed of two or more nested layers and will display
|
||||
one of the nested layers based on a boolean property. For a simple example
|
||||
of a switch see $FG_ROOT/Aircraft/c172/Instruments/brake.xml.
|
||||
|
||||
<layer>
|
||||
<name>Brake light</name>
|
||||
<type>switch</type> <!-- define layer as a switch -->
|
||||
<property>/controls/brakes</property> <!-- tie it to a property -->
|
||||
<layer1> <!-- layer for true state -->
|
||||
<name>on</name> <!-- label to make life easy -->
|
||||
<texture> <!-- layer1 of switch is a texture layer -->
|
||||
<path>Aircraft/c172/Instruments/Textures/brake.rgb</path>
|
||||
<x1>0.25</x1>
|
||||
<y1>0.0</y1>
|
||||
<x2>0.5</x2>
|
||||
<y2>0.095</y2>
|
||||
</texture>
|
||||
<w>64</w> <!-- required width - layer isn't static -->
|
||||
<h>24</h> <!-- required height - layer isn't static -->
|
||||
</layer1> <!-- close layer1 of switch -->
|
||||
<layer2> <!-- layer for false state -->
|
||||
<name>off</name>
|
||||
<texture>
|
||||
<path>Aircraft/c172/Instruments/Textures/brake.rgb</path>
|
||||
<x1>0.0</x1>
|
||||
<y1>0.0</y1>
|
||||
<x2>0.25</x2>
|
||||
<y2>0.095</y2>
|
||||
</texture>
|
||||
<w>64</w>
|
||||
<h>24</h>
|
||||
</layer2>
|
||||
</layer>
|
||||
|
||||
Switches can have more than 2 states. This requires nesting one switch inside another.
|
||||
One could make, for example, a 3 color LED by nesting switch layers.
|
||||
|
||||
<type>text</type>
|
||||
A text layer may be static, as in a label, generated from a property or a combination of both.
|
||||
This example is a switch that contains both static and dynamic text:
|
||||
|
||||
<layer1> <!-- switch layer -->
|
||||
<name>display</name>
|
||||
<type>text</type> <!-- type == text -->
|
||||
<point-size>12</point-size> <!-- font size -->
|
||||
<color> <!-- specify rgb values to color text -->
|
||||
<red>1.0</red>
|
||||
<green>0.5</green>
|
||||
<blue>0.0</blue>
|
||||
</color> <!-- close color section -->
|
||||
<chunks> <!-- sections of text are referred to as chunks -->
|
||||
<chunk> <!-- first chunk of text -->
|
||||
<type>number-value</type> <!-- value defines it as dynamic -->
|
||||
<property>/radios/nav1/dme/distance</property> <!-- ties it to a property -->
|
||||
<scale>0.00053995680</scale> <!-- convert between statute and nautical miles? -->
|
||||
<format>%5.1f</format> <!-- define format -->
|
||||
</chunk>
|
||||
</chunks>
|
||||
</layer1>
|
||||
<layer2> <!-- switch layer -->
|
||||
<name>display</name>
|
||||
<type>text</type> <!-- type == text -->
|
||||
<point-size>10</point-size> <!-- font size -->
|
||||
<color> <!-- specify rgb values to color text -->
|
||||
<red>1.0</red>
|
||||
<green>0.5</green>
|
||||
<blue>0.0</blue>
|
||||
</color> <!-- close color section -->
|
||||
<chunks> <!-- sections of text are referred to as chunks -->
|
||||
<chunk> <!-- first chunk of text -->
|
||||
<type>literal</type> <!-- static text -->
|
||||
<text>---.--</text> <!-- fixed value -->
|
||||
</chunk>
|
||||
</chunks>
|
||||
</layer2>
|
||||
|
||||
|
||||
Transformations:
|
||||
---------------
|
||||
A transformation is a rotation, an x-shift, or a y-shift. Transformations
|
||||
can be static or they can be based on properties. Static rotations are
|
||||
useful for flipping textures horizontally or vertically. Transformations
|
||||
based on properties are useful for driving instrument needles. I.E. rotate the
|
||||
number of degrees equal to the airspeed. X and y shifts are relative to the
|
||||
center of the instrument. Each specified transformation type takes an <offset>.
|
||||
Offsets are relative to the center of the instrument. A shift without an offset
|
||||
has no effect. For example, let's say we have a texure that is a circle. If we
|
||||
use this texture in two layers, one defined as having a size of 128x128 and
|
||||
the second layer is defined as 64x64 and neither is supplied a shift and offset
|
||||
the net result appears as 2 concentric circles.
|
||||
|
||||
|
||||
About Transformations and Needle Placement:
|
||||
------------------------------------------
|
||||
When describing placement of instrument needles, a transformation offset must
|
||||
be applied to shift the needles fulcrum or else the needle will rotate around it's
|
||||
middle. The offset will be of <type> x-shift or y-shift depending on the orientation of
|
||||
the needle section in the cropped texture.
|
||||
|
||||
This example comes from the altimeter.xml
|
||||
|
||||
<layer>
|
||||
<name>long needle (hundreds)</name> <!-- the altimeter has more than one needle -->
|
||||
<texture>
|
||||
<path>Aircraft/c172/Instruments/Textures/misc-1.rgb</path>
|
||||
<x1>0.8</x1>
|
||||
<y1>0.78125</y1>
|
||||
<x2>0.8375</x2>
|
||||
<y2>1.0</y2>
|
||||
</texture>
|
||||
<w>8</w>
|
||||
<h>56</h>
|
||||
<transformations> <!-- begin defining transformations -->
|
||||
<transformation> <!-- start definition of transformation that drives the needle -->
|
||||
<type>rotation</type>
|
||||
<property>/steam/altitude</property> <!-- bind it to a property -->
|
||||
<max>100000.0</max> <!-- upper limit of instrument -->
|
||||
<scale>0.36</scale> <!-- once around == 1000 ft -->
|
||||
</transformation> <!-- close this transformation -->
|
||||
<transformation> <!-- this one shifts the fulcrum of the needle -->
|
||||
<type>y-shift</type> <!-- y-shift relative to needle -->
|
||||
<offset>24.0</offset> <!-- amount of shift -->
|
||||
</transformation>
|
||||
</transformations>
|
||||
</layer>
|
||||
|
||||
This needles has its origin in the center of the instrument. If the needles fulcrum was
|
||||
towards the edge of the instrument, the transformations to place the pivot point must
|
||||
precede those which drive the needle,
|
||||
|
||||
Interpolation
|
||||
-------------
|
||||
Non linear transformations are now possible via the use of interpolation tables.
|
||||
|
||||
<transformation>
|
||||
...
|
||||
<interpolation>
|
||||
<entry>
|
||||
<ind>0.0</ind> <!-- raw value -->
|
||||
<dep>0.0</dep> <!-- displayed value -->
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>10.0</ind>
|
||||
<dep>100.0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>20.0</ind>
|
||||
<dep>-5.0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>30.0</ind>
|
||||
<dep>1000.0</dep>
|
||||
</entry>
|
||||
</interpolation>
|
||||
</transformation>
|
||||
|
||||
Of course, interpolation tables are useful for non-linear stuff, as in
|
||||
the above example, but I kind-of like the idea of using them for
|
||||
pretty much everything, including non-trivial linear movement -- many
|
||||
instrument markings aren't evenly spaced, and the interpolation tables
|
||||
are much nicer than the older min/max/scale/offset stuff and should
|
||||
allow for a more realistic panel without adding a full equation parser
|
||||
to the property manager.
|
||||
|
||||
If you want to try this out, look at the airspeed.xml file in the base
|
||||
package, and uncomment the interpolation table in it for a
|
||||
very funky, non-linear and totally unreliable airspeed indicator.
|
||||
|
||||
|
||||
Actions:
|
||||
-------
|
||||
An action is a hotspot on an instrument where something will happen
|
||||
when the user clicks the left or center mouse button. Actions are
|
||||
always tied to properties: they can toggle a boolean property, adjust
|
||||
the value of a numeric property, or swap the values of two properties.
|
||||
The x/y placement for actions specifies the origin of the lower left corner.
|
||||
In the following example the first action sets up a hotspot 32 pixels wide
|
||||
and 16 pixels high. It lower left corner is placed 96 pixels (relative to the
|
||||
defined base size of the instrument) to the right of the center of the
|
||||
instrument. It is also 32 pixels below the centerline of the instrument.
|
||||
The actual knob texture over which the action is superimposed is 32x32.
|
||||
Omitted here is a second action, bound to the same property, with a positive
|
||||
increment value. This second action is placed to cover the other half of the
|
||||
knob. The result is that clicking on the left half of the knob texture decreases
|
||||
the value and clicking the right half increases the value. Also omitted here
|
||||
is a second pair of actions with the same coordinates but a larger increment
|
||||
value. This second pair is bound to a different mouse button. The net result
|
||||
is that we have both fine and coarse adjustments in the same hotspot, each
|
||||
bound to a different mouse button.
|
||||
|
||||
These examples come from the radio stack:
|
||||
<actions> <!-- open the actions section -->
|
||||
<action> <!- first action -->
|
||||
<name>small nav frequency decrease</name>
|
||||
<type>adjust</type>
|
||||
<button>0</button> <!-- bind it to a mouse button -->
|
||||
<x>96</x> <!-- placement relative to instrument center -->
|
||||
<y>-32</y>
|
||||
<w>16</w> <!-- size of hotspot -->
|
||||
<h>32</h>
|
||||
<property>/radios/nav1/frequencies/standby</property> <!-- bind to a property -->
|
||||
<increment>-0.05</increment> <!-- amount of adjustment per mouse click -->
|
||||
<min>108.0</min> <!-- lower range -->
|
||||
<max>117.95</max> <!-- upper range -->
|
||||
<wrap>1</wrap> <!-- boolean value -- value wraps around when it hits bounds -->
|
||||
</action>
|
||||
<action>
|
||||
<name>swap nav frequencies</name>
|
||||
<type>swap</type> <!-- define type of action -->
|
||||
<button>0</button>
|
||||
<x>48</x>
|
||||
<y>-32</y>
|
||||
<w>32</w>
|
||||
<h>32</h>
|
||||
<property1>/radios/nav1/frequencies/selected</property1> <!-- properties to toggle between -->
|
||||
<property2>/radios/nav1/frequencies/standby</property2>
|
||||
</action>
|
||||
<action>
|
||||
<name>ident volume on/off</name>
|
||||
<type>adjust</type>
|
||||
<button>1</button>
|
||||
<x>40</x>
|
||||
<y>-24</y>
|
||||
<w>16</w>
|
||||
<h>16</h>
|
||||
<property>/radios/nav1/ident</property> <!-- this property is for Morse code identification of nav beacons -->
|
||||
<increment>1.0</increment> <!-- the increment equals the max value so this toggles on/off -->
|
||||
<min>0</min>
|
||||
<max>1</max>
|
||||
<wrap>1</wrap> <!-- a shortcut to avoid having separate actions for on/off -->
|
||||
</action>
|
||||
</actions>
|
||||
|
||||
More About Textures:
|
||||
-------------------
|
||||
As previously stated, the usual size instrument texture files in FGFS are 256x256
|
||||
pixels, red/green/blue/alpha format. However the mechanism for specifying
|
||||
texture cropping coordinates is decimal in nature. When calling a section
|
||||
of a texture file the 0,0 lower left convention is used.
|
||||
There is a pair of x/y coordinates defining which section of the texture
|
||||
to use.
|
||||
|
||||
The following table can be used to calculate texture cropping specifications.
|
||||
|
||||
# of divisions | width in pixels | decimal specification
|
||||
per axis
|
||||
1 = 256 pixels 1
|
||||
2 = 128 pixels, 0.5
|
||||
4 = 64 pixels, 0.25
|
||||
8 = 32 pixels, 0.125
|
||||
16 = 16 pixels, 0.0625
|
||||
32 = 8 pixels, 0.03125
|
||||
64 = 4 pixels, 0.015625
|
||||
128 = 2 pixels, 0.0078125
|
||||
|
||||
A common procedure for generating gauge faces is to use a
|
||||
vector graphics package such as xfig, exporting the result as a
|
||||
postscript file. 3D modeling tools may also be used and I prefer them
|
||||
for pretty items such as levers, switches, bezels and so forth.
|
||||
Ideally, the size of the item in the final render
|
||||
should be of proportions that fit into the recommended pixel widths.
|
||||
The resulting files can be imported into a graphics manipulation
|
||||
package such as GIMP, et al for final processing.
|
||||
|
||||
How do I get my panels/instruments into the base package?
|
||||
-------------------------------------------------------
|
||||
Cash bribes always help ;) Seriously though, there are two main considerations.
|
||||
Firstly, original artwork is a major plus since you as the creator can dictate the terms
|
||||
of distribution. All Artwork must have a license compatible with the GPL.
|
||||
Artwork of unverifiable origin is not acceptable.
|
||||
Secondly, texture sizes must meet the lowest common denominator of 256e2 pixels.
|
||||
Artwork from third parties may be acceptable if it meets these criteria.
|
||||
|
||||
* If there are *any* XML parsing errors, the panel will fail to load,
|
||||
so it's worth downloading a parser like Expat (http://www.jclark.com/xml/)
|
||||
for checking your XML. FlightGear will print the location of errors, but
|
||||
the messages are a little cryptic right now.
|
||||
|
||||
** NOTE: There is one built-in layer -- for the mag compass ribbon --
|
||||
and all other layers are defined in the XML files. In the future,
|
||||
there may also be built-in layers for special things like a
|
||||
weather-radar display or a GPS (though the GPS could be handled with
|
||||
text properties).
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue