Kleiner Gauges-Workshop

Dieser Workshop soll zeigen, daß es auch ohne umfangreiche Programmierkenntnisse möglich ist, eigene Gauges im XML-Format zu programmieren. Es geht hierbei nicht darum die komplette XML-Programmiersprache zu vermitteln, das würde den Rahmen meiner Zeit und auch meines Wissens um das XML sprengen. Wer aber die vorgestellten Beispiele Teil für Teil theoretisch und auch praktisch durcharbeitet und sich selber tiefer mit dieser Materie beschäftigt, wird bald in der Lage sein auch umfangreiche und komplizierte Gauges zu programmieren. Und genau das ist das Ziel des Workshops!

1. Teil

Eigene Gauges entwerfen? Mit dem neuen XML-Format ist das gar nicht so kompliziert. Die CAB-Dateien erstellen? Es gibt zwar einige Programme die das können, wie z.B. WinRar, doch die sind meistens kostenpflichtig. Eine kostenlose Möglichkeit liefert uns Microsoft schon mit dem FS2004 in Form der Cabdir.exe (im Hauptverzeichnis) mit. Diese kann man sich gegebenenfalls auch mit dem MS Cabdir-SDK downloaden, wo auch gleich eine Beschreibung des Programms dabei ist. Als nächstes brauchen wir natürlich die Befehle, Variablen sowie die Syntax (die Schreibweise des Programmcodes). Das finden wir alles bei Avsim.com in Form der Datei xmltp.zip. Diese enthält Textdateien mit allen im FS2004 zur Verfügung stehenden K und A Variablen, HelpID's, Units, und der XML Gauge Syntax. Um nun erst einmal annähernd zu verstehen, wie so eine XML-Datei aufgebaut ist, sollte man sich einfach mal die boeing747-400.cab aus dem Gauges-Ordner des FS2004 in einen vorher neu angelegten Ordner extrahieren. Dazu einen Doppelklick auf die Datei, dann auf Bearbeiten - Alles Markieren, rechter Mausklick auf das Markierte und Extrahieren wählen. Mit einem Doppelklick auf die XML-Dateien kann man sich nun deren Inhalt ansehen und wird feststellen, daß alle Dateien den gleichen Aufbau haben, egal ob umfangreich wie die Clock.xml oder einfach wie die Anti-Ice Switch.xml.

Anhand der einfachen Switch-Dateien wagen wir uns jetzt an unser erstes eigenes Gauge. Wir wollen natürlich nicht das Rad neu erfinden und etwas Erstellen, was schon vorhanden ist. Nein, wir bauen uns etwas ganz neues, was uns bei der Fliegerei helfen soll. Jeder kennt das: Am Boden hat man eine perfekte Sicht nach vorne, in der Luft in großen Höhen sieht man über dem Cockpit nur den Himmel. Auch beim Landeanflug sieht man meistens kaum die Landebahn. Die einzige Hilfe ist dann die Sichthöhenverstellung per Umschalt- und Enter- bzw. Back-Taste. Was liegt also näher, als dieses über ein Gauge per Mausklick zu erledigen.

Dazu benötigen wir als erstes ein Bild, welches den Schalter darstellt. Dieses muß für den FS im 256-Farbmodus vorliegen. Am günstigsten ist es, solche Bilder erst einmal im 24-Bit-Farbmodus zu erstellen weil hier die Farbverläufe durch die höhere Farbanzahl besser darstellbar sind. Danach wird es dann mit einem geeigneten Grafikprogramm in ein 256-Index-Farben-Bild umgewandel (Paint ist dazu leider nicht in der Lage, dort ist der Farbverlußt zu hoch). Wie man diesen Schalter nun zeichnet ist der freien Fantasie überlassen, er sollte nur nicht zu groß sein und vor allem neutral, so daß er in jedes beliebige Panel eingebunden werden kann. Ich habe hier mal ein ganz einfaches Beispiel gewählt:

(View.bmp mit einer Größe von 48 x 29 Pixel - diese Werte werden später benötigt)

Nun können wir uns ans Programmieren wagen. Dazu öffnen wir als erstes den Editor und tragen die folgenden fettgedruckten Zeilen untereinander ein:

