diff --git a/Docs/README.xmlpanel.html b/Docs/README.xmlpanel.html new file mode 100644 index 000000000..4147284ef --- /dev/null +++ b/Docs/README.xmlpanel.html @@ -0,0 +1,953 @@ +Users Guide to FlightGear panel configuration + +

Users Guide to FlightGear panel configuration

+ + +Version 0.7.7.2, July 24 2001 +Author: John Check + + +
    +
  1. Some History +
  2. About The Property Manager +
  3. XML and The Property Manager +
  4. Loading Panels +
  5. Regarding Window Geometry +
  6. Panel Architecture +
  7. Example Top Level Panel Config +
  8. Indexed Properties +
  9. Inclusion +
  10. Aliasing +
  11. Instrument Architecture +
  12. Textures +
  13. Instrument Layers +
  14. Transformations +
  15. About Transformations and Needle Placement +
  16. Interpolation Tables +
  17. Actions +
  18. More About Textures +
  19. Generating Textures +
  20. Contributing Panels +
  21. Units +
+ +

+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          ~/           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) +Properties must have units specified where appropriate. See section "Units" +at the end of this doc. +

+

+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-mhz</comm-freq-prop>
+ <nav-freq-prop>/radios/nav1/frequencies/selected-mhz</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-mhz</comm-freq-prop>
+ <nav-freq-prop>/radios/nav1/frequencies/selected-mhz</nav-freq-prop>
+ </params>
+ .....
+ </instrument>
+
+ <instrument include="../Instruments/navcomm.xml">
+ <name>NAVCOM 2 radio</name>
+ <params>
+ <comm-freq-prop>/radios/comm2/frequencies/selected-mhz</comm-freq-prop>
+ <nav-freq-prop>/radios/nav2/frequencies/selected-mhz</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-nm</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-ft</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 Tables:

+
+ +

+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-mhz</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-mhz</property1>   <!-- properties to toggle between -->
+   <property2>/radios/nav1/frequencies/standby-mhz</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
+        256 =   1 pixel,                0.00390625
+
+
+ +

+The displayed size of a texture in pixels is set in the instrument +configuration file. The size of the cropped area in pixels is not +directly related to the final display size. +

+

+What that table represents is: +

+

+1 / (256 / # of pixels) +

+

+Take as an example, a section 64 pixels wide on the texture file. +256/64 = 4 +1/4 = 0.25 +

+

+Or lets consider 1 pixel wide +256/1 = 256 +1/256 = 0.00390625 +

+

+If the section starts at the extreme left of the texture, the +starting number is 0.0 and the end is 0.25 +If the section *doesn't* start at the edge you need to take the starting +pixel and calculate an offset. Lets say you start 2 pixels from the +edge and you are cropping a section 64 pixels wide... +

+ +
+256/2 = 128
+1/128 = 0.0078125 <- this is the value for a 2 pixel wide offset
+
+
+0.0078125 <- start at
+0.25      <- add value for 64 px wide
+0.2571825 <- end at
+
+
+ +
+

Generating Textures:

+
+ +

+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. +

+ +
+

Contributing Panels And Instruments

+
+ +

+There are two main considerations when contributing panels and instruments. +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. +

+ +
+

UNITS:

+
+

+Here is a list of property names including appropriate units: +

+ +
+/autopilot/locks/nav1 => /autopilot/locks/nav[0]
+/autopilot/settings/altitude += "-ft"
+/autopilot/settings/climb-rate += "-fpm"
+/autopilot/settings/heading-bug += "-deg"
+/consumables/fuel/tank1/level => /consumables/fuel/tank[0]/level-gal_us
+/consumables/fuel/tank2/level => /consumables/fuel/tank[1]/level-gal_us
+/engines/engine0/cht => /engines/engine[0]/cht-degf
+/engines/engine0/egt => /engines/engine[0]/egt-degf
+/engines/engine0/fuel-flow => /engines/engine[0]/fuel-flow-gph
+/engines/engine0/mp => /engines/engine[0]/mp-osi
+/engines/engine0/rpm => /engines/engine[0]/rpm
+/environment/clouds/altitude += "-ft"
+/environment/magnetic-dip += "-deg"
+/environment/magnetic-varation += "-deg"
+/environment/visibility += "-m"
+/environment/wind-down += "-fps"
+/environment/wind-east += "-fps"
+/environment/wind-north += "-fps"
+/orientation/heading += "-deg"
+/orientation/heading-magnetic += "-deg"
+/orientation/pitch += "-deg"
+/orientation/roll += "-deg"
+/position/altitude += "-ft"
+/position/altitude-agl += "-ft"
+/position/latitude += "-deg"
+/position/longitude += "-deg"
+/radios/adf/frequencies/selected += "-khz"
+/radios/adf/frequencies/standby += "-khz"
+/radios/adf/rotation += "-deg"
+/radios/nav1/* => /radios/nav[0]/*
+/radios/nav2/* => /radios/nav[1]/*
+/radios/nav[*]/dme/distance += "-nm"
+/radios/nav[*]/frequencies/selected += "-mhz"
+/radios/nav[*]/frequencies/standby += "-mhz"
+/radios/nav[*]/radials/actual += "-deg"
+/radios/nav[*]/radials/selected += "-deg"
+/sim/model/h-rotation => /sim/model/heading-offset-deg
+/sim/model/p-rotation => /sim/model/roll-offset-deg
+/sim/model/r-rotation => /sim/model/pitch-offset-deg
+/sim/model/x-offset += "-m"
+/sim/model/y-offset += "-m"
+/sim/model/z-offset += "-m"
+/sim/view/goal-offset += "-deg"
+/sim/view/offset += "-deg"
+/steam/adf += "-deg"
+/steam/airspeed += "-kt"
+/steam/altitude += "-ft"
+/steam/gyro-compass += "-deg"
+/steam/gyro-compass-error += "-deg"
+/steam/mag-compass += "-deg"
+/steam/vertical-speed += "-fpm"
+/velocities/airspeed += "-kt"
+/velocities/side-slip += "-rad"
+/velocities/speed-down += "-fps"
+/velocities/speed-east += "-fps"
+/velocities/speed-north += "-fps"
+/velocities/uBody += "-fps"
+/velocities/vBody += "-fps"
+/velocities/wBody += "-fps"
+/velocities/vertical-speed += "-fps"
+
+
+

+* 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). +

+ +