1ea33b9e5d
This fix assigns the correct id string, axis numbers and trim switch orientation under Windows, with some convinience tweak for view panning step. Tested on Windows 7/10 and Ubuntu, this is for the stick only.
473 lines
11 KiB
XML
473 lines
11 KiB
XML
<?xml version="1.0"?>
|
|
<!--
|
|
Copyright (c) 2011 Melchior FRANZ mfranz # aon : at
|
|
|
|
This driver supports joystick overlay files (see ./Warthog/README).
|
|
|
|
TMS ... Target Management Switch (black, rippled cursor switch, left side)
|
|
DMS ... Data Management Switch (black cursor switch with flat cross on top, right side)
|
|
CMS ... Countermeasures Management Switch (grey)
|
|
-->
|
|
|
|
<PropertyList>
|
|
<name>Thustmaster Joystick - HOTAS Warthog</name>
|
|
<name>Thrustmaster Joystick - HOTAS Warthog</name> <!-- in case they ever manage to fix their name -->
|
|
<name>Joystick - HOTAS Warthog</name>
|
|
|
|
<nasal>
|
|
<script>
|
|
var this = cmdarg().getParent();
|
|
var init = !contains(caller(0)[0], "init");
|
|
if (!contains(globals, "warthog"))
|
|
io.load_nasal(getprop("/sim/fg-root") ~ "/Input/Joysticks/ThrustMaster/Warthog/warthog.nas");
|
|
|
|
var jslistener = func init and call(setlistener, arg);
|
|
var popup = func gui.popupTip(call(sprintf, arg));
|
|
var is_helicopter = (func {(var n = props.globals.getNode("rotors", 0)) != nil and n.getAttribute("children")})();
|
|
var aircraft_type = getprop("/sim/type");
|
|
|
|
var load_overlay = func(name) {
|
|
foreach (var dir; [getprop("/sim/fg-home"), getprop("/sim/fg-root")]) {
|
|
var file = dir ~ "/Input/Joysticks/ThrustMaster/Warthog/Stick/" ~ name ~ ".xml";
|
|
if (io.stat(file) != nil) {
|
|
printlog("info", "WARTHOG: loading overlay " ~ file);
|
|
cmdarg().setValues({command: "nasal", script: ""});
|
|
io.read_properties(file, this);
|
|
props.runBinding(cmdarg());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 mod = 0;
|
|
var m = props.globals.initNode("/devices/status/joysticks/warthog/modifier", mod, "INT");
|
|
jslistener(m, func(n) mod = n.getValue());
|
|
|
|
var trimstep = 0.75;
|
|
var viewstep = 1.5;
|
|
var button = {18: {id: 0}};
|
|
|
|
var reset_zoom = func setprop("/sim/current-view/field-of-view", 55);
|
|
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;
|
|
}
|
|
|
|
load_overlay("generic");
|
|
if (is_helicopter)
|
|
load_overlay("helicopter");
|
|
if (aircraft_type)
|
|
load_overlay(aircraft_type);
|
|
foreach (var o; split(":", getprop("/input/joysticks/overlays") or ""))
|
|
load_overlay(o);
|
|
load_overlay(getprop("/sim/aircraft"));
|
|
</script>
|
|
</nasal>
|
|
|
|
<axis n="0">
|
|
<name>X-axis</name>
|
|
<desc>aileron</desc>
|
|
<tolerance>0.00001</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.00001</tolerance>
|
|
<binding>
|
|
<command>property-scale</command>
|
|
<property>/controls/flight/elevator</property>
|
|
<factor type="double">-1.0</factor>
|
|
</binding>
|
|
</axis>
|
|
|
|
<axis>
|
|
<name>Trim Hat Switch Left/Right</name>
|
|
<desc>adjust aileron trim, +mod: reset aileron trim</desc>
|
|
<number>
|
|
<unix>2</unix>
|
|
</number>
|
|
<low>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/aileron-trim", 0);
|
|
else
|
|
controls.aileronTrim(-trimstep);
|
|
</script>
|
|
</binding>
|
|
</low>
|
|
<high>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/aileron-trim", 0);
|
|
else
|
|
controls.aileronTrim(trimstep);
|
|
</script>
|
|
</binding>
|
|
</high>
|
|
</axis>
|
|
|
|
<!--Please fix me: axis are duplicated due to different binding per OS-->
|
|
|
|
<axis>
|
|
<name>Trim Hat Switch Left/Right</name>
|
|
<desc>adjust aileron trim, +mod: reset aileron trim</desc>
|
|
<number>
|
|
<windows>6</windows>
|
|
</number>
|
|
<low>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/aileron-trim", 0);
|
|
else
|
|
controls.aileronTrim(-trimstep);
|
|
</script>
|
|
</binding>
|
|
</low>
|
|
<high>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/aileron-trim", 0);
|
|
else
|
|
controls.aileronTrim(trimstep);
|
|
</script>
|
|
</binding>
|
|
</high>
|
|
</axis>
|
|
|
|
<axis>
|
|
<name>Trim Hat Switch Down/Up</name>
|
|
<desc>adjust elevator trim, +mod: reset elevator trim</desc>
|
|
<number>
|
|
<unix>3</unix>
|
|
</number>
|
|
<low>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/elevator-trim", 0);
|
|
else
|
|
controls.elevatorTrim(trimstep);
|
|
</script>
|
|
</binding>
|
|
</low>
|
|
<high>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/elevator-trim", 0);
|
|
else
|
|
controls.elevatorTrim(-trimstep);
|
|
</script>
|
|
</binding>
|
|
</high>
|
|
</axis>
|
|
|
|
<!--Please fix me: axis are duplicated due to different binding per OS-->
|
|
|
|
<axis>
|
|
<name>Trim Hat Switch Down/Up</name>
|
|
<desc>adjust elevator trim, +mod: reset elevator trim</desc>
|
|
<number>
|
|
<windows>7</windows>
|
|
</number>
|
|
<low>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/elevator-trim", 0);
|
|
else
|
|
controls.elevatorTrim(-trimstep);
|
|
</script>
|
|
</binding>
|
|
</low>
|
|
<high>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
setprop("/controls/flight/elevator-trim", 0);
|
|
else
|
|
controls.elevatorTrim(trimstep);
|
|
</script>
|
|
</binding>
|
|
</high>
|
|
</axis>
|
|
|
|
<button n="0">
|
|
<name>Trigger Button/Half Pushed</name>
|
|
<desc>camera oper</desc>
|
|
</button>
|
|
|
|
<button n="1">
|
|
<name>Weapons Release</name>
|
|
</button>
|
|
|
|
<button n="2">
|
|
<name>Nosewheel Steering Button</name>
|
|
<desc>toggle nosewheel steering/tailwheel lock</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
var i = !(getprop("/controls/gear/nose-wheel-steering") or 0);
|
|
setprop("/controls/gear/nose-wheel-steering", i);
|
|
setprop("/controls/gear/tailwheel-lock", !i);
|
|
popup("Tail Wheel %sLOCKED!", i ? "UN" : "");
|
|
</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<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">
|
|
<name>Master Mode Control Button</name>
|
|
</button>
|
|
|
|
<button n="5">
|
|
<name>Trigger Button/Fully Pushed</name>
|
|
<desc>gun trigger</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="6">
|
|
<name>left black curosr (TMS) up</name>
|
|
<desc>brakes, +mod: toggle parking brake</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(1)</script>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod) {
|
|
var i = controls.applyParkingBrake(1);
|
|
popup("Parking Brake %s", i ? "ON" : "OFF");
|
|
}
|
|
controls.applyBrakes(0)
|
|
</script>
|
|
</binding>
|
|
</mod-up>
|
|
</button>
|
|
|
|
<button n="7">
|
|
<name>left black cursor (TMS) right</name>
|
|
<desc>brakes right</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(1, 1)</script>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(0, 1)</script>
|
|
</binding>
|
|
</mod-up>
|
|
</button>
|
|
|
|
<button n="8">
|
|
<name>left black cursor (TMS) down</name>
|
|
<desc>brakes, +mod: toggle parking brake</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(1)</script>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod) {
|
|
var i = controls.applyParkingBrake(1);
|
|
popup("Parking Brake %s", i ? "ON" : "OFF");
|
|
}
|
|
controls.applyBrakes(0)
|
|
</script>
|
|
</binding>
|
|
</mod-up>
|
|
</button>
|
|
|
|
<button n="9">
|
|
<name>left black cursor (TMS) left</name>
|
|
<desc>brakes left</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(1, -1)</script>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>controls.applyBrakes(0, -1)</script>
|
|
</binding>
|
|
</mod-up>
|
|
</button>
|
|
|
|
<button n="10">
|
|
<name>right black cursor (DMS) up</name>
|
|
<desc>zoom in, +mod: reset zoom</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
reset_zoom();
|
|
else
|
|
view.decrease(1);
|
|
</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="11">
|
|
<name>right black cursor (DMS) right</name>
|
|
<desc>next active view, +mod: next view</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.stepView(1, mod)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="12">
|
|
<name>right black cursor (DMS) down</name>
|
|
<desc>zoom out, +mod: reset zoom</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
if (mod)
|
|
reset_zoom();
|
|
else
|
|
view.increase(1);
|
|
</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="13">
|
|
<name>right black cursor (DMS) left</name>
|
|
<desc>previous active view, +mod: previous view</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.stepView(-1, mod)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="14">
|
|
<name>grey cursor (CMS) up</name>
|
|
<desc>view up</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.panViewPitch(viewstep)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="15">
|
|
<name>grey cursor (CMS) right</name>
|
|
<desc>view right</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.panViewDir(viewdir[view.index] * viewstep)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="16">
|
|
<name>grey cursor (CMS) down</name>
|
|
<desc>view down</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.panViewPitch(-viewstep)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="17">
|
|
<name>grey cursor (CMS) left</name>
|
|
<desc>view left</desc>
|
|
<repeatable>true</repeatable>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>view.panViewDir(-viewdir[view.index] * viewstep)</script>
|
|
</binding>
|
|
</button>
|
|
|
|
<button n="18">
|
|
<name>grey cursor (CMS) push</name>
|
|
<desc>short: center view, long (>0.5 sec): centered cockpit view</desc>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
(func(id) {
|
|
settimer(func {
|
|
if (id == button[18].id) {
|
|
setprop("/sim/current-view/view-number", 0);
|
|
view.resetView();
|
|
}
|
|
}, 0.5, 1);
|
|
})(button[18].id += 1);
|
|
</script>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>
|
|
button[18].id += 1;
|
|
view.resetView();
|
|
</script>
|
|
</binding>
|
|
</mod-up>
|
|
</button>
|
|
</PropertyList>
|