From 558c321f9439eee30605889749c68cb0490e6d1e Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Thu, 8 Sep 2011 19:34:15 +0200
Subject: [PATCH 1/4] Fix problem with the A320 family not starting up
 correctly.

---
 Nasal/aircraft.nas | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Nasal/aircraft.nas b/Nasal/aircraft.nas
index 7c88f8d3d..a8c2b08bc 100644
--- a/Nasal/aircraft.nas
+++ b/Nasal/aircraft.nas
@@ -846,7 +846,7 @@ var tyresmoke = {
 	},
 	update: func {
 		var rollspeed = me.get_rollspeed();
-		var vert_speed = (me.vertical_speed) ? me.vertical_speed.getValue() : -999;
+		var vert_speed = (me.vertical_speed) != nil ? me.vertical_speed.getValue() : -999;
 		var groundspeed = me.speed.getValue();
 		var friction_factor = me.friction_factor.getValue();
 		var wow = me.wow.getValue();

From ea0c72494d275a0a0f71ef1c4b4ade530fa518a8 Mon Sep 17 00:00:00 2001
From: Melchior FRANZ <mfranz@aon.at>
Date: Fri, 9 Sep 2011 16:23:35 +0200
Subject: [PATCH 2/4] first draft of Thrustmaster HOTAS Warthog js config (WIP)

---
 .../Joysticks/ThrustMaster/Warthog-Stick.xml  | 182 ++++++++++
 .../ThrustMaster/Warthog-Throttle.xml         | 338 ++++++++++++++++++
 2 files changed, 520 insertions(+)
 create mode 100644 Input/Joysticks/ThrustMaster/Warthog-Stick.xml
 create mode 100644 Input/Joysticks/ThrustMaster/Warthog-Throttle.xml

diff --git a/Input/Joysticks/ThrustMaster/Warthog-Stick.xml b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
new file mode 100644
index 000000000..60a7e68e8
--- /dev/null
+++ b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<!--
+	Copyright (c) 2011   Melchior FRANZ   mfranz # aon : at
+	Work In Progress
+-->
+
+<PropertyList>
+	<name>Thustmaster Joystick - HOTAS Warthog</name>
+
+	<nasal>
+		<script>
+			var this = cmdarg().getParent();
+			var popup = func gui.popupTip(call(sprintf, arg));
+
+			var trimstep = 0.75;
+
+			foreach (var b; this.getChildren("button")) {
+				if (b.getAttribute("children") == 1) {
+					var name = b.getNode("name", 1).getValue() or "??";
+					b.setValues({binding: {command: "nasal", script: 'popup("' ~ name ~ '")'}});
+				}
+			}
+		</script>
+	</nasal>
+
+	<axis n="0">
+		<name>X-axis</name>
+		<desc>aileron</desc>
+		<tolerance>0.0001</tolerance>
+		<binding>
+			<command>property-scale</command>
+			<property>/controls/flight/aileron</property>
+		</binding>
+	</axis>
+
+	<axis n="1">
+		<name>Y-axis</name>
+		<desc>elevator</desc>
+		<tolerance>0.0001</tolerance>
+		<binding>
+			<command>property-scale</command>
+			<property>/controls/flight/elevator</property>
+			<factor type="double">-1.0</factor>
+		</binding>
+	</axis>
+
+	<axis n="2">
+		<name>Trim Coolie Left/Right</name>
+		<desc>aileron trim</desc>
+		<low>
+			<repeatable>true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>controls.aileronTrim(-trimstep)</script>
+			</binding>
+		</low>
+		<high>
+			<repeatable>true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>controls.aileronTrim(trimstep)</script>
+			</binding>
+		</high>
+	</axis>
+
+	<axis n="3">
+		<name>Trim Coolie Down/Up</name>
+		<desc>elevator trim</desc>
+		<low>
+			<repeatable>true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>controls.elevatorTrim(trimstep)</script>
+			</binding>
+		</low>
+		<high>
+			<repeatable>true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>controls.elevatorTrim(-trimstep)</script>
+			</binding>
+		</high>
+	</axis>
+
+	<button n="0">
+		<name>Trigger Button 1</name>
+		<desc>gun trigger stage 1</desc>
+		<binding>
+			<command>nasal</command>
+			<script>controls.trigger(1)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>controls.trigger(0)</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="1">
+		<name>Weapons Release</name>
+	</button>
+
+	<button n="2">
+		<name>Nosewheel Steering Button</name>
+	</button>
+
+	<button n="3">
+		<name>Paddle Switch</name>
+	</button>
+
+	<button n="4">
+		<name>Master Mode Control Button</name>
+	</button>
+
+	<button n="5">
+		<name>Trigger Button 2</name>
+		<desc>gun trigger stage 2</desc>
+		<binding>
+			<command>nasal</command>
+			<script>controls.trigger(2)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>controls.trigger(0)</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="6">
+		<name>Target Management Switch (TMS) up</name>
+	</button>
+
+	<button n="7">
+		<name>Target Management Switch (TMS) right</name>
+	</button>
+
+	<button n="8">
+		<name>Target Management Switch (TMS) down</name>
+	</button>
+
+	<button n="9">
+		<name>Target Management Switch (TMS) left</name>
+	</button>
+
+	<button n="10">
+		<name>Data Management Switch (DMS) up</name>
+	</button>
+
+	<button n="11">
+		<name>Data Management Switch (DMS) right</name>
+	</button>
+
+	<button n="12">
+		<name>Data Management Switch (DMS) down</name>
+	</button>
+
+	<button n="13">
+		<name>Data Management Switch (DMS) left</name>
+	</button>
+
+	<button n="14">
+		<name>Countermeasures Management Switch (CMS) up</name>
+	</button>
+
+	<button n="15">
+		<name>Countermeasures Management Switch (CMS) right</name>
+	</button>
+
+	<button n="16">
+		<name>Countermeasures Management Switch (CMS) down</name>
+	</button>
+
+	<button n="17">
+		<name>Countermeasures Management Switch (CMS) left</name>
+	</button>
+
+	<button n="18">
+		<name>Countermeasures Management Switch (CMS) push</name>
+	</button>
+</PropertyList>
diff --git a/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
new file mode 100644
index 000000000..fcef23493
--- /dev/null
+++ b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
@@ -0,0 +1,338 @@
+<?xml version="1.0"?>
+<!--
+	Copyright (c) 2011   Melchior FRANZ   mfranz # aon : at
+	Work In Progress
+-->
+
+<PropertyList>
+	<name>Thrustmaster Throttle - HOTAS Warthog</name>
+
+	<nasal>
+		<script>
+			var this = cmdarg().getParent();
+			var popup = func gui.popupTip(call(sprintf, arg));
+
+			var even_engines = [0, 2, 4, 6, 8, 10];
+			var odd_engines = [1, 3, 5, 7, 9, 11];
+			var viewstep = 0.5;
+			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;
+			}
+
+			foreach (var b; this.getChildren("button")) {
+				if (b.getAttribute("children") == 1) {
+					var name = b.getNode("name", 1).getValue() or "??";
+					b.setValues({binding: {command: "nasal", script: 'popup("' ~ name ~ '")'}});
+				}
+			}
+		</script>
+	</nasal>
+
+	<axis n="0">
+		<name>Mouse Horizontal</name>
+		<desc>mouse horizontal</desc>
+		<low>
+			<repeatable type="bool">true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>view.panViewDir(-viewdir[view.index] * viewstep)</script>
+			</binding>
+		</low>
+		<high>
+			<repeatable type="bool">true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>view.panViewDir(viewdir[view.index] * viewstep)</script>
+			</binding>
+		</high>
+	</axis>
+
+	<axis n="1">
+		<name>Mouse Vertical</name>
+		<desc>mouse vertical</desc>
+		<low>
+			<repeatable type="bool">true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>view.panViewPitch(viewstep)</script>
+			</binding>
+		</low>
+		<high>
+			<repeatable type="bool">true</repeatable>
+			<binding>
+				<command>nasal</command>
+				<script>view.panViewPitch(-viewstep)</script>
+			</binding>
+		</high>
+	</axis>
+
+	<axis n="2">
+		<name>Right Throttle</name>
+		<desc>right throttle (odd engines)</desc>
+		<tolerance>0.0001</tolerance>
+		<binding>
+			<command>nasal</command>
+			<script>controls.perEngineSelectedAxisHandler(0)(odd_engines)</script>
+		</binding>
+	</axis>
+
+	<axis>
+		<name>Left Throttle</name>
+		<desc>left throttle (even engines)</desc>
+		<number>
+			<unix>3</unix>
+			<mac>3</mac>
+			<windows>5</windows>
+		</number>
+		<tolerance>0.0001</tolerance>
+		<binding>
+			<command>nasal</command>
+			<script>controls.perEngineSelectedAxisHandler(0)(even_engines)</script>
+		</binding>
+	</axis>
+
+	<axis>
+		<name>Friction Wheel</name>
+		<desc>rudder trim</desc>
+		<number>
+			<unix>4</unix>
+			<mac>4</mac>
+			<windows>6</windows>
+		</number>
+		<binding>
+			<command>property-scale</command>
+			<property>/controls/flight/rudder</property>
+			<factor type="double">-1</factor>
+		</binding>
+	</axis>
+
+	<axis>
+		<name>Coolie Switch Horizontal</name>
+		<number>
+			<unix>5</unix>
+			<mac>5</mac>
+			<windows>3</windows>
+		</number>
+		<low>
+			<binding>
+				<command>nasal</command>
+				<script>popup("coolie switch left")</script>
+			</binding>
+		</low>
+		<high>
+			<binding>
+				<command>nasal</command>
+				<script>popup("coolie switch right")</script>
+			</binding>
+		</high>
+	</axis>
+
+	<axis>
+		<name>Coolie Switch Vertical</name>
+		<number>
+			<unix>6</unix>
+			<mac>6</mac>
+			<windows>4</windows>
+		</number>
+		<low>
+			<binding>
+				<command>nasal</command>
+				<script>popup("coolie switch up")</script>
+			</binding>
+		</low>
+		<high>
+			<binding>
+				<command>nasal</command>
+				<script>popup("coolie switch down")</script>
+			</binding>
+		</high>
+	</axis>
+
+	<button n="0">
+		<name>Mouse Button</name>
+		<desc>reset view</desc>
+		<binding>
+			<command>nasal</command>
+			<script>view.resetView()</script>
+		</binding>
+	</button>
+
+	<button n="1">
+		<name>MIC Switch Push</name>
+		<desc>Push To Talk (PTT)</desc>
+		<binding>
+			<command>nasal</command>
+			<script>controls.ptt(1)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>controls.ptt(0)</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="2">
+		<name>MIC Switch Up</name>
+	</button>
+
+	<button n="3">
+		<name>MIC Switch Forward</name>
+	</button>
+
+	<button n="4">
+		<name>MIC Switch Down</name>
+	</button>
+
+	<button n="5">
+		<name>MIC Switch Aft</name>
+	</button>
+
+	<button n="6">
+		<name>Speedbrake Forward</name>
+	</button>
+
+	<button n="7">
+		<name>Speedbrake Aft</name>
+	</button>
+
+	<button n="8">
+		<name>Boat Switch Forward</name>
+	</button>
+
+	<button n="9">
+		<name>Boat Switch Aft</name>
+	</button>
+
+	<button n="10">
+		<name>China Hat Forward</name>
+	</button>
+
+	<button n="11">
+		<name>China Hat Aft</name>
+	</button>
+
+	<button n="12">
+		<name>Pinky Switch Forward</name>
+	</button>
+
+	<button n="13">
+		<name>Pinky Switch Aft</name>
+	</button>
+
+	<button n="14">
+		<name>Left Throttle Button</name>
+	</button>
+
+	<button n="15">
+		<name>Engine Fuel Flow Left</name>
+	</button>
+
+	<button n="16">
+		<name>Engine Fuel Flow Right</name>
+	</button>
+
+	<button n="17">
+		<name>Engine Operate Left MOTOR</name>
+	</button>
+
+	<button n="18">
+		<name>Engine Operate Right MOTOR</name>
+	</button>
+
+	<button n="19">
+		<name>APU Start</name>
+	</button>
+
+	<button n="20">
+		<name>Landing Gear Horn Silence Button</name>
+	</button>
+
+	<button n="21">
+		<name>Flaps Up</name>
+		<desc>flaps up</desc>
+		<binding>
+			<command>nasal</command>
+			<script>controls.flapsDown(-1)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>controls.flapsDown(0)</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="22">
+		<name>Flaps Down</name>
+		<desc>flaps down</desc>
+		<binding>
+			<command>nasal</command>
+			<script>controls.flapsDown(1)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>controls.flapsDown(0)</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="23">
+		<name>EAC Switch</name>
+	</button>
+
+	<button n="24">
+		<name>RADAR ALT</name>
+	</button>
+
+	<button n="25">
+		<name>Autopilot (Dis)Engage</name>
+	</button>
+
+	<button n="26">
+		<name>Autopilot PATH</name>
+		<binding>
+			<command>nasal</command>
+			<script>popup("autopilot path")</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>popup("autopilot alt/hdg")</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="27">
+		<name>Autopilot ALT</name>
+		<binding>
+			<command>nasal</command>
+			<script>popup("autopilot alt")</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>popup("autopilot alt/hdg")</script>
+			</binding>
+		</mod-up>
+	</button>
+
+	<button n="28">
+		<name>Right Throttle Idle Switch</name>
+	</button>
+
+	<button n="29">
+		<name>Left Throttle Idle Switch</name>
+	</button>
+
+	<button n="30">
+		<name>Engine Operate Left IGN</name>
+	</button>
+
+	<button n="31">
+		<name>Engine Operate Right IGN</name>
+	</button>
+</PropertyList>

