<?xml version="1.0"?>
<!--
$Id$


_______________________________________ Layout _______________________________________


axis 0:              aileron
axis 1:              elevator
axis 2:              rudder
axis 3:              throttle


                     no modifier     F3              F4              F3+F4
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
button 0 (trigger):  brakes          parking brake   speed brake     thrust revers.
button 1 (left):     flaps up        gear up         previous view   previous view (all)
button 2 (middle):   reset view dir  tail wheel lock cockpit view    reset all trim
button 3 (right):    flaps down      gear down       next view       next view (all)
button 4 (F1):       brakes left     *               zoom out        *
button 5 (F2):       brakes right    *               zoom in         *
button 6 (F3):       //////////////////////// modifier 0 /////////////////////////
button 7 (F4):       //////////////////////// modifier 1 /////////////////////////
button 8 (>>):       *               *               *               *
button 9 (<<):       *               *               *               *
hat left:            look left       leaner mixture  aileron trim    rudder trim
hat right:           look right      richer mixture  aileron trim    rudder trim
hat back:            look down       dec prop pitch  elevator trim   *
hat forward:         look up         inc prop pitch  elevator trim   *


F3 and F4 are used like "Shift", "Control", or "Alternate" on computer keyboards.
For example: press F3 and keep holding it down while pressing the fire
button/trigger -> toggle parking brake

When flying the Harrier, "F3/hat left" and "right" control the thrust vector.



With the keyboard's Control key pressed, the following keys have a different meaning:

Control +            no modifier
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
button 0 (trigger):  trigger selected weapon
button 1 (left):     switch to previous weapon system
button 3 (right):    switch to next weapon system



___________________________________ Customization ____________________________________



If you want to change some (or all) of the bindings, the recommended way is
to copy this file to your home directory, make your changes there, and include
it from your personal preferences.xml file. You can use any number lower than
1000 for n in <js-named n="0">. The lowest takes precedence in case of identical
names. You can include such a preferences.xml file with the ~~config option,
e.g. ~~config=$HOME/.fgfs/preferences.xml, and you can put that ~~config line
into your personal $HOME/.fgfsrc file.

<?xml version="1.0"?>
<PropertyList>
	<input>
		<js-named n="100">
			<joysticks include="your-modified-copy.xml"/>
		</js-named>
	</input>
</PropertyList>


The property "/input/joysticks/js[0]/data/modifier" indicates the "shift" level.
F3 sets bit 0, F4 sets bit 1. The property is zero if none of the shift buttons
is pressed, 1 if F3 is pressed, 2 if F4 is pressed, and 3 if both F3 and F4 are
pressed.

Note that you have to enclose nasal scripts in <script><![CDATA[...]]></script>
if they contain characters that interfere with the xml markup. This is the case
if you are, for example, using < (lower than). Alternatively, you can 'escape'
the character with "&lt;".

Also note that all nasal code shares a common namespace, so it's possible to set
a variable in one nasal binding, and to read it in another.



____________________________________ References ______________________________________



Joysticks:      $FG_ROOT/Docs/README.Joystick.html
Properties:     see property browser (fgfs menu: "File"->"Browse internal properties")

Nasal:          http://www.plausible.org/nasal/
Nasal examples: $FG_ROOT/Nasal/


______________________________________________________________________________________

                                                 ~~ Melchior FRANZ <mfranz # aon : at>
-->

