]> git.mxchange.org Git - flightgear.git/blob - docs-mini/README.xmlpanel
Simplify fgValidatePath + minor fix (requires simgear update)
[flightgear.git] / docs-mini / README.xmlpanel
1 Users Guide to FlightGear panel configuration
2 Version 0.7.7, May 16 2001
3 Author: John Check <j4strngs@rockfish.net>
4
5 This document is an attempt to describe the configuration of
6 FlightGear flight simulator's aircraft panel display via XML.  The
7 information was culled from the fgfs-devel@flightgear.org mailing list
8 and my experiences making alternate panels.  Corrections and additions
9 are encouraged.
10
11 Some History:
12 ------------
13 Older versions of FGFS had a hard coded display of instruments.  This
14 was a less than ideal state of affairs due to FGFS ability to use
15 different aircraft models. Being primarily developed on UNIX type
16 systems, a modular approach is taken towards the simulation. To date,
17 most alternatives to the default Cessna 172 aircraft are the product
18 of research institutions interested in the flight characteristics and
19 not cosmetics.  The result of this was that one could fly the X-15 or
20 a Boeing 747 but be limited to C172 instrumentation.
21
22 A rewrite of the panel display code was done around v0.7.5 by
23 developer David Megginson allowing for configuration of the panel via
24 XML to address this limitation. Some major changes and additions were
25 made during the course of version 0.7.7 necessitating a rewrite and
26 expansion of this document.
27
28
29 About The Property Manager:
30 --------------------------
31 While not absolutely necessary in order to create aircraft panels,
32 some familiarity with the property manager is beneficial....
33 FlightGear provides a hierarchical representation of all aspects of
34 the state of the running simulation that is known as the property
35 tree.  Some properties, such as velocities are read only. Others such
36 as the frequencies to which the navcom radios are tuned or the
37 position of control surfaces can be set by various means.  FlightGear
38 can optionally provide an interface to these properties for external
39 applications such as Atlas, the moving map program, or even lowly
40 telnet, via a network socket. Data can even be placed on a serial port
41 and connected to, say a GPS receiver.  Aside from its usefulness in a
42 flight training context, being able to manipulate the property tree on
43 a running copy of FG allows for switching components on the fly, a
44 positive boon for panel authors.  To see the property tree start FG
45 with the following command line:
46
47 fgfs --props=socket,bi,5,localhost,5500,tcp
48
49 Then use telnet to connect to localhost on port 5500. You can browse
50 the tree as you would a filesystem.
51
52 XML and the Property Manager:
53 ----------------------------
54 Panel instruments interface with the property tree to get/set values
55 as appropriate. Properties for which FG doesn't yet provide a value
56 can be created by simply making them up. Values can be adjusted using
57 the telnet interface allowing for creation and testing of instruments
58 while code to drive them is being developed.
59
60 If fact, the XML configuration system allows a user to combine
61 components such as flight data model, aircraft exterior model, heads
62 up display, and of course control panel. Furthermore, such a
63 preconfigured aircraft.xml can be included into a scenario with
64 specific flight conditions. These can be manually specified or a FG
65 session can be saved and/or edited and reloaded later. Options
66 specified in these files can be overridden on the command line. For
67 example:
68
69 --prop:/sim/panel/path=Aircraft/c172/Panels/c172-panel.xml
70
71 passed as an option, would override a panel specified elsewhere.
72 Property tree options all have the same format, specify the node and
73 supply it a value.
74
75 The order of precedence for options is thus:
76
77 Source          Location                Format
78 ------          --------                ------
79 command line
80 .fgfsrc         Users home directory.   command line options
81 system.fgfsrc   $FG_ROOT                ""      ""
82 preferences.xml $FG_ROOT                XML property list
83
84
85 Loading Panels on the fly:
86 -------------------------
87 When editing a panel configuration, pressing Shift +F3 will reload the
88 panel. If your changes don't seem to be taking effect, check the
89 console output.  It will report the success or failure of the panel
90 reload*. Editing textures requires restarting FGFS so the new textures
91 can be loaded. Panels can be switched on the fly by setting the
92 /sim/panel/path property value and reloading.
93
94 Regarding Window Geometry:
95 -------------------------
96 For the sake of simplicity the FGFS window is always considered to be
97 1024x768 so all x/y values for instrument placement should relative to
98 these dimensions.  Since FG uses OpenGL 0,0 represents the lower left
99 hand corner of the screen. Panels may have a virtual size larger than
100 1024x768. Vertical scrolling is accomplished with
101 Shift+F5/F6. Horizontal scrolling is via Shift+F7/F8. An offset should
102 be supplied to set the default visible area. It is possible to place
103 items to overlap the 3D viewport.
104
105 Panel Architecture:
106 -------------------
107 All of the panel configuration files are XML-encoded* property lists.
108 The root element of each file is always named <PropertyList>. Tags are
109 almost always found in pairs, with the closing tag having a slash
110 prefixing the tag name, i.e </PropertyList>. The exception is the tag
111 representing an aliased property. In this case a slash is prepended to
112 the closing angle bracket.  (see section Aliasing)
113
114 The top level panel configuration file is composed of a <name>, a
115 <background> texture and zero or more <instruments>.Earlier versions
116 required instruments to have a unique name and a path specification
117 pointing to the instruments configuration file.
118
119 [ Paths are relative to $FG_ROOT (the installed location of FGFS data files.) ]
120 [ Absolute paths may be used.Comments are bracketed with <!-- -->.            ]
121
122 Old style instrument call in top level panel.xml:
123 ------------------------------------------------
124   <clock>         <!-- required "unique_name" -->
125    <path>Aircraft/c172/Instruments/clock.xml</path>
126    <x>110</x>     <!-- required horizontal placement -->
127    <y>320</y>     <!-- required vertical placement -->
128    <w>72</w>      <!-- optional width specification -->
129    <h>72</h>      <!-- optional height specification -->
130   </clock>
131
132 The difference between the old and new styles, while subtle, is rather
133 drastic.  The old and new methods are indeed incompatible. I cover the
134 old style only to acknowledge the incompatibility. This section will
135 be removed after the next official FGFS release.
136
137 New Style Example Top Level Panel Config:
138 ----------------------------------------
139 <PropertyList>
140  <name>Example Panel</name>
141  <background>Aircraft/c172/Panels/Textures/panel-bg.rgb</background>
142  <w>1024</w>                      <!-- virtual width -->
143  <h>768</h>                       <!-- virtual height -->
144  <y-offset>-305</y-offset>        <!-- hides the bottom part -->
145  <view-height>172</view-height>   <!-- amount of overlap between 2D panel and 3D viewport -->
146
147  <instruments>                    <!-- from here down is where old and new styles break compatibility -->
148
149   <instrument include="../Instruments/clock.xml">
150    <name>Chronometer</name>   <!-- currently optional but strongly recommended -->
151    <x>150</x>                 <!-- required horizontal placement -->
152    <y>645</y>                 <!-- required vertical placement -->
153    <w>72</w>                  <!-- optional width specification -->
154    <h>72</h>                  <!-- optional height specification -->
155   </instrument>
156
157  </instruments>
158
159 </PropertyList>
160
161
162 Indexed Properties
163 ------------------
164 This is a lot to do with the compatibility break so lets get it out of
165 the way.  The property manager now assigns incremental indices to
166 repeated properties with the same parent node, so that
167
168  <PropertyList>
169  <x>1</x>
170  <x>2</x>
171  <x>3</x>
172  </PropertyList>
173
174 shows up as
175
176  /x[0] = 1
177  /x[1] = 2
178  /x[2] = 3
179
180 This means that property files no longer need to make up a separate
181 name for each item in a list of instruments, layers, actions,
182 transformations, or text chunks. In fact, the new panel I/O code now
183 insists that every instrument have the XML element name "instrument",
184 every layer have the name "layer", every text chunk have the name
185 "chunk", every action have the name "action", and every transformation
186 have the name "transformation" -- this makes the XML more regular (so
187 that it can be created in a DTD-driven tool) and also allows us to
188 include other kinds of information (such as doc strings) in the lists
189 without causing confusion.
190
191 Inclusion:
192 ----------
193 The property manager now supports file inclusion and aliasing.
194 Inclusion means that a node can include another property file as if it
195 were a part of the current file.  To clarify how inclusion works,
196 consider the following examples:
197
198 If bar.xml contains
199
200  <PropertyList>
201  <a>1</a>
202  <b>
203  <c>2</c>
204  </b>
205  </PropertyList>
206
207 then the declaration
208
209  <foo include="../bar.xml">
210  </foo>
211
212 is exactly equivalent to
213
214  <foo>
215  <a>1</a>
216  <b>
217  <c>2</c>
218  </b>
219  </foo>
220
221 However, it is also possible to selectively override properties in the
222 included file. For example, if the declaration were
223
224  <foo include="../bar.xml">
225  <a>3</a>
226  </foo>
227
228 then the property manager would see
229
230  <foo>
231  <a>3</a>
232  <b>
233  <c>2</c>
234  </b>
235  </foo>
236
237 with the original 'a' property's value replaced with 3.
238
239 This new inclusion feature allows property files to be broken up and
240 reused arbitrarily -- for example, there might be separate cropping
241 property lists for commonly-used textures or layers, to avoid
242 repeating the information in each instrument file.
243
244
245 Aliasing
246 --------
247 Properties can now alias other properties, similar to a symbolic link
248 in Unix. When the target property changes value, the new value will
249 show up in the aliased property as well. For example,
250
251  <PropertyList>
252  <foo>3</foo>
253  <bar alias="/foo"/>
254  </PropertyList>
255
256 will look the same to the application as
257
258  <PropertyList>
259  <foo>3</foo>
260  <bar>3</bar>
261  </PropertyList>
262
263 except that when foo changes value, bar will change too.
264
265
266 The combination of inclusions and aliases is very powerful, because it
267 allows for parameterized property files. For example, the XML file for
268 the NAVCOM radio can include a parameter subtree at the start, like
269 this:
270
271  <PropertyList>
272  <params>
273  <comm-freq-prop>/radios/comm1/frequencies/selected</comm-freq-prop>
274  <nav-freq-prop>/radios/nav1/frequencies/selected</comm-freq-prop>
275  </params>
276
277  ...
278
279  <chunk>
280  <type>number-value</type>
281  <property alias="/params/nav-freq-prop"/>
282  </chunk>
283
284  ...
285  </PropertyList>
286
287 Now, the same instrument file can be used for navcomm1 and navcomm2,
288 for example, simply by overriding the parameters at inclusion:
289
290  <instrument include="../Instruments/navcomm.xml">
291  <params>
292  <comm-freq-prop>/radios/comm1/frequencies/selected</comm-freq-prop>
293  <nav-freq-prop>/radios/nav1/frequencies/selected</comm-freq-prop>
294  </params>
295  </instrument>
296
297  <instrument include="../Instruments/navcomm.xml">
298  <params>
299  <comm-freq-prop>/radios/comm2/frequencies/selected</comm-freq-prop>
300  <nav-freq-prop>/radios/nav2/frequencies/selected</comm-freq-prop>
301  </params>
302  </instrument>
303
304 Instrument Architecture:
305 -----------------------
306 Instruments are defined in separate configuration files. An instrument
307 consists of a base width and height, one or more stacked layers, and
308 zero or more actions. Base dimensions are specified as follows:
309
310 <PropertyList>                   <!-- remember, all xml files start like this -->
311  <name>Airspeed Indicator</name> <!-- names are good -->
312  <w-base>128</w-base>            <!-- required width spec-->
313  <h-base>128</h-base>            <!-- required height spec-->
314   <layers>                       <!-- begins layers section -->
315
316 Height and width can be overriden in the top level panel.xml by
317 specifying <w> and <h>. Transformations are caculated against the base
318 size regardless of the display size. This ensures that instruments
319 remain calibrated
320
321 Textures:
322 --------
323 FG uses red/green/blue/alpha .rgba files for textures. Dimensions for
324 texture files should be power of 2 with a maximum 8:1 aspect ratio.
325 The lowest common denominator for maximum texture size is 256 pixels.
326 This is due to the limitations of certain video accelerators, most
327 notably those with 3Dfx chipset such as the Voodoo2.
328
329 Instrument Layers**:
330 -------------------
331 The simplest layer is a <texture>. These can be combined in <switch> layers
332
333 <texture>
334 A texture layer looks like this:
335
336   <layer>                      <!-- creates a layer -->
337    <name>face</name>
338    <texture>                   <!-- defines it as a texture layer -->
339     <path>Aircraft/c172/Instruments/Textures/faces-2.rgb</path>
340     <x1>0</x1>                 <!-- lower boundary for texture cropping-->
341     <y1>0.51</y1>              <!-- left boundary  for texture cropping-->
342     <x2>0.49</x2>              <!-- upper boundary  for texture cropping-->
343     <y2>1.0</y2>               <!-- right boundary  for texture cropping-->
344    </texture>                  <!-- closing texure tag -->
345   </layer>                     <!-- closing layer tag -->
346
347 The texture cropping specification is represented as a decimal. There
348 is a table at the end of this document for converting from pixel
349 coordinates to percentages.
350
351 This particular layer, being a gauge face has no transformations
352 applied to it.  Layers with that aren't static *must* include <w> and
353 <h> parameters to be visible.
354
355 <type> May be either text or switch..
356
357 <type>switch</type>
358 A switch layer is composed of two or more nested layers and will
359 display one of the nested layers based on a boolean property. For a
360 simple example of a switch see
361 $FG_ROOT/Aircraft/c172/Instruments/brake.xml.
362
363   <layer>
364    <name>Brake light</name>
365    <type>switch</type>                      <!-- define layer as a switch -->
366    <property>/controls/brakes</property>    <!-- tie it to a property -->
367     <layer1>                                <!-- layer for true state -->
368      <name>on</name>                        <!-- label to make life easy -->
369      <texture>                              <!-- layer1 of switch is a texture layer -->
370      <path>Aircraft/c172/Instruments/Textures/brake.rgb</path>
371      <x1>0.25</x1>
372      <y1>0.0</y1>
373      <x2>0.5</x2>
374      <y2>0.095</y2>
375      </texture>
376      <w>64</w>                              <!-- required width - layer isn't static -->
377      <h>24</h>                              <!-- required height - layer isn't static -->
378     </layer1>                               <!-- close layer1 of switch -->
379     <layer2>                                <!-- layer for false state -->
380      <name>off</name>
381      <texture>
382      <path>Aircraft/c172/Instruments/Textures/brake.rgb</path>
383      <x1>0.0</x1>
384      <y1>0.0</y1>
385      <x2>0.25</x2>
386      <y2>0.095</y2>
387      </texture>
388      <w>64</w>
389      <h>24</h>
390    </layer2>
391   </layer>
392
393 Switches can have more than 2 states. This requires nesting one switch
394 inside another.  One could make, for example, a 3 color LED by nesting
395 switch layers.
396
397 <type>text</type>
398 A text layer may be static, as in a label, generated from a property
399 or a combination of both.  This example is a switch that contains both
400 static and dynamic text:
401
402    <layer1>                               <!-- switch layer -->
403     <name>display</name>
404     <type>text</type>                     <!-- type == text -->
405     <point-size>12</point-size>           <!-- font size -->
406     <color>                               <!-- specify rgb values to color text -->
407      <red>1.0</red>
408      <green>0.5</green>
409      <blue>0.0</blue>
410     </color>                              <!-- close color section -->
411     <chunks>                              <!-- sections of text are referred to as chunks -->
412      <chunk>                              <!-- first chunk of text -->
413       <type>number-value</type>           <!-- value defines it as dynamic -->
414       <property>/radios/nav1/dme/distance</property>      <!-- ties it to a property -->
415       <scale>0.00053995680</scale>        <!-- convert between  statute and nautical miles? -->
416       <format>%5.1f</format>              <!-- define format -->
417      </chunk>
418     </chunks>
419    </layer1>
420    <layer2>                                <!-- switch layer -->
421     <name>display</name>
422     <type>text</type>                      <!-- type == text -->
423     <point-size>10</point-size>            <!-- font size -->
424     <color>                                <!-- specify rgb values to color text -->
425      <red>1.0</red>
426      <green>0.5</green>
427      <blue>0.0</blue>
428     </color>                               <!-- close color section -->
429     <chunks>                               <!-- sections of text are referred to as chunks -->
430      <chunk>                               <!-- first chunk of text -->
431       <type>literal</type>                 <!-- static text -->
432       <text>---.--</text>                  <!-- fixed value -->
433      </chunk>
434     </chunks>
435    </layer2>
436
437
438 Transformations:
439 ---------------
440 A transformation is a rotation, an x-shift, or a
441 y-shift. Transformations can be static or they can be based on
442 properties. Static rotations are useful for flipping textures
443 horizontally or vertically. Transformations based on properties are
444 useful for driving instrument needles. I.E. rotate the number of
445 degrees equal to the airspeed. X and y shifts are relative to the
446 center of the instrument. Each specified transformation type takes an
447 <offset>.  Offsets are relative to the center of the instrument. A
448 shift without an offset has no effect. For example, let's say we have
449 a texure that is a circle. If we use this texture in two layers, one
450 defined as having a size of 128x128 and the second layer is defined as
451 64x64 and neither is supplied a shift and offset the net result
452 appears as 2 concentric circles.
453
454
455 About Transformations and Needle Placement:
456 ------------------------------------------
457
458 When describing placement of instrument needles, a transformation
459 offset must be applied to shift the needles fulcrum or else the needle
460 will rotate around it's middle. The offset will be of <type> x-shift
461 or y-shift depending on the orientation of the needle section in the
462 cropped texture.
463
464 This example comes from the altimeter.xml
465
466   <layer>
467    <name>long needle (hundreds)</name>        <!-- the altimeter has more than one needle -->
468    <texture>
469     <path>Aircraft/c172/Instruments/Textures/misc-1.rgb</path>
470     <x1>0.8</x1>
471     <y1>0.78125</y1>
472     <x2>0.8375</x2>
473     <y2>1.0</y2>
474    </texture>
475    <w>8</w>
476    <h>56</h>
477    <transformations>                          <!-- begin defining transformations -->
478     <transformation>                          <!-- start definition of transformation that drives the needle -->
479      <type>rotation</type>
480      <property>/steam/altitude</property>     <!-- bind it to a property -->
481      <max>100000.0</max>                      <!-- upper limit of instrument -->
482      <scale>0.36</scale>                      <!-- once around == 1000 ft -->
483     </transformation>                         <!-- close this transformation -->
484     <transformation>                          <!-- this one shifts the fulcrum of the needle -->
485      <type>y-shift</type>                     <!-- y-shift relative to needle -->
486      <offset>24.0</offset>                    <!-- amount of shift -->
487     </transformation>
488    </transformations>
489   </layer>
490
491 This needles has its origin in the center of the instrument. If the
492 needles fulcrum was towards the edge of the instrument, the
493 transformations to place the pivot point must precede those which
494 drive the needle,
495
496 Interpolation
497 -------------
498 Non linear transformations are now possible via the use of
499 interpolation tables.
500
501  <transformation>
502  ...
503  <interpolation>
504  <entry>
505  <ind>0.0</ind>            <!-- raw value -->
506  <dep>0.0</dep>            <!-- displayed value -->
507  </entry>
508  <entry>
509  <ind>10.0</ind>
510  <dep>100.0</dep>
511  </entry>
512  <entry>
513  <ind>20.0</ind>
514  <dep>-5.0</dep>
515  </entry>
516  <entry>
517  <ind>30.0</ind>
518  <dep>1000.0</dep>
519  </entry>
520  </interpolation>
521  </transformation>
522
523 Of course, interpolation tables are useful for non-linear stuff, as in
524 the above example, but I kind-of like the idea of using them for
525 pretty much everything, including non-trivial linear movement -- many
526 instrument markings aren't evenly spaced, and the interpolation tables
527 are much nicer than the older min/max/scale/offset stuff and should
528 allow for a more realistic panel without adding a full equation parser
529 to the property manager.
530
531 If you want to try this out, look at the airspeed.xml file in the base
532 package, and uncomment the interpolation table in it for a very funky,
533 non-linear and totally unreliable airspeed indicator.
534
535
536 Actions:
537 -------
538 An action is a hotspot on an instrument where something will happen
539 when the user clicks the left or center mouse button.  Actions are
540 always tied to properties: they can toggle a boolean property, adjust
541 the value of a numeric property, or swap the values of two properties.
542 The x/y placement for actions specifies the origin of the lower left
543 corner.  In the following example the first action sets up a hotspot
544 32 pixels wide and 16 pixels high. It lower left corner is placed 96
545 pixels (relative to the defined base size of the instrument) to the
546 right of the center of the instrument. It is also 32 pixels below the
547 centerline of the instrument.  The actual knob texture over which the
548 action is superimposed is 32x32.  Omitted here is a second action,
549 bound to the same property, with a positive increment value. This
550 second action is placed to cover the other half of the knob. The
551 result is that clicking on the left half of the knob texture decreases
552 the value and clicking the right half increases the value. Also
553 omitted here is a second pair of actions with the same coordinates but
554 a larger increment value. This second pair is bound to a different
555 mouse button. The net result is that we have both fine and coarse
556 adjustments in the same hotspot, each bound to a different mouse
557 button.
558
559 These examples come from the radio stack:
560 <actions>                              <!-- open the actions section -->
561   <action>                             <!- first action -->
562    <name>small nav frequency decrease</name>
563    <type>adjust</type>
564    <button>0</button>                  <!-- bind it to a mouse button -->
565    <x>96</x>                           <!-- placement relative to instrument center -->
566    <y>-32</y>
567    <w>16</w>                           <!-- size of hotspot -->
568    <h>32</h>
569    <property>/radios/nav1/frequencies/standby</property>    <!-- bind to a property -->
570    <increment>-0.05</increment>        <!-- amount of adjustment per mouse click -->
571    <min>108.0</min>                    <!-- lower range -->
572    <max>117.95</max>                   <!-- upper range -->
573    <wrap>1</wrap>                      <!-- boolean value -- value wraps around when it hits bounds -->
574   </action>
575   <action>
576    <name>swap nav frequencies</name>
577    <type>swap</type>                   <!-- define type of action -->
578    <button>0</button>
579    <x>48</x>
580    <y>-32</y>
581    <w>32</w>
582    <h>32</h>
583    <property1>/radios/nav1/frequencies/selected</property1>   <!-- properties to toggle between -->
584    <property2>/radios/nav1/frequencies/standby</property2>
585   </action>
586   <action>
587    <name>ident volume on/off</name>
588    <type>adjust</type>
589    <button>1</button>
590    <x>40</x>
591    <y>-24</y>
592    <w>16</w>
593    <h>16</h>
594    <property>/radios/nav1/ident</property>  <!-- this property is for Morse code identification of nav beacons -->
595    <increment>1.0</increment>          <!-- the increment equals the max value so this toggles on/off -->
596    <min>0</min>
597    <max>1</max>
598    <wrap>1</wrap>                      <!-- a shortcut to avoid having separate actions for on/off -->
599   </action>
600 </actions>
601
602 More About Textures:
603 -------------------
604 As previously stated, the usual size instrument texture files in FGFS
605 are 256x256 pixels, red/green/blue/alpha format. However the mechanism
606 for specifying texture cropping coordinates is decimal in nature. When
607 calling a section of a texture file the 0,0 lower left convention is
608 used.  There is a pair of x/y coordinates defining which section of
609 the texture to use.
610
611 The following table can be used to calculate texture cropping
612 specifications.
613
614 # of divisions | width in pixels | decimal specification
615 per axis
616         1   =   256 pixels              1
617         2   =   128 pixels,             0.5
618         4   =   64 pixels,              0.25
619         8   =   32 pixels,              0.125
620         16  =   16 pixels,              0.0625
621         32  =   8 pixels,               0.03125
622         64  =   4 pixels,               0.015625
623         128 =   2 pixels,               0.0078125
624
625 A common procedure for generating gauge faces is to use a vector
626 graphics package such as xfig, exporting the result as a postscript
627 file. 3D modeling tools may also be used and I prefer them for pretty
628 items such as levers, switches, bezels and so forth.  Ideally, the
629 size of the item in the final render should be of proportions that fit
630 into the recommended pixel widths.  The resulting files can be
631 imported into a graphics manipulation package such as GIMP, et al for
632 final processing.
633
634 How do I get my panels/instruments into the base package?
635 -------------------------------------------------------
636 Cash bribes always help ;) Seriously though, there are two main
637 considerations.  Firstly, original artwork is a major plus since you
638 as the creator can dictate the terms of distribution.All Artwork must
639 have a license compatible with the GPL.  Artwork of unverifiable
640 origin is not acceptable.  Secondly, texture sizes must meet the
641 lowest common denominator of 256e2 pixels.  Artwork from third parties
642 may be acceptable if it meets these criteria.
643
644 *  If there are *any* XML parsing errors, the panel will fail to load,
645    so it's worth downloading a parser like Expat (http://www.jclark.com/xml/)
646    for checking your XML. FlightGear will print the location of errors, but
647    the messages are a little cryptic right now.
648
649 ** NOTE: There is one built-in layer -- for the mag compass ribbon --
650    and all other layers are defined in the XML files.  In the future,
651    there may also be built-in layers for special things like a
652    weather-radar display or a GPS (though the GPS could be handled with
653    text properties).
654