From 820323e8545a849f2bc4f1d7b1ceaa35a603897f Mon Sep 17 00:00:00 2001
From: Melchior FRANZ <mfranz@aon.at>
Date: Sat, 10 Sep 2011 00:03:11 +0200
Subject: [PATCH 3/4] warthog: add js overlay support

This allows to have generic axis/button definitions with aircraft
specific or aircraft class specific modification overlays. These
are also found in $FG_HOME, where they override global files. This
mechanism is desirable, because the Warthog is an A-10 replica, and
it should be possible to have an automatically loaded (1:1 mapped)
A-10 joystick config when flying the A-10, while using generic layouts
otherwise, or a specific helicopter overlay for helicopters etc.

Overlay files look exactly like joystick config files, except they
have no <name> and only specify actually differing elements. Axes
with <number> *need* a property index (e.g. <axis n="2">), which
usually corresponds to the <unix> value (i.e. n'th axis def in file).
Overlay files can contain a <nasal> block which is executed on
load. The files are to be named {$FG_ROOT,$FG_HOME}/Input/Joysticks/\
ThrustMaster/Warthog/{Joystick,Throttle}/{generic,helicopter,<aircraft>}\
.xml.
---
 .../Joysticks/ThrustMaster/Warthog-Stick.xml  | 28 ++++++++++++-
 .../ThrustMaster/Warthog-Throttle.xml         | 40 +++++++++++++++----
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/Input/Joysticks/ThrustMaster/Warthog-Stick.xml b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
index 60a7e68e8..35ce2a9a4 100644
--- a/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
+++ b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
@@ -8,11 +8,35 @@
 	<name>Thustmaster Joystick - HOTAS Warthog</name>
 
 	<nasal>
+		<command>nasal</command>
 		<script>
 			var this = cmdarg().getParent();
 			var popup = func gui.popupTip(call(sprintf, arg));
+			var is_dir = func(path) {(var stat = io.stat(path)) != nil and stat[11] == "dir"};
+			var is_helicopter = (var _ = props.globals.getNode("rotors", 0)) != nil and _.getAttribute("children");
+			var dir = "/Input/Joysticks/ThrustMaster/Warthog/Joystick/";
 
-			var trimstep = 0.75;
+			var overlay = {};
+			foreach (var base; [getprop("/sim/fg-root"), getprop("/sim/fg-home")])
+				if (is_dir(base ~ dir))
+					foreach (var file; directory(base ~ dir))
+						overlay[file] = base ~ dir ~ file;
+
+			var load_overlay = func(name) {
+				var file = name ~ ".xml";
+				if (contains(overlay, file)) {
+					printlog("info", "WARTHOG: loading overlay " ~ overlay[file]);
+					cmdarg().getNode("script").setValue("");
+					io.read_properties(overlay[file], this);
+					props.runBinding(cmdarg());
+				}
+			}
+
+			load_overlay("generic");
+			if (is_helicopter)
+				load_overlay("helicopter");
+			load_overlay(getprop("/sim/aircraft"));
+			overlay = nil;
 
 			foreach (var b; this.getChildren("button")) {
 				if (b.getAttribute("children") == 1) {
@@ -20,6 +44,8 @@
 					b.setValues({binding: {command: "nasal", script: 'popup("' ~ name ~ '")'}});
 				}
 			}
+
+			var trimstep = 0.75;
 		</script>
 	</nasal>
 
diff --git a/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
index fcef23493..e943f35c3 100644
--- a/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
+++ b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
@@ -8,9 +8,42 @@
 	<name>Thrustmaster Throttle - HOTAS Warthog</name>
 
 	<nasal>
+		<command>nasal</command>
 		<script>
 			var this = cmdarg().getParent();
 			var popup = func gui.popupTip(call(sprintf, arg));
+			var is_dir = func(path) {(var stat = io.stat(path)) != nil and stat[11] == "dir"}
+			var is_helicopter = (var _ = props.globals.getNode("rotors", 0)) != nil and _.getAttribute("children");
+			var dir = "/Input/Joysticks/ThrustMaster/Warthog/Throttle/";
+
+			var overlay = {};
+			foreach (var base; [getprop("/sim/fg-root"), getprop("/sim/fg-home")])
+				if (is_dir(base ~ dir))
+					foreach (var file; directory(base ~ dir))
+						overlay[file] = base ~ dir ~ file;
+
+			var load_overlay = func(name) {
+				var file = name ~ ".xml";
+				if (contains(overlay, file)) {
+					printlog("info", "WARTHOG: loading overlay " ~ overlay[file]);
+					cmdarg().getNode("script").setValue("");
+					io.read_properties(overlay[file], this);
+					props.runBinding(cmdarg());
+				}
+			}
+
+			load_overlay("generic");
+			if (is_helicopter)
+				load_overlay("helicopter");
+			load_overlay(getprop("/sim/aircraft"));
+			overlay = nil;
+
+			foreach (var b; this.getChildren("button")) {
+				if (b.getAttribute("children") == 1) {
+					var name = b.getNode("name", 1).getValue() or "??";
+					b.setValues({binding: {command: "nasal", script: 'popup("' ~ name ~ '")'}});
+				}
+			}
 
 			var even_engines = [0, 2, 4, 6, 8, 10];
 			var odd_engines = [1, 3, 5, 7, 9, 11];
@@ -20,13 +53,6 @@
 				var t = viewdir[i].getNode("type");
 				viewdir[i] = t != nil and t.getValue() == "lookat" ? 1 : -1;
 			}