<Gauge Name="View Switch" Version="1.0"> Hier wird das GAUGE definiert, das ganz einfach den Namen bekommt, welche auch die XML-Datei später erhält. Als Versionsnummer belassen wir einfach die 1.0
<Image Name="View.bmp" ImageSizes="48,29,48,29"/> In dieser Zeile sagen wir dem Programm, welches Bild es darstellen soll und in welcher Größe. Die ersten beiden Werte stehen dabei für kleine Bildschirmauflösungen und die letzten beiden für große Auflösungen. Da wir aber nur ein Bild erstellt haben, sind hier die Werte für beide Auflösungen gleich.
<Mouse> Ein Mouse-Bereich wird definiert, in den die Mausbefehle eingebettet werden.
<Area Right="24"> Die rechte Hälfte des Bildes (48 / 2 = 24 Pixel) wird für die Aktion "Blickrichtung höher" festgelegt. Das entspricht der Tastenkombination Umschalt-Back.
<Cursor Type="DownArrow"/> Wir sagen dem Programm, welcher Mauszeiger beim Überfahren der rechten Bildhälfte angezeigt werden soll. In diesem Fall die Hand mit dem Pluszeichen. Es steht zwar "DownArrow" in der Zeile, was möglicherweise auf einen Programmierfehler von MS zurückzuführen ist, die Darstellung des Zeigers durch den Flusi erfolgt aber korrekt.
<Click Event="EYEPOINT_UP"/> Die K-Variable "Eyepoint_UP" finden wir in der o.g. Textdatei und fügen sie in diese Zeile ein. Klicken wir nun mit der Maus auf die rechte Bildhälfte, wird die schon genannte Tastenkombination simuliert und der Blick nach vorne erhöht.
</Area> Der Bereich für die rechte Bildhälfte wird abgeschlossen.
<Area Left="24"> Der zweite Bereich, diesmal für die linke Bildhälfte wird festgelegt.
<Cursor Type="UpArrow"/> Im linken Bereich soll die Hand mit dem Minuszeichen erscheinen.
<Click Event="EYEPOINT_DOWN"/> Es wird wieder festgelegt, welche Aktion bei einem Mausklick ausgeführt werden soll. In diesem Fall wird die Tastenkombination Umschalt-Enter simuliert und wir können über das Cockpit hinaus wieder den Boden sehen.
</Area> Der Bereich für die Linke Bildhälfte wird abgeschlossen.
</Mouse> Der Mouse-Bereich wird abgeschlossen.
</Gauge> Das Gauge ist fertig.

Das wars schon. Die Datei wird nun unter dem Namen View Switch.xml abgespeichert. Dabei ist zu beachten, das im Speichermenü des Editors Alle Dateien eingestellt wird, da der Editor sonst hinter dem xml noch die Endung .txt anhängt! Bevor es weitergeht, wird unsere Datei erst einmal getestet. Dazu öffnen wir sie im Explorer mit einem Doppelklick. Sind keine Schreibfehler vorhanden, wird die Datei im Internet-Explorer geöffnet. Anderenfalls erscheint eine Fehlermeldung mit Fehlerbeschreibung und Zeilennummer des Fehlers. In solch einem Fall muß der Internet-Explorer geschlossen werden, weil dort keine Korrektur möglich ist. Um an der Datei etwas zu ändern, wird sie mit der rechten Maustaste im Explorer angeklickt und im Kontext-Menü BEARBEITEN gewählt! Dadurch wird sie wieder im Editor geöffnet.

War der Test erfolgreich, erstellen wir uns einen neuen Ordner z.B auf Laufwerk C:. Diesen nennen wir einfach Cabfiles. In diesem Ordner, also nicht direkt auf C:, erstellen wir einen Unterordner mit Namen NewGauges. In den ersten Ordner kopieren wir die Cabdir.exe und in den NewGauges-Ordner unsere XML- und BMP-Datei. Danach gehen wir auf START-AUSFÜHREN, tippen folgendes ein und klicken dann auf OK:

c:\cabfiles\cabdir newgauges (das Leerzeichen zwischen cabdir und newgauges beachten!)

Dadurch wird die Cabdir.exe veranlasst, aus dem Inhalt des Ordners NewGauges eine Cab-Datei zu erstellen, die dann unter dem Namen NewGauges.cab im Ordner Cabfiles zu finden ist. Diese wird in den Ordner Gauges des FS2004 kopiert.
Als letztes müssen wir noch die Panel.cfg des Fliegers, dem wir das neue Gauge spendieren wollen, erweitern. Dazu wird im Abschitt [Window00] die Zeile gaugeXX=NewGauges!View Switch, xx, yy, 20, 14 eingefügt. XX steht dabei für die fortlaufende Gauges-Nummerierung, xx für die horizontale und yy für die vertikale Position des Gauges auf dem Panel. Die letzten beiden Werte bestimmen die Größe des Gauges auf dem Bildschirm und können so für die meisten Auflösungen belassen werden.

Hier noch ein Beispiel, wie ich das bei meiner 747 realisiert habe. Es sind dort noch weitere Gauges zu sehen, deren Programmierung ich in weiteren Workshops vorstellen werde.

2. Teil