<PropertyList>
	<name>SAITEK CYBORG 3D USB</name>
	<name>CYBORG 3D USB</name>

	<data>
		<mode type="int">0</mode>
		<modifier type="int">0</modifier>
	</data>

	<nasal>
		<script>
			var selfN = cmdarg().getParent();
			var dataN = selfN.getNode("data");
			var modeN = dataN.getNode("mode");
			var modifierN = dataN.getNode("modifier");
			var f1 = 0;
			var f2 = 0;
			var left_brake = 0;
			var right_brake = 0;
			var trigger = 0;

			var modifier = 0;

			var setmodifier = func(bit, val) {
				modifierN.setValue(modifier = bits.switch(modifier, bit, val));
			}

			if (props.globals.getNode("/rotors", 0) != nil) {
				selfN.getNode("axis[0]/binding/power").setIntValue(1);
				selfN.getNode("axis[1]/binding/power").setIntValue(1);
			}

			var viewdir = props.globals.getNode("/sim").getChildren("view");
			forindex (var i; viewdir) {
				var t = viewdir[i].getNode("type");
				viewdir[i] = t != nil and t.getValue() == "lookat" ? 1 : -1;
			}

			var kbdshift = props.globals.getNode("/devices/status/keyboard/shift", 1);
			var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1);
			var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1);

			var m = 0;
			var setmode = func m = modifierN.getValue() + modeN.getValue() * 4;
			setlistener(modeN, setmode);
			setlistener(modifierN, setmode, 1);

			var aircraft = getprop("/sim/aircraft");

			var thrust_display = func nil;
			if (aircraft == "harrier") {
				thrust_display = func {
					thv = getprop("/controls/engines/engine[0]/mixture");
					gui.popupTip("Thrust vector " ~ int(thv * 120 - 20 + 0.5));
				}
			}
		</script>
	</nasal>

	<axis n="0">
		<desc>aileron</desc>
		<binding>
			<command>property-scale</command>
			<property>/controls/flight/aileron</property>
			<power type="int">2</power>
		</binding>
	</axis>

	<axis n="1">
		<desc>elevator</desc>
		<binding>
			<command>property-scale</command>
			<property>/controls/flight/elevator</property>
			<factor type="double">-1.0</factor>
			<power type="int">2</power>
		</binding>
	</axis>

	<axis>
		<desc>rudder</desc>
		<number>
			<unix>2</unix>
			<mac>2</mac>
			<windows>3</windows>
		</number>
		<binding>
			<command>property-scale</command>
			<property>/controls/flight/rudder</property>
			<offset type="double">0.0</offset>
			<factor type="double">1.0</factor>
			<power type="int">2</power>
		</binding>
	</axis>

	<axis>
		<desc>throttle</desc>
		<number>
			<unix>3</unix>
			<mac>3</mac>
			<windows>2</windows>
		</number>
		<binding>
			<command>nasal</command>
			<script>controls.throttleAxis()</script>
		</binding>
	</axis>

	<button n="0">
		<name>Trigger</name>
		<desc>brakes,  +Ctrl: fire,  +F3: parking brake,  +F4: speedbrake,  +F3+F4: thrust reverser</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					if (kbdctrl.getBoolValue()) {
						controls.trigger(trigger = 1);
					} else {
						controls.applyBrakes(1);
					}
				} elsif (m == 1) {
					controls.applyBrakes(1);
				} elsif (m == 2) {
					#
				} elsif (m == 3) {
					#
				}
			</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>
					if (m == 0) {
						if (trigger)
							controls.trigger(trigger = 0);
						else
							controls.applyBrakes(0);

						controls.applyBrakes(0);
					} elsif (m == 1) {
						i = controls.applyParkingBrake(1);
						gui.popupTip("Parking Brake " ~ (i ? "ON" : "OFF"));
						controls.applyBrakes(0);
					} elsif (m == 2) {
						i = !getprop("/controls/flight/speedbrake");
						setprop("/controls/flight/speedbrake", i);
						gui.popupTip("Speed Brake " ~ (i ? "ON" : "OFF"));
					} elsif (m == 3) {
						i = !getprop("/controls/engines/engine[0]/reverser");
						props.setAll("/controls/engines/engine", "reverser", i);
						gui.popupTip("Thrust Reverser " ~ (i ? "ON" : "OFF"));
					}
				</script>
			</binding>
		</mod-up>
	</button>

	<button n="1">
		<name>Left Button</name>
		<desc>flaps up,  +F3: gear up,  +F4: previous active view,  +F3+F4: previous view</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					if (kbdctrl.getBoolValue())
						controls.weaponSelect(-1);
					else
						controls.flapsDown(-1);

				} elsif (m == 1) {
					controls.gearDown(-1);
				} elsif (m == 2) {
					view.stepView(-1, 0);
				} elsif (m == 3) {
					view.stepView(-1, 1);
				}
			</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>
					if (m == 0) {
						controls.flapsDown(0);
					} elsif (m == 1) {
						controls.gearDown(0);
					} elsif (m == 2) {
						#
					} elsif (m == 3) {
						#
					}
				</script>
			</binding>
		</mod-up>
	</button>

	<button n="2">
		<name>Middle Button</name>
		<desc>center view,  +F3: toggle tail-wheel lock,  +F4: reset view,  +F3+F4: reset trim</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					view.resetView();
				} elsif (m == 1) {
					i = !getprop("/controls/gear/tailwheel-lock");
					setprop("/controls/gear/tailwheel-lock", i);
					gui.popupTip("Tail Wheel " ~ (i ? "LOCKED" : "UNLOCKED"));
				} elsif (m == 2) {
					setprop("/sim/current-view/view-number", 0);
					view.resetView();
				} elsif (m == 3) {
					setprop("/controls/flight/elevator-trim", 0);
					setprop("/controls/flight/aileron-trim", 0);
					setprop("/controls/flight/rudder-trim", 0);
				}
			</script>
		</binding>
	</button>

	<button n="3">
		<name>Right Button</name>
		<desc>flaps down,  +Ctrl: weapon select,  +F3: gear down,  +F4: next active view,  +F3+F4: next view</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					if (kbdctrl.getBoolValue())
						controls.weaponSelect(1);
					else
						controls.flapsDown(1);

				} elsif (m == 1) {
					controls.gearDown(1);
				} elsif (m == 2) {
					view.stepView(1, 0);
				} elsif (m == 3) {
					view.stepView(1, 1);
				}
			</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>
					if (m == 0) {
						controls.flapsDown(0);
					} elsif (m == 1) {
						controls.gearDown(0);
					} elsif (m == 2) {
						#
					} elsif (m == 3) {
						#
					}
				</script>
			</binding>
		</mod-up>
	</button>

	<button n="4">
		<name>F1</name>
		<desc>brakes left,  +F4: zoom out</desc>
		<repeatable type="bool">true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				f1 = 1;
				if (m == 0) {
					if (!left_brake)
						controls.applyBrakes(left_brake = 1, -1);

				} elsif (m == 1) {
					#
				} elsif (m == 2) {
					f2 ? view.resetFOV() : view.increase();
				} elsif (m == 3) {
					#
				}
			</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>
					f1 = 0;
					if (m == 0) {
						controls.applyBrakes(left_brake = 0, -1);
					} elsif (m == 1) {
						#
					} elsif (m == 2) {
						#
					} elsif (m == 3) {
						#
					}
				</script>
			</binding>
		</mod-up>
	</button>

	<button n="5">
		<name>F2</name>
		<desc>brakes right,  +F4: zoom in</desc>
		<repeatable type="bool">true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				f2 = 1;
				if (m == 0) {
					if (!right_brake)
						controls.applyBrakes(right_brake = 1, 1);

				} elsif (m == 1) {
					#
				} elsif (m == 2) {
					f1 ? view.resetFOV() : view.decrease();
				} elsif (m == 3) {
					#
				}
			</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>
					f2 = 0;
					if (m == 0) {
						controls.applyBrakes(right_brake = 0, 1);
					} elsif (m == 1) {
						#
					} elsif (m == 2) {
						#
					} elsif (m == 3) {
						#
					}
				</script>
			</binding>
		</mod-up>
	</button>

	<button n="6"><!-- bit 0 -->
		<name>F3</name>
		<desc>modifier for other buttons</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>setmodifier(0, 1)</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>setmodifier(0, 0)</script>
			</binding>
		</mod-up>
	</button>

	<button n="7"><!-- bit 1 -->
		<name>F4</name>
		<desc>modifier for other buttons</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>setmodifier(1, 1)</script>
		</binding>
		<mod-up>
			<binding>
				<command>nasal</command>
				<script>setmodifier(1, 0)</script>
			</binding>
		</mod-up>
	</button>

	<button n="8">
		<name>>></name>
		<desc>unused</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				<![CDATA[
				text = "read $FG_ROOT/Input/Joysticks/Saitek/Cyborg-Gold-3d-USB.xml";
				print("Please " ~ text ~ " for the full joystick layout.");
				gui.popupTip(text);
				]]>
			</script>
		</binding>
	</button>

	<button n="9">
		<name>&lt;&lt;</name>
		<desc>unused</desc>
		<repeatable type="bool">false</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				<![CDATA[
				text = "read $FG_ROOT/Input/Joysticks/Saitek/Cyborg-Gold-3d-USB.xml";
				print("Please " ~ text ~ " for the full joystick layout.");
				gui.popupTip(text);
				]]>
			</script>
		</binding>
	</button>

	<button n="10">
		<name>Hat Up</name>
		<desc>view up,  +F3: increase prop pitch,  +F4: elevator trim down</desc>
		<repeatable>true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					view.panViewPitch(1);
				} elsif (m == 1) {
					controls.adjPropeller(1);
				} elsif (m == 2) {
					controls.elevatorTrim(0.75);
				} elsif (m == 3) {
					#
				}
			</script>
		</binding>
	</button>

	<button n="11">
		<name>Hat Left</name>
		<desc>view left,  +F3: mixture leaner,  +F4: aileron trim left,  +F3+F4: rudder trim left</desc>
		<repeatable>true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					view.panViewDir(-viewdir[view.index]);
				} elsif (m == 1) {
					controls.adjMixture(-1);
					thrust_display();
				} elsif (m == 2) {
					controls.aileronTrim(-0.75);
				} elsif (m == 3) {
					controls.rudderTrim(-0.75);
				}
			</script>
		</binding>
	</button>

	<button n="12">
		<name>Hat Right</name>
		<desc>view right,  +F3: mixture richer,  +F4: aileron trim right,  +F3+F4: rudder trim right</desc>
		<repeatable>true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					view.panViewDir(viewdir[view.index]);
				} elsif (m == 1) {
					controls.adjMixture(1);
					thrust_display();
				} elsif (m == 2) {
					controls.aileronTrim(0.75);
				} elsif (m == 3) {
					controls.rudderTrim(0.75);
				}
			</script>
		</binding>
	</button>

	<button n="13">
		<name>Hat Down</name>
		<desc>view down,  +F3: decrease prop pitch,  +F4: elevator trim up</desc>
		<repeatable>true</repeatable>
		<binding>
			<command>nasal</command>
			<script>
				if (m == 0) {
					view.panViewPitch(-1);
				} elsif (m == 1) {
					controls.adjPropeller(-1);
				} elsif (m == 2) {
					controls.elevatorTrim(-0.75);
				} elsif (m == 3) {
					#
				}
			</script>
		</binding>
	</button>
</PropertyList>