-
-			foreach (var b; this.getChildren("button")) {
-				if (b.getAttribute("children") == 1) {
-					var name = b.getNode("name", 1).getValue() or "??";
-					b.setValues({binding: {command: "nasal", script: 'popup("' ~ name ~ '")'}});
-				}
-			}
 		</script>
 	</nasal>
 

From 587993138c10b5c0f046b450887283ab08bef5ff Mon Sep 17 00:00:00 2001
From: Melchior FRANZ <mfranz@aon.at>
Date: Sat, 10 Sep 2011 14:18:37 +0200
Subject: [PATCH 4/4] warthog: simplify overlay handling, more bindings

---
 .../Joysticks/ThrustMaster/Warthog-Stick.xml  |  79 +++++++---
 .../ThrustMaster/Warthog-Throttle.xml         | 149 +++++++++++++++---
 2 files changed, 180 insertions(+), 48 deletions(-)

diff --git a/Input/Joysticks/ThrustMaster/Warthog-Stick.xml b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
index 35ce2a9a4..7cc8db36d 100644
--- a/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
+++ b/Input/Joysticks/ThrustMaster/Warthog-Stick.xml
@@ -12,31 +12,25 @@
 		<script>
 			var this = cmdarg().getParent();
 			var popup = func gui.popupTip(call(sprintf, arg));