In diesem Teil werden zwei weitere Schalter vorgestellt, die bis auf die beiden Befehlszeilen (Click Event) genau den gleichen Aufbau haben wie der View-Schalter aus dem ersten Teil, mit dem wir uns zuvor aber noch kurz beschäftigen müssen.

Der View-Schalter wurde so unkompliziert wie möglich von mir vorgestellt. Ein kleiner Nachteil dabei ist, daß der Schalter auch bei ausgeschalteter Bordelektronik stets erleuchtet ist. Dieses wollen wir noch schnell korrigieren. Dazu ist ein weiteres Bild notwendig, welches den Schalter in unbeleuchtetem Zustand darstellt. Ich habe dazu wieder ein ganz einfaches Beispiel gewählt. Wie schon gesagt, beim Erstellen der Schalter mit einem Malprogramm sind der Phantasie keine Grenzen gesetzt. Man kann sie mit 3D-Effekt versehen, fotorealistische Vorlagen verwenden usw. Zu beachten ist dabei, daß die Farbe SCHWARZ (Farbwert 0) als Transparenzfarbe im Flugsimulator genutzt wird. D.h., daß alles was schwarz ist, durchsichtig erscheint. So ist es z.B. möglich auch runde Schalter zu entwerfen.

(View_Off.bmp,47 x 25 Pixel)
(View_On.bmp, 47 x 25 Pixel)

Nun öffnen wir unsere View Switch.xml (im Explorer rechter Mausklick auf die Datei und Bearbeiten wählen) und fügen die folgenden fettgedruckten Zeilen in den Programmcode ein:

<Gauge Name="View Switch" Version="1.0">  
<Element> In einem Gauge können mehrere verschiedene Zustands-Abfragen untergebracht werden (siehe z.B den Throttles-Quadranten der 747, welches aus einem Grundbild mit vielen einzelnen Bildern besteht (Throttles, Parkbremse, Spoiler usw.). Diese Teile werden im Gauge als Elemente behandelt.
<Select> Auch ein Element selber kann mehrere Abfragen enthalten. diese werden durch Select voneinander getrennt.
<Value>(A:CIRCUIT GENERAL PANEL ON, bool)</Value> Hier nun wird Abgefragt, ob das Panel mit Strom versorgt wird oder abgeschaltet ist (durch Avionic / Batterieschalter). Die A-Variable dafür finden wir ebenfalls in der im 1. Teil beschrieben Datei aus der xmltp.zip von Avsim.com. Der Wert der Variablen ist 0 (Panel hat keinen Strom) oder 1 (Panel ist eingeschaltet).
<Failures> Fehlerabfrage - siehe nächste Zeile
<SYSTEM_ELECTRICAL_PANELS Action="0"/> Ist das Panel abgeschaltet soll keine Aktion stattfinden. Beim View-Schalter hat das zwar keine Auswirkung (man kann die Sicht trotzdem verstellen), aber es wird zumindest gleich der Schalterzustand OFF angezeigt.
</Failures> Ende der Fehlerabfrage
<Case Value="0"> Dieses ist die erste Abfrage auf den Panelzustand. Die Null bedeutet: das Panel hat keinen Strom.
<Image Name="View_Off.bmp" ImageSizes="47,25,47,25"/> Hat das Panel keinen Strom, so wird dieses Bild als Gauge angezeigt.
</Case> Ende der 0-Zustands-Abfrage
<Case Value="1"> Die zweite Abfrage. 1 bedeutet, das Panel ist eingeschaltet.
<Image Name="View_On.bmp" ImageSizes="47,25,47,25"/> Ist das Panel eingeschaltet, bzw. ist der Abgefragte Wert 1, so wird diese Bild angezeigt.
</Case> Ende der 1-Zustands-Abfrage
</Select> Ende des Bereichs
</Element> Das Element wird abgeschlossen.
<Mouse>  
<Area Right="23">  
<Cursor Type="DownArrow"/>  
<Click Event="EYEPOINT_UP"/>  
</Area>  
<Area Left="23">  
<Cursor Type="UpArrow"/>  
<Click Event="EYEPOINT_DOWN"/>  
</Area>  
</Mouse>  
</Gauge>  

Sind die Zeilen eingefügt, dann das Abspeichern nicht vergessen - aber den Editor noch nicht schliessen! Bevor wir nämlich eine neue Cab-Datei erstellen, wollen wir noch gleich zwei weitere Schalter basteln. Einen für den Zoom und einen für die Simulationsrate.

Dazu gehen wir nach dem Abspeichern der View Switch.xml im Editor auf Datei - Speichern unter und speichern die Datei unter dem Namen Zoom Switch.xml ab. Dabei nicht vergessen, unten im Editor bei Dateityp - Alle Dateien einzustellen. Ist das geschehen, gehen wir wieder auf Datei - Speichern unter und speichern die Datei nochmals unter dem Namen SimRate Switch.xml ab. Nun besitzen wir drei xml-Dateien, die aber noch den gleichen Inhalt haben. Als erstes korrigieren wir die SimRate Switch.xml, die als letztes gespeichert wurde und dadurch z.Z. im Editor geöffnet ist. Dazu ist das Ändern von nur 5 Zeilen notwendig:

<Gauge Name="SimRate Switch" Version="1.0"> Hier wird der Gaugename in SimRate Switch geändert
<Element>  
<Select>  
<Value>(A:CIRCUIT GENERAL PANEL ON, bool)</Value>  
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="0"/>  
</Failures>  
<Case Value="0">  
<Image Name="SimRate_Off.bmp" ImageSizes="47,25,47,25"/> Der Name für das Bild, daß bei ausgeschaltetem Panel angezeigt werden soll, wird eingetragen.
</Case>  
<Case Value="1">  
<Image Name="Simrate_On.bmp" ImageSizes="47,25,47,25"/> Hier wird der Bild-Name für das eingeschaltene Panel korrigiert.
</Case>  
</Select>  
</Element>  
<Mouse>  
<Area Right="23">  
<Cursor Type="DownArrow"/>  
<Click Event="SIM_RATE_DECR"/> Dieses ist der Befehl für das Verringern der Simulationsrate; wieder zu finden in o.g. Datei bei den K_Variablen.
</Area>  
<Area Left="23">  
<Cursor Type="UpArrow"/>  
<Click Event="SIM_RATE_INCR"/> Dieses ist der Befehl für das Erhöhen der SimRate.
</Area>  
</Mouse>  
</Gauge>  

Nach dem Ändern wird die Datei abgespeichert und danach die Zoom Switch.xml zum Bearbeiten geöffnet. Auch hier sind nur die 5 Zeilen zu ändern:

<Gauge Name="Zoom Switch" Version="1.0">
....
<Case Value="0">
<Image Name="Zoom_Off.bmp" ImageSizes="47,25,47,25"/>
....
<Case Value="1">
<Image Name="Zoom_On.bmp" ImageSizes="47,25,47,25"/>
....
<Click Event="ZOOM_IN"/>
....
<Click Event="ZOOM_OUT"/>

Nach der Änderung das Abspeichern nicht vergessen! Zur Sicherheit werden alle Dateien wieder durch Öffnen im Internet-Explorer getestet und gegebenenfalls korrigiert.

Was nun noch fehlt sind die entsprechenden Bilder für die neuen Schalter. Diese sollten im Aussehen dem View-Switch ähnlich sein und die Namen erhalten, die in den XML-Dateien verwendet wurden. Hier ein Beispiel:

Ist alles erledigt, werden, falls noch nicht geschehen, alle Datein in den Ordner NewGauges kopiert und, wie im Teil 1 beschrieben, eine neue Cab-Datei erstellt. Diese wird wiederum in den Gauges-Ordner der FS kopiert. Die Nachfrage auf das Überschreiben der bereits vorhandenen Datei bejahen!

Nun noch die Panel.cfg anpassen und ... fertig. Ein Beispiel, um das in der 747 des FS auszuprobieren (die Gauge-Nummerierung XX bitte anpassen):

gaugeXX=NewGauges!Simrate Switch, 67, 37, 20, 12
gaugeXX=NewGauges!View Switch, 45, 37, 20, 12
gaugeXX=NewGauges!Zoom Switch, 23, 37, 20, 12

Und so sieht das ganze nun bei mir aus (etwas verwaschen durch die Konvertierung ins JPG-Format). Weitere Schalter folgen im nächsten Workshop.

3. Teil

Heute möchte ich zuerst einen Schalter vorstellen, mit dem man das Smokesystem aktivieren kann. Interressant ist das bestimmt für diejenigen unter Euch, die sich das Smokesystem mit dem FlusiFix nachgerüstet haben. Gegenüber den bereits in den ersten beiden Teilen des Workshops vorgestellten Schaltern soll uns dieser gleichzeitig den aktuellen Zustand signalisieren (Smoke On oder Off). Dazu muß man sich natürlich entsprechende Bilder anfertigen.

Dann öffnen wir wieder den Editor und fügen die folgenden fettgedruckten Zeilen in das Textfenster ein:

<Gauge Name="Smoke Switch" Version="1.0"> Das Gauge bekommt seinen Namen.
<Element>  
<Select>  
<Value>(A:Smoke enable,bool)</Value> Die A-Variable SMOKE ENABLE enthält den Schaltzustand des Rauchsystems.
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="0"/>  
</Failures>  
<Case Value="0"> Dieses ist die erste Abfrage auf den Smokezustand. Die Null bedeutet: Smokesystem ist ausgeschaltet.
<Image Name="Smoke_Off.bmp" ImageSizes="47,25,47,25"/> Ist das Smokesystem ausgeschaltet, so wird dieses Bild angezeigt.
</Case> Ende der 0-Zustands-Abfrage
<Case Value="1"> Die zweite Abfrage. 1 bedeutet, das Smokesystem ist eingeschaltet.
<Image Name="Smoke_On.bmp" ImageSizes="47,25,47,25"/> Ist das Smokesystem eingeschaltet, so wird dieses Bild angezeigt.
</Case> Ende der 1-Zustands-Abfrage
</Select>  
</Element>  
<Mouse>  
<Cursor Type="Hand"/> Beim Draufzeigen auf den Schalter mit der Maus, erscheint die Hand.
<Click Event="SMOKE_TOGGLE"/> Beim Klick auf den Schalter bewirkt die K-Variable das Umschalten des gerade anliegenden Zustands des Smokesystems.
</Mouse>  
</Gauge>  

Wie immer das Abspeichern nicht vergessen (Smoke Switch.xml) und dabei daran denken, im Editor ALLE DATEIEN einzustellen. In dieser Form können alle möglichen Schalter programmiert werden. Man braucht nur die entsprechenden Variablen auszutauschen und die Namen der Bilder zu ändern. Für die Parkbremse sähe das dann etwa so aus:

<Gauge Name="ParkingBrake Switch" Version="1.0">
...
<Value>(A:Brake parking position, bool)</Value>
...
<Image Name="ParkingBrake_Off.bmp" ImageSizes="47,25,47,25"/>
...
<Image Name="ParkingBrake_On.bmp" ImageSizes="47,50,47,25"/>
...
<Click Event="PARKING_BRAKES"/>

Eine andere Art von Schalter sind solche, die man sich frei ausdenkt und die weiter nichts machen als ein- oder ausgeschaltet zu sein und für die es auch keine Variablen im FS gibt. Dazu gehören z.B. Schalter, die in den Kabinen irgendwelche Anzeigen aufleuchten lassen.
Ein gutes Beispiel hierfür sind die Nichtraucher- und Anschnallzeichen. Für diese gibt es zwar Variablen im FS (werden u.a. bei der 747 verwendet), jedoch werde ich sie hier nicht benutzen, da sie drei verschiedene Schaltzustände definieren. (aus, automatik, ein). Wir wollen uns aber nur auf Ein und Aus beschränken.

Und hier ist der entsprechende Programmcode:

<Gauge Name="NoSmoking Switch" Version="1.0">  
<Element>  
<Select>  
<Value>(G:Var1)</Value> Hier wird eine eigene Variable definiert, die den Zustand des Schalters speichern soll. Der Startwert ist 0 (ausgeschaltet).
Benötigt man in einem Gauge mehrere solcher Variablen, wird einfach fortlaufend weiternummeriert - Var2, Var3 usw.
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="0"/>  
<Case Value="0">  
<Image Name="NoSmoking_Off.bmp" ImageSizes="23,25,23,25"/>  
</Case>  
<Case Value="1">  
<Image Name="NoSmoking_On.bmp" ImageSizes="23,25,23,25"/>  
</Case>  
</Select>  
</Element>  
<Mouse>  
<CursorType="Hand"/>  
<Click>(G:Var1) 0 == if{ 1 } els{ 0 } (&gt;G:Var1)</Click> Bei einem Klick auf das Gauge wird durch diese Zeile der Inhalt der Variablen umgekehrt. Ist er 0, so wird er 1/ ist er 1, wird er 0.
</Mouse>  
</Gauge>  

Eine Besonderheit in der Click-Zeile sind die Zeichen "&gt;". Diese müssen im Editor genauso eingegeben werden. Sieht man sich den Code dann im I-Explorer an, so wird man feststellen, daß daraus das Zeichen ">" wird und das Ganze dann so aussieht: (>G:Var1). Das ">" bewirkt, daß der neue Wert dieser Variablen zugeordnet wird. Gibt man dieses Zeichen normal wie am Anfang oder Ende jeder Zeile über dieTastatur ein, funktioniert der Code nicht!
Um dieses Zeichen "<" innerhalb einer Zeile darzustellen, lautet die Zeichenfolge "&lt;"!

Wer nicht so talentiert beim Erstellen der Bilder für die Schalter ist, kann sich bei AVSIM.COM die Datei "cptts1.2.zip" runterladen, die viele Freeware-Bilder für Schalter enthält.

4. Teil

In diesem Teil möchte ich Zeigen wie einfach es ist, ein Panel mit Warnlichtern auszustatten. Dazu bieten sich besonders Lichter für den Overspeed und den Stall an, für die im FS9 bereits Variablen definiert sind. Ein Beispiel, wie die Warnleuchten realisiert werden können, ist auf dem Bild in Teil 2 des Workshops zu sehen. Und so lautet der Code für den Overspeed:

<Gauge Name="Overspeed Warning" Version="1.0">  
<Element>  
<Select>  
<Value>(A:Overspeed warning,bool)</Value> Die A-Variable lautet "Overspeed warning" und gibt den Zustand des Warnsystems an.
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="0"/>  
</Failures>  
<Case Value="0">  
<Image Name="Overspeed_Off.bmp" ImageSizes="57,18,57,18"/> Dieses Bild (erloschenes Licht) wird angezeigt, wenn die Fluggeschwindigkeit im normalen Limit liegt.
</Case>  
<Case Value="1">  
<Image Name="Overspeed_On.bmp" ImageSizes="57,18,57,18"/> Wird die zulässige Höchstgeschwindigkeit überschritten, erhält die A-Variable den Wert 1 und dieses Bild (erleuchtete Lampe) erscheint auf dem Panel.
Unabhängig davon gibt der FS9 zusätzlich noch einen Warnton aus und läßt die blinkende Zeile mit dem Warntext links unten auf dem Bildschirm erscheinen. Diese Zeile ist leider nicht ohne direkten Eingriff in eine Datei zu eleminieren. Man muß also damit leben.
</Case>  
</Select>  
</Element>  
</Gauge>  

Für die Stallwarnung brauchen wiederum nur ein paar Zeilen geändert werden:

<Gauge Name="Stall Warning" Version="1.0">
...
<Value>(A:Stall warning, bool)</Value>
...
<Image Name="Stall_Off.bmp" ImageSizes="57,18,57,18"/>
...
<Image Name="Stall_On.bmp" ImageSizes="57,18,57,18"/>
...

Im nächsten Teil geht es dann richtig zur Sache. Dann zeige ich wie man einen Pushback-Schalter programmieren kann, der beim Betätigen nicht nur den Pushback startet, sondern gleichzeitig noch die Parkbremse löst, sofern diese aktiviert war.

5. Teil

Wie angekündigt geht es in dieser Folge um das Programmieren eines Pushback-Schalters. Um die jeweiligen Zustände für Stop, Rückwärts, nach Links oder Rechts anzuzeigen, sind bei diesem Schalter vier Einzelbilder notwendig. Als Beispiel habe ich einen Schalter für die KingAir gewählt, den ich mir dafür im typischen Design des Panels erstellt habe.

1. Pushback_Off.bmp / 2. Pushback_On_B.bmp / 3. Pushback_On_L.bmp / 4. Pushback_On_R.bmp

<Gauge Name="Pushback Switch" Version="1.0">  
<Element>  
<Select>  
<Value>(A:Pushback state,bool)</Value> Pushback state ist die Variable, die den jeweiligen Zustand des Pushback enthält.
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="3"/> Der Normalzustand der Variable ist 3 (Pushback aus). Dieser Wert muß hier stehen, damit bei ausgeschaltetem Panel nur das Bild Pushback_Off.bmp angezeigt wird.
</Failures>  
<Case Value="0">  
<Image Name="Pushback_On_B.bmp" ImageSizes="64,67,64,67"/> Wurde der Pushback durch Anklicken des Schalters oder auch über die Tastenkombination UMSCHALT + P gestartet, wird die Variable auf 0 gesetzt und das Bild mit dem Pfeil nach unten für Rückwärtsfahren wird angezeigt.
</Case>  
<Case Value="1">  
<Image Name="Pushback_On_L.bmp" ImageSizes="64,67,64,67"/> Nach dem Starten des Pushback hat man die Möglichkeit mit den Tasten 1 und 2 eine Drehrichtung des Hecks nach links oder rechts zu wählen. Hierbei ändert sich natürlich der Inhalt der Variablen, der für eine Linksdrehung dann 1 beträgt. Diesem Wert wird das Bild mit dem Pfeil nach links zugewiesen.
</Case>  
<Case Value="2">  
<Image Name="Pushback_On_R.bmp" ImageSizes="64,67,64,67"/> Bei einer Rechtsdrehung ist der Inhalt der Variable 2 und das Bild mit dem Pfeil nach rechts soll angezeigt werden.
</Case>  
<Case Value="3">  
<Image Name="Pushback_Off.bmp" ImageSizes="64,67,64,67"/> Wird der Pushback mit Klick auf den Schalter oder über die Tastenkombination UMSCHALT + P beendet, beträgt der Inhalt der Variable 3 und das entsprechende Bild Pushback_Off.bmp wird angezeigt. Das Beenden des Pushback ist auch über die Taste 3 möglich!
</Case>  
<Case Value="4">  
<Image Name="Pushback_On_B.bmp" ImageSizes="64,67,64,67"/> Eine Besonderheit besitzt die Taste 4. Hiermit kann eine Drehbewegung, die normalerweise 90° beträgt, vorzeitig beendet werden, ohne den Pushback zu stoppen. Der Inhalt der Variablen ändert sich bei dieser Aktion auf 4. Die Maschine fährt danach weiter Rückwärts und das Bild mit dem Pfeil nach unten für Rückwärtsfahren wird wieder angezeigt. Mit den Tasten 1 oder 2 kann man auch wieder eine neue Drehbewegung einleiten!
</Case>  
</Select>  
</Element>  
<Mouse>  
<Cursor Type="Hand"/>  
<Click>(A:Pushback state,bool) 3 == if{ (A:Brake parking position,bool) 1 == if{ (&gt;K:PARKING_BRAKES) } } (&gt;K:TOGGLE_PUSHBACK)</Click> In dieser Zeile wird definiert, was das Betätigen des Schalters auslösen soll. Die Erklärung erfolgt weiter unten. Zu beachten ist, daß die Befehle alle in einer einzigen Zeile stehen müssen!
</Mouse>  
</Gauge>  

<Click>(A:Pushback state,bool) 3 == if{ (A:Brake parking position, bool) 1 == if{ (&gt;K:PARKING_BRAKES) } } (&gt;K:TOGGLE_PUSHBACK)</Click>

Beim Betätigen des Schalters wird zuerst mit A:Pushback state abgefragt, ob die Variable des Pushback den Wert 3 besitzt (ausgeschaltet). Wenn dieses so ist, erfolgt eine weitere Abfrage die den Zustand der Parkbremse durch A:Brake parking position ermittelt. Ist die Parkbremse gesetzt (Wert 1), so wird sie durch die K-Variable PARKING_BRAKES auf 0 gesetzt (Parkbremse gelöst). Ist der Zustand der Bremse bereits 0, passiert natürlich gar nichts.
Ist der Inhalt der Pushback-Variablen beim Betätigen des Schalters ungleich 3 (also 0, 1, 2 oder 4) erfolgt keine Abfrage der Parkbremse, da diese dann definitiv nicht gesetzt ist. Man könnte nun auch die Abfrage so erweitern, daß die Parkbremse beim Beenden des Pushback wieder gesetzt wird. Das hätte aber durch das abruppte Stoppen der Maschine ein starkes Aufbäumen der Nase zur Folge.
Nach den Abfragen steht dann ganz zuletzt die Variable K:TOGGLE_PUSHBACK in der Zeile, die den Pushback startet oder beendet.

Das Lösen der Parkbremse funktioniert natürlich nur über diesen Schalter. Über die Tastenkombination UMSCHALT + P geht es weiterhin nicht. Zu beachten sind auch wieder die Zeichen "&gt;", die genau so eingegeben werden müssen und im I-Explorer dann so ">" angezeigt werden (siehe Teil 3 des Workshops).

Will man auf die Abfrage der Parkbremse verzichten, so würde die Zeile
<Click Event="TOGGLE_PUSHBACK"/> genügen.

6. Teil

Im 6. Teil des Workshops möchte ich zeigen, daß es auch problemlos möglich ist, Gauges für das Bedienen der Störklappen nachzurüsten. Im folgenden Beispiel habe ich dafür zwei Gauges erstellt. Das erste dient zum ARMEN der Klappen im Landeanflug und mit dem zweiten Gauge lassen sie sich voll ausfahren / einfahren. Das Bild zeigt einen Auschnitt meines Learjets. Die Gauges sind beschriftet mit ARM und EXT (Extended).

Für das ARMEN, also das Einstellen der Störklappen auf Automatik, wird folgender Code benötigt:

<Gauge Name="Spoiler Armed Switch" Version="1.0">  
<Element>  
<Select>  
<Value>(A:Spoilers armed,bool)</Value> Über die A-Variable "Spoilers armed" wird der Zustand ermittelt (Automatik ein oder aus)
<Failures>  
<SYSTEM_ELECTRICAL_PANELS Action="0"/>  
</Failures>  
<Case Value="0">  
<Image Name="Spoiler_Arm_Off.bmp" ImageSizes="21,15,21,15"/> Dieses Bild wird angezeigt wenn die Spoiler nicht auf Automatik stehen.
</Case>  
<Case Value="1">  
<Image Name="Spoiler_Arm_On.bmp" ImageSizes="21,15,21,15"/> Wird der Schalter betätigt und die Spoiler somit auf Automatik gesetzt, wird dieses durch das zweite Bitmap angezeigt.
</Case>  
</Select>  
</Element>  
<Mouse>  
<Cursor Type="Hand"/>  
<Click Event="SPOILERS_ARM_TOGGLE"/> Die K-Variable "Spoilers_Arm_Toggle" sorgt beim Betätigen des Schalters für das Aktivieren bzw. Deaktivieren der Automatik.
</Mouse>  
</Gauge>  
Der Schalter für das vollständige Ausfahren der Störklappen ist genauso aufgebaut und unterscheidet sich vom Arm-Schalter nur durch ein paar Zeilen:

<Gauge Name="Spoiler Extended Switch" Version="1.0">
...
<Value>(A:Spoilers handle position,bool)</Value>
...
<Image Name="Spoiler_Ext_Off.bmp" ImageSizes="21,15,21,15"/>
...
<Image Name="Spoiler_Ext_On.bmp" ImageSizes="21,15,21,15"/>
...
<Click Event="SPOILERS_TOGGLE"/>
...

Bei diesen Schaltern gibt es eine Besonderheit, die man beachten muß. Die Störklappen lassen sich NICHT am Boden ARMEN, sondern nur wenn sich das Flugzeug in der Luft befindet. Am Boden werden die Klappen durch das Betätigen der Automatik vollständig ausgefahren! So ist es auch, wenn die Klappen durch Umschalt + # am Boden gearmed werden.
Hat man die Automatik beim Landeanflug aktiviert, so fahren die Klappen nach dem Aufsetzen aus und der Schalter "Extended" leuchtet ebenfalls auf. Gibt man nach dem Ausrollen wieder etwas Schub, um die Rollbahn zu verlassen, werden die Störklappen automatisch wieder eingefahren und beide Schalter gehen aus. Möchte man die Automatik nicht nutzen, kann man die Spoiler auch selber mit dem Schalter Ext nach dem Aufsetzen ausfahren.

7. Teil

Nach längerer Pause geht es heute mit zwei Gauges weiter, deren Funktion von den Programmierern unverständlicherweise kaum in Flugzeugpanels für den FS2004 genutzt wird. Dabei handelt es sich um das Betanken der Maschinen und um das Einstellen der Mixture bei Propellermaschinen, wenn die Automatik dafür in den Eigenschaften des FS9 zwecks realistischerem Fliegen ausgeschaltet wurde.
Obwohl die vorgestellten Gauges im engeren Sinne Schalter sind, wird im Panel trotzdem kein Schaltzustand angezeigt. Deshalb werden als Gaugebilder auch vorzugsweise Icons verwendet. Diese Icons passen in jedes Panel und sollten, wenn möglich, bei den schon vorhandenen Icons (Kniebrett, GPS... usw.) platziert werden.

Klickt man im Panel auf die Tanksäule, so wird der Inhalt aller vorhandenen Tanks der betreffenden Maschine um ca. 25% erhöht. Dieser Wert ist leider fest im FS9 vorgegeben und läßt sich (noch) nicht beeinflussen. Zu beachten ist, daß es im FS9 nur einen Befehl für das Auftanken, aber keinen für das Verringern des Treibstoffes gibt. Hat man also einmal zuviel geklickt kann man den übermäßigen Treibstoff nur per Hand im Menü wieder reduzieren!

Wird der Mixture-Schalter betätigt, so stellt sich automatisch je nach Flughöhe das beste Luft/Treibstoff-Gemisch für die Propeller ein. Vom Ausgangswert "Fette Mischung" beim Start und anfänglichem Steigflug sollte man den Schalter etwa alle 2.000 ft betätigen. Man sieht am Mixturehebel, wie sich mit steigender Höhe das Gemisch nach und nach abmagert (dünnere Luft / wenig Treibstoff). Im Sinkflug funktioniert das natürlich auch, indem das Gemisch nach und nach wieder fetter wird.

TankGauge:
<Gauge Name="Fuel Icon" Version="1.0">
<Image Name="Fuel_Icon.bmp" ImageSizes="12,12,19,19"/>
<Mouse>
<Cursor Type="Hand"/>
<Click Event="ADD_FUEL_QUANTITY"/>
</Mouse>
</Gauge>

MixtureGauge:
<Gauge Name="Mixture Set Best" Version="1.0">
<Image Name="Mixture_Set_Best_Icon.bmp" ImageSizes="12,12,19,19"/>
<Mouse>
<Cursor Type="Hand"/>
<Click Event="MIXTURE_SET_BEST"/>
</Mouse>
</Gauge>

Der Code kann so übernommen werden, wie er hier steht und auf der in den ersten Teilen des Workshops beschriebenen Weise weiterverarbeitet werden.