-			var is_dir = func(path) {(var stat = io.stat(path)) != nil and stat[11] == "dir"};
 			var is_helicopter = (var _ = props.globals.getNode("rotors", 0)) != nil and _.getAttribute("children");
-			var dir = "/Input/Joysticks/ThrustMaster/Warthog/Joystick/";
-
-			var overlay = {};
-			foreach (var base; [getprop("/sim/fg-root"), getprop("/sim/fg-home")])
-				if (is_dir(base ~ dir))
-					foreach (var file; directory(base ~ dir))
-						overlay[file] = base ~ dir ~ file;
 
 			var load_overlay = func(name) {
-				var file = name ~ ".xml";
-				if (contains(overlay, file)) {
-					printlog("info", "WARTHOG: loading overlay " ~ overlay[file]);
-					cmdarg().getNode("script").setValue("");
-					io.read_properties(overlay[file], this);
-					props.runBinding(cmdarg());
+				foreach (var dir; [getprop("/sim/fg-home"), getprop("/sim/fg-root")]) {
+					var file = dir ~ "/Input/Joysticks/ThrustMaster/Warthog/Joystick/" ~ name;
+					if (io.stat(file) != nil) {
+						printlog("info", "WARTHOG: loading overlay " ~ file);
+						cmdarg().getNode("script").setValue("");
+						io.read_properties(file, this);
+						props.runBinding(cmdarg());
+						break;
+					}
 				}
 			}
 
-			load_overlay("generic");
+			load_overlay("generic.xml");
 			if (is_helicopter)
-				load_overlay("helicopter");
-			load_overlay(getprop("/sim/aircraft"));
-			overlay = nil;
+				load_overlay("helicopter.xml");
+			load_overlay(getprop("/sim/aircraft") ~ ".xml");
 
 			foreach (var b; this.getChildren("button")) {
 				if (b.getAttribute("children") == 1) {
@@ -45,6 +39,10 @@
 				}
 			}
 
+			var mod = 0;
+			var _ = props.globals.initNode("/devices/status/joysticks/warthog/modifier", mod, "INT");
+			setlistener(_, func(n) mod = n.getValue());
+
 			var trimstep = 0.75;
 		</script>
 	</nasal>
@@ -72,38 +70,58 @@
 
 	<axis n="2">
 		<name>Trim Coolie Left/Right</name>
-		<desc>aileron trim</desc>
+		<desc>adjust aileron trim,  +mod: reset aileron trim</desc>
 		<low>
 			<repeatable>true</repeatable>
 			<binding>
 				<command>nasal</command>
-				<script>controls.aileronTrim(-trimstep)</script>
+				<script>
+					if (mod)
+						controls.aileronTrim(-trimstep);
+					else
+						setprop("/controls/flight/aileron-trim", 0);
+				</script>
 			</binding>
 		</low>
 		<high>
 			<repeatable>true</repeatable>
 			<binding>
 				<command>nasal</command>
-				<script>controls.aileronTrim(trimstep)</script>
+				<script>
+					if (mod)
+						controls.aileronTrim(trimstep);
+					else
+						setprop("/controls/flight/aileron-trim", 0);
+				</script>
 			</binding>
 		</high>
 	</axis>
 
 	<axis n="3">
 		<name>Trim Coolie Down/Up</name>
-		<desc>elevator trim</desc>
+		<desc>adjust elevator trim,  +mod: reset elevator trim</desc>
 		<low>
 			<repeatable>true</repeatable>
 			<binding>
 				<command>nasal</command>
-				<script>controls.elevatorTrim(trimstep)</script>
+				<script>
+					if (mod)
+						controls.elevatorTrim(trimstep);
+					else
+						setprop("/controls/flight/elevator-trim", 0);
+				</script>
 			</binding>
 		</low>
 		<high>
 			<repeatable>true</repeatable>
 			<binding>
 				<command>nasal</command>
-				<script>controls.elevatorTrim(-trimstep)</script>
+				<script>
+					if (mod)
+						controls.elevatorTrim(-trimstep);
+					else
+						setprop("/controls/flight/elevator-trim", 0);
+				</script>
 			</binding>
 		</high>
 	</axis>
@@ -133,6 +151,19 @@
 
 	<button n="3">
 		<name>Paddle Switch</name>
+		<desc>modifier button</desc>
+		<binding>
+			<command>property-assign</command>
+			<property>/devices/status/joysticks/warthog/modifier</property>
+			<value>1</value>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>property-assign</command>
+				<property>/devices/status/joysticks/warthog/modifier</property>
+				<value>0</value>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="4">
diff --git a/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
index e943f35c3..c9c83465c 100644
--- a/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
+++ b/Input/Joysticks/ThrustMaster/Warthog-Throttle.xml
@@ -12,23 +12,18 @@
 		<script>
 			var this = cmdarg().getParent();
 			var popup = func gui.popupTip(call(sprintf, arg));
-			var is_dir = func(path) {(var stat = io.stat(path)) != nil and stat[11] == "dir"}
 			var is_helicopter = (var _ = props.globals.getNode("rotors", 0)) != nil and _.getAttribute("children");
-			var dir = "/Input/Joysticks/ThrustMaster/Warthog/Throttle/";
-
-			var overlay = {};
-			foreach (var base; [getprop("/sim/fg-root"), getprop("/sim/fg-home")])
-				if (is_dir(base ~ dir))
-					foreach (var file; directory(base ~ dir))
-						overlay[file] = base ~ dir ~ file;
 
 			var load_overlay = func(name) {
-				var file = name ~ ".xml";
-				if (contains(overlay, file)) {
-					printlog("info", "WARTHOG: loading overlay " ~ overlay[file]);
-					cmdarg().getNode("script").setValue("");
-					io.read_properties(overlay[file], this);
-					props.runBinding(cmdarg());
+				foreach (var dir; [getprop("/sim/fg-home"), getprop("/sim/fg-root")]) {
+					var file = dir ~ "/Input/Joysticks/ThrustMaster/Warthog/Throttle/" ~ name;
+					if (io.stat(file) != nil) {
+						printlog("info", "WARTHOG: loading overlay " ~ file);
+						cmdarg().getNode("script").setValue("");
+						io.read_properties(file, this);
+						props.runBinding(cmdarg());
+						break;
+					}
 				}
 			}
 
@@ -36,7 +31,6 @@
 			if (is_helicopter)
 				load_overlay("helicopter");
 			load_overlay(getprop("/sim/aircraft"));
-			overlay = nil;
 
 			foreach (var b; this.getChildren("button")) {
 				if (b.getAttribute("children") == 1) {
@@ -45,8 +39,12 @@
 				}
 			}
 
-			var even_engines = [0, 2, 4, 6, 8, 10];
-			var odd_engines = [1, 3, 5, 7, 9, 11];
+			var mod = 0;
+			var _ = props.globals.initNode("/devices/status/joysticks/warthog/modifier", mod, "INT");
+			setlistener(_, func(n) mod = n.getValue());
+
+			var left_engines = [0, 2, 4, 6, 8, 10];
+			var right_engines = [1, 3, 5, 7, 9, 11];
 			var viewstep = 0.5;
 			var viewdir = props.globals.getNode("/sim").getChildren("view");
 			forindex (var i; viewdir) {
@@ -100,11 +98,11 @@
 		<tolerance>0.0001</tolerance>
 		<binding>
 			<command>nasal</command>
-			<script>controls.perEngineSelectedAxisHandler(0)(odd_engines)</script>
+			<script>controls.perEngineSelectedAxisHandler(0)(right_engines)</script>
 		</binding>
 	</axis>
 
-	<axis>
+	<axis n="3">
 		<name>Left Throttle</name>
 		<desc>left throttle (even engines)</desc>
 		<number>
@@ -115,11 +113,11 @@
 		<tolerance>0.0001</tolerance>
 		<binding>
 			<command>nasal</command>
-			<script>controls.perEngineSelectedAxisHandler(0)(even_engines)</script>
+			<script>controls.perEngineSelectedAxisHandler(0)(left_engines)</script>
 		</binding>
 	</axis>
 
-	<axis>
+	<axis n="4">
 		<name>Friction Wheel</name>
 		<desc>rudder trim</desc>
 		<number>
@@ -129,12 +127,12 @@
 		</number>
 		<binding>
 			<command>property-scale</command>
-			<property>/controls/flight/rudder</property>
+			<property>/controls/flight/rudder-trim</property>
 			<factor type="double">-1</factor>
 		</binding>
 	</axis>
 
-	<axis>
+	<axis n="5">
 		<name>Coolie Switch Horizontal</name>
 		<number>
 			<unix>5</unix>
@@ -155,7 +153,7 @@
 		</high>
 	</axis>
 
-	<axis>
+	<axis n="6">
 		<name>Coolie Switch Vertical</name>
 		<number>
 			<unix>6</unix>
@@ -254,22 +252,103 @@
 
 	<button n="15">
 		<name>Engine Fuel Flow Left</name>
+		<desc>engine fuel flow left</desc>
+		<binding>
+			<command>nasal</command>
+			<script>
+				foreach (var i; left_engines)
+					setprop("/controls/engines/engine[" ~ i ~ "]/fuel-pump", 1);
+			</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>
+					foreach (var i; left_engines)
+						setprop("/controls/engines/engine[" ~ i ~ "]/fuel-pump", 0);
+				</script>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="16">
 		<name>Engine Fuel Flow Right</name>
+		<desc>engine fuel flow right</desc>
+		<binding>
+			<command>nasal</command>
+			<script>
+				foreach (var i; right_engines)
+					setprop("/controls/engines/engine[" ~ i ~ "]/fuel-pump", 1);
+			</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>
+					foreach (var i; right_engines)
+						setprop("/controls/engines/engine[" ~ i ~ "]/fuel-pump", 0);
+				</script>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="17">
 		<name>Engine Operate Left MOTOR</name>
+		<desc>engine operate left motor (magnetos)</desc>
+		<binding>
+			<command>nasal</command>
+			<script>
+				foreach (var i; left_engines)
+					setprop("/controls/engines/engine[" ~ i ~ "]/magnetos", 1);
+			</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>
+					foreach (var i; left_engines)
+						setprop("/controls/engines/engine[" ~ i ~ "]/magnetos", 0);
+				</script>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="18">
 		<name>Engine Operate Right MOTOR</name>
+		<desc>engine operate right motor (magnetos)</desc>
+		<binding>
+			<command>nasal</command>
+			<script>
+				foreach (var i; right_engines)
+					setprop("/controls/engines/engine[" ~ i ~ "]/magnetos", 1);
+			</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>
+					foreach (var i; right_engines)
+						setprop("/controls/engines/engine[" ~ i ~ "]/magnetos", 0);
+				</script>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="19">
 		<name>APU Start</name>
+		<desc>APU (auxiliary power unit) on/off</desc>
+		<binding>
+			<command>property-assign</command>
+			<property>/controls/electric/APU-generator</property>
+			<value>1</value>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>property-assign</command>
+				<property>/controls/electric/APU-generator</property>
+				<value>0</value>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="20">
@@ -356,9 +435,31 @@
 
 	<button n="30">
 		<name>Engine Operate Left IGN</name>
+		<desc>start left engines</desc>
+		<binding>
+			<command>nasal</command>
+			<script>call(controls.startEngine, [1] ~ left_engines)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>call(controls.startEngine, [0] ~ left_engines)</script>
+			</binding>
+		</mod-up>
 	</button>
 
 	<button n="31">
 		<name>Engine Operate Right IGN</name>
+		<desc>start right engines</desc>
+		<binding>
+			<command>nasal</command>
+			<script>call(controls.startEngine, [1] ~ right_engines)</script>
+		</binding>
+		<mod-up>
+			<binding>
+				<command>nasal</command>
+				<script>call(controls.startEngine, [0] ~ right_engines)</script>
+			</binding>
+		</mod-up>
 	</button>
 </PropertyList>