1
0
Fork 0

Merge branch 'master' of gitorious.org:fg/fgdata

This commit is contained in:
Frederic Bouvier 2010-11-02 21:44:34 +01:00
commit a653f4bcdb
12 changed files with 868 additions and 116 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<PropertyList>
<sim>
<model>
<logo>
<name type="string">Pumpkin</name>
<texture>../../Generic/Logos/pumpkin.png</texture>
</logo>
</model>
</sim>
</PropertyList>

View file

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Walk view module for FlightGear.
Copyright (C) 2010 Anders Gidenstam (anders(at)gidenstam.org)
This file is licensed under the GPL license v2 or later.
-->
<PropertyList>
<!--
This module can be used to add suitable key bindings for walk views
to any aircraft.
Usage example:
Include it in the keybord section of the aircraft's -set file.
<keyboard include="../Generic/WalkView/walk-view-keys.xml">
Note: If the aircraft use other custom key bindings for the same keys
the walk view bindings should be merged into the aircraft specific
bindings. The walk view API commands return false if not currently
in a walk view so the other alternative action can be put in an
if statement. E.g.
if (!walkview.forward(4.0)) {
# Perform the non-walk view action of this key.
}
-->
<!-- Keyboard commands -->
<key n="87">
<name>W</name>
<desc>Walk view: Run forward.</desc>
<binding>
<command>nasal</command>
<script>
if (!walkview.forward(4.0)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.forward(0);
</script>
</binding>
</mod-up>
</key>
<key n="119">
<name>w</name>
<desc>Walk view: Walk forward.</desc>
<binding>
<command>nasal</command>
<script>
if (!walkview.forward(1.0)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.forward(0);
</script>
</binding>
</mod-up>
</key>
<key n="100">
<name>d</name>
<desc>Walk view: Side step right.</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>
if (!walkview.side_step(0.5)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.side_step(0);
</script>
</binding>
</mod-up>
</key>
<key n="68">
<name>D</name>
<desc>Walk view: Fast side step right.</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>
if (!walkview.side_step(1.0)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.side_step(0);
</script>
</binding>
</mod-up>
</key>
<key n="97">
<name>a</name>
<desc>Walk view: Side step left.</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>
if (!walkview.side_step(-0.5)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.side_step(0);
</script>
</binding>
</mod-up>
</key>
<key n="65">
<name>A</name>
<desc>Walk view: Fast side step left.</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>
if (!walkview.side_step(-1.0)) {
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.side_step(0);
</script>
</binding>
</mod-up>
</key>
<key n="115">
<name>s</name>
<desc>Walk view: Walk backwards.</desc>
<binding>
<command>nasal</command>
<script>
if (!walkview.forward(-1.0)) {
controls.startEngine(1);
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.forward(0);
controls.startEngine(0);
</script>
</binding>
</mod-up>
</key>
<!-- Remove this if you for some reason have 2d panels and want the default
Swap panels function on 'S'.
-->
<!-- key n="83">
<name>S</name>
<desc>Walk view: Walk backwards.</desc>
<binding>
<command>nasal</command>
<script>
walkview.forward(-1.0);
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
walkview.forward(0);
</script>
</binding>
</mod-up>
</key -->
</PropertyList>

View file

@ -83,7 +83,8 @@ var active_walker = func {
# speed ... speed in m/sec : double
#
# set_pos(pos)
# get_pos() : position
# pos ... position in meter : [double, double, double]
# get_pos() : position ([meter, meter, meter])
#
# set_eye_height(h)
# get_eye_height() : int (meter)
@ -97,13 +98,15 @@ var active_walker = func {
# [19.5, 0.3, -8.85]);
# var walker = walkview.walker.new("Passenger View", constraint);
#
# See Aircraft/Nordstern, Aircraft/Short_Empire and Aircraft/ZLT-NT
# for working examples of walk views.
#
# NOTES:
# Currently there can only be one view manager per view so the
# walk view should not have any other view manager.
#
var walker = {
var Walker = {
new : func (view_name, constraints = nil, managers = nil) {
var obj = { parents : [walker] };
var obj = { parents : [Walker] };
obj.view = view.views[view.indexof(view_name)];
obj.constraints = constraints;
obj.managers = managers;
@ -124,7 +127,7 @@ var walker = {
view.manager.register(view_name, obj);
walkers[obj.view.getPath()] = obj;
debug.dump(obj);
#debug.dump(obj);
return obj;
},
active : func {
@ -216,13 +219,52 @@ var walker = {
###############################################################################
# Constraint classes. Determines where the view can walk.
#
# Convenience functions.
# Build a UnionConstraint hierarchy from a list of constraints.
# cs - list of constraints : [constraint]
var makeUnionConstraint = func (cs) {
if (size(cs) < 2) return cs[0];
var ret = cs[0];
for (var i = 1; i < size(cs); i += 1) {
ret = UnionConstraint.new(ret, cs[i]);
}
return ret;
}
# Build a UnionConstraint hierachy that represents a polyline path
# with a certain width. Each internal point gets a circular surface.
# points - list of points : [position] ([[meter, meter, meter]])
# width - width of the path : length (meter)
# round_ends - put a circle also on the first and last points : bool
var makePolylinePath = func (points, width, round_ends = 0) {
if (size(points) < 2) return nil;
var ret = LinePlane.new(points[0], points[1], width);
if (round_ends) {
ret = UnionConstraint.new(line,
CircularXYSurface.new(points[0], width/2));
}
for (var i = 2; i < size(points); i += 1) {
var line = LinePlane.new(points[i-1], points[i], width);
if (i + 1 < size(points) or round_ends) {
line = UnionConstraint.new
(line,
CircularXYSurface.new(points[i], width/2));
}
ret = UnionConstraint.new(line, ret);
}
return ret;
}
# The union of two constraints.
# c1, c2 - the constraints : constraint
# NOTE: Assumes that the constraints are convex.
var unionConstraint = {
var UnionConstraint = {
new : func (c1, c2) {
var obj = { parents : [unionConstraint] };
var obj = { parents : [UnionConstraint] };
obj.c1 = c1;
obj.c2 = c2;
return obj;
@ -244,40 +286,82 @@ var unionConstraint = {
}
};
# Build a unionConstraint hierarchy from a list of constraints.
# cs - list of constraints : [constraint]
var makeUnionConstraint = func (cs) {
if (size(cs) < 2) return cs[0];
var ret = cs[0];
for (var i = 1; i < size(cs); i += 1) {
ret = unionConstraint.new(ret, cs[i]);
}
return ret;
}
# Rectangular plane defined by a straight line and a width.
# The line is extruded horizontally on each side by width/2 into a
# planar surface.
# p1, p2 - the line endpoints. : position ([meter, meter, meter])
# width - total width of the plane. : length (meter)
var LinePlane = {
new : func (p1, p2, width) {
var obj = { parents : [LinePlane] };
obj.p1 = p1;
obj.p2 = p2;
obj.halfwidth = width/2;
obj.length = vec2.length(vec2.sub(p2, p1));
obj.e1 = vec2.normalize(vec2.sub(p2, p1));
obj.e2 = [obj.e1[1], -obj.e1[0]];
obj.k = (p2[2] - p1[2]) / obj.length;
# Mostly aligned plane sloping along the X axis.
# minp - the X,Y minimum point : position (meter)
# maxp - the X,Y maximum point : position (meter)
var slopingYAlignedPlane = {
new : func (minp, maxp) {
var obj = { parents : [slopingYAlignedPlane] };
obj.minp = minp;
obj.maxp = maxp;
obj.kxz = (maxp[2] - minp[2])/(maxp[0] - minp[0]);
return obj;
},
constrain : func (pos) {
var p = [pos[0], pos[1], pos[2]];
if (pos[0] < me.minp[0]) p[0] = me.minp[0];
if (pos[0] > me.maxp[0]) p[0] = me.maxp[0];
if (pos[1] < me.minp[1]) p[1] = me.minp[1];
if (pos[1] > me.maxp[1]) p[1] = me.maxp[1];
p[2] = me.minp[2] + me.kxz * (pos[0] - me.minp[0]);
var p = [pos[0], pos[1], pos[2]];
var pXY = vec2.sub(pos, me.p1);
var along = vec2.dot(pXY, me.e1);
var across = vec2.dot(pXY, me.e2);
var along2 = max(0, min(along, me.length));
var across2 = max(-me.halfwidth, min(across, me.halfwidth));
if (along2 != along or across2 != across) {
# Compute new XY position.
var t = vec2.add(vec2.mul(along2, me.e1), vec2.mul(across2, me.e2));
p[0] = me.p1[0] + t[0];
p[1] = me.p1[1] + t[1];
}
# Compute Z positition.
p[2] = me.p1[2] + me.k * along2;
return p;
}
};
# Circular surface aligned with the XY plane
# center - the center point : position ([meter, meter, meter])
# radius - radius in the XY plane : length (meter)
var CircularXYSurface = {
new : func (center, radius) {
var obj = { parents : [CircularXYSurface] };
obj.center = center;
obj.radius = radius;
return obj;
},
constrain : func (pos) {
var p = [pos[0], pos[1], me.center[2]];
var pXY = vec2.sub(pos, me.center);
var lXY = vec2.length(pXY);
if (lXY > me.radius) {
var t = vec2.add(me.center, vec2.mul(me.radius/lXY, pXY));
p[0] = t[0];
p[1] = t[1];
}
return p;
},
};
# Mostly aligned plane sloping along the X axis.
# NOTE: Obsolete. Use linePlane instead.
# minp - the X,Y minimum point : position ([meter, meter, meter])
# maxp - the X,Y maximum point : position ([meter, meter, meter])
var SlopingYAlignedPlane = {
new : func (minp, maxp) {
return LinePlane.new([minp[0], (minp[1] + maxp[1])/2, minp[2]],
[maxp[0], (minp[1] + maxp[1])/2, maxp[2]],
(maxp[1] - minp[1]));
}
};
# Action constraint
# Triggers an action when entering or exiting the constraint.
# constraint - the area in question : constraint
@ -285,9 +369,9 @@ var slopingYAlignedPlane = {
# on_exit(x, y) - function that is called when the walker leaves the area.
# x and y are <0, 0 or >0 depending on in which direction(s)
# the walker left the constraint.
var actionConstraint = {
var ActionConstraint = {
new : func (constraint, on_enter = nil, on_exit = nil) {
var obj = { parents : [actionConstraint] };
var obj = { parents : [ActionConstraint] };
obj.constraint = constraint;
obj.on_enter = on_enter;
obj.on_exit = on_exit;
@ -366,3 +450,33 @@ var closerXY = func (pos, p1, p2) {
var l2 = [p2[0] - pos[0], p2[1] - pos[1]];
return (l1[0]*l1[0] + l1[1]*l1[1]) - (l2[0]*l2[0] + l2[1]*l2[1]);
}
var max = func (a, b) {
return b > a ? b : a;
}
var min = func (a, b) {
return a > b ? b : a;
}
# 2D vector math.
var vec2 = {
add : func (a, b) {
return [a[0] + b[0], a[1] + b[1]];
},
sub : func (a, b) {
return [a[0] - b[0], a[1] - b[1]];
},
mul : func (k, a) {
return [k * a[0], k * a[1]];
},
length : func (a) {
return math.sqrt(a[0]*a[0] + a[1]*a[1]);
},
dot : func (a, b) {
return a[0]*b[0] + a[1]*b[1];
},
normalize : func (a) {
var s = 1/vec2.length(a);
return [s * a[0], s * a[1]];
}
}

View file

@ -1,9 +1,8 @@
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="joystick.xsl"?>
<!-- $Id$ -->
<!-- Saitek AV8R/Aviator
Copyright (C) 2007 - 2009 Anders Gidenstam (anders(at)gidenstam.org)
Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
This file is released under the GPL license v2 or later.
-->
<PropertyList>
@ -21,18 +20,27 @@
# TM0: All selected; TM1: #1 & #2; TM2: #3 & #4
var engine_axis_mode = 0;
# Valid only in TM1 and TM2.
# EA0: throttle, +mod: propeller
# EA1: propeller, +mod: throttle
# EA0: throttle
# EA1: mixture
# EA2: propeller
var quick_view_active = 0;
var old_view = view.point.save();
var pressed = [0,0,0,0,0,0,0,0,0,0,0,0];
# Map engines to throttles for TM1 (0, 1) and TM2 (2, 3)
var engine = [0, 1, 2, 3];
# Do per-aircraft modifications
if (getprop("/sim/model/path") ==
"Aircraft/Short_Empire/Models/Short_Empire-model.xml") {
# Do per-aircraft modifications
if (contains({"Aircraft/Short_Empire/Models/Short_Empire-model.xml" : 0,
"Aircraft/Lockheed1049/Models/Lockheed1049_twa.xml" : 0},
getprop("/sim/model/path"))) {
# TM1: the outer engines, TM2: the inner engines
engine = [0, 3, 1, 2];
}
if (contains({"Aircraft/DO-X/Models/dox.xml" : 0},
getprop("/sim/model/path"))) {
engine = [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11],
[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]];
}
var goal_heading_offset =
@ -46,7 +54,7 @@
var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1);
var quick_view = func {
dir = arg[0];
var dir = arg[0];
if (dir == 0) {
quick_view_active = 0;
view.point.move(old_view, 0.1);
@ -99,7 +107,13 @@
</nasal>
<!-- Analog axis 0. Aileron -->
<axis n="0">
<axis>
<name>Stick left/right</name>
<number>
<unix>0</unix>
<mac>0</mac>
<windows>0</windows>
</number>
<desc>aileron</desc>
<binding>
<command>property-scale</command>
@ -111,7 +125,13 @@
</axis>
<!-- Analog axis 1. Elevator -->
<axis n="1">
<axis>
<name>Stick forward/back</name>
<number>
<unix>1</unix>
<mac>1</mac>
<windows>1</windows>
</number>
<desc>elevator</desc>
<binding>
<command>property-scale</command>
@ -125,6 +145,7 @@
<!-- Analog axis 3. Rudder -->
<axis>
<name>Stick twist</name>
<number>
<unix>3</unix>
<mac>2</mac>
@ -139,10 +160,18 @@
<factor type="double">1.0</factor>
<squared type="bool">true</squared>
</binding>
<!-- binding>
<command>nasal</command>
<script>
setprop("sim/current-view/goal-heading-offset-deg",
-90.0*cmdarg().getNode("setting").getValue());
</script>
</binding -->
</axis>
<!-- Analog axis 2. Throttle 1 -->
<axis>
<name>Left throttle</name>
<number>
<unix>2</unix>
<mac>3</mac>
@ -155,43 +184,43 @@
if (engine_select_mode == 0) {
controls.throttleAxis();
} else {
var val = cmdarg().getNode("setting").getValue();
var ctrl_pp =
"/controls/engines/engine[" ~
((engine_select_mode == 1) ? engine[0] : engine[2]) ~ "]/" ~
(engine_axis_mode ? "propeller-pitch" : "throttle");
setprop(ctrl_pp, (1 - val)/2);
controls.perEngineSelectedAxisHandler(engine_axis_mode)
((engine_select_mode == 1) ? engine[0] : engine[2]);
}
</script>
</binding>
</axis>
<!-- Analog axis 4. Throttle 2 -->
<axis n="4">
<desc>TM0: mixture, +mod: propeller pitch, TM1: throttle/propeller 2, TM2: throttle/propeller 4</desc>
<axis>
<name>Right throttle</name>
<number>
<unix>4</unix>
<mac>4</mac>
<windows>4</windows>
</number>
<desc>TM0: mixture, TM1: throttle/propeller 2, TM2: throttle/propeller 4</desc>
<binding>
<command>nasal</command>
<script>
if (engine_select_mode == 0) {
if (!modifier) {
controls.mixtureAxis();
} else {
controls.propellerAxis();
}
controls.mixtureAxis();
} else {
var val = cmdarg().getNode("setting").getValue();
var ctrl_pp =
"/controls/engines/engine[" ~
((engine_select_mode == 1) ? engine[1] : engine[3]) ~ "]/" ~
(engine_axis_mode ? "propeller-pitch" : "throttle");
setprop(ctrl_pp, (1 - val)/2);
controls.perEngineSelectedAxisHandler(engine_axis_mode)
((engine_select_mode == 1) ? engine[1] : engine[3]);
}
</script>
</binding>
</axis>
<!-- Axis 5. Hat left/right -->
<axis n="5">
<axis>
<name>Hat left/right</name>
<number>
<unix>5</unix>
<mac>5</mac>
<windows>5</windows>
</number>
<desc>quick view left/right, +mod: horizontal view pan</desc>
<low>
<repeatable type="bool">true</repeatable>
@ -238,10 +267,12 @@
<binding>
<command>nasal</command>
<script>
<![CDATA[
trace("Axis 5, Hat: low released!");
if (!modifier) {
quick_view(0);
}
]]>
</script>
</binding>
</mod-up>
@ -249,7 +280,13 @@
</axis>
<!-- Axis 6. Hat up/down -->
<axis n="6">
<axis>
<name>Hat up/down</name>
<number>
<unix>6</unix>
<mac>6</mac>
<windows>6</windows>
</number>
<desc>view reset/quick view front, +mod: vertical view pan</desc>
<low>
<repeatable type="bool">true</repeatable>
@ -270,9 +307,11 @@
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (!modifier) {
#quick_view(0);
}
]]>
</script>
</binding>
</mod-up>
@ -296,9 +335,11 @@
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (!modifier) {
quick_view(0);
}
]]>
</script>
</binding>
</mod-up>
@ -306,8 +347,13 @@
</axis>
<!-- Trigger Button -->
<button n="0">
<button>
<name>Trigger</name>
<number>
<unix>0</unix>
<mac>0</mac>
<windows>0</windows>
</number>
<desc>function modifier (mod)</desc>
<binding>
<command>nasal</command>
@ -327,8 +373,13 @@
</button>
<!-- Center Button -->
<button n="2">
<button>
<name>Center button</name>
<number>
<unix>2</unix>
<mac>2</mac>
<windows>2</windows>
</number>
<desc>brakes, +mod: Toggle parking brake</desc>
<binding>
<command>nasal</command>
@ -352,8 +403,13 @@
</button>
<!-- Left Button -->
<button n="1">
<button>
<name>Left button</name>
<number>
<unix>1</unix>
<mac>1</mac>
<windows>1</windows>
</number>
<desc>left brake, +mod: PTT</desc>
<binding>
<command>nasal</command>
@ -378,8 +434,13 @@
</button>
<!-- Right Button -->
<button n="3">
<button>
<name>Right button</name>
<number>
<unix>3</unix>
<mac>3</mac>
<windows>3</windows>
</number>
<desc>right brake, +mod: trigger</desc>
<binding>
<command>nasal</command>
@ -404,8 +465,13 @@
</button>
<!-- Button: T1 -->
<button n="4">
<button>
<name>T1</name>
<number>
<unix>4</unix>
<mac>4</mac>
<windows>4</windows>
</number>
<desc>next view, +mod: zoom in +Shift: next weapon</desc>
<repeatable type="bool">true</repeatable>
<binding>
@ -442,8 +508,13 @@
</button>
<!-- Button: T2 -->
<button n="5">
<button>
<name>T2</name>
<number>
<unix>5</unix>
<mac>5</mac>
<windows>5</windows>
</number>
<desc>previous view, +mod: zoom out, +Shift: previous weapon</desc>
<repeatable type="bool">true</repeatable>
<binding>
@ -480,8 +551,13 @@
</button>
<!-- Button: T3 -->
<button n="6">
<button>
<name>T3</name>
<number>
<unix>6</unix>
<mac>6</mac>
<windows>6</windows>
</number>
<desc>trim nose down, +mod: disarm speed brakes</desc>
<repeatable type="bool">true</repeatable>
<binding>
@ -498,8 +574,13 @@
</button>
<!-- Button: T4 -->
<button n="7">
<button>
<name>T4</name>
<number>
<unix>7</unix>
<mac>7</mac>
<windows>7</windows>
</number>
<desc>trim nose up, +mod: deploy speed brakes</desc>
<repeatable type="bool">true</repeatable>
<binding>
@ -516,8 +597,13 @@
</button>
<!-- Button: T5 -->
<button n="8">
<button>
<name>T5</name>
<number>
<unix>8</unix>
<mac>8</mac>
<windows>8</windows>
</number>
<desc>retract flaps one step, +mod: gear up</desc>
<binding>
<command>nasal</command>
@ -542,8 +628,13 @@
</button>
<!-- Button: T6 -->
<button n="9">
<button>
<name>T6</name>
<number>
<unix>9</unix>
<mac>9</mac>
<windows>9</windows>
</number>
<desc>deploy flaps one step, +mod: gear down</desc>
<binding>
<command>nasal</command>
@ -568,8 +659,13 @@
</button>
<!-- Button: T7 -->
<button n="10">
<button>
<name>T7</name>
<number>
<unix>10</unix>
<mac>10</mac>
<windows>10</windows>
</number>
<desc>Increase magnetos, +mod: Engine throttle/propeller axis swap</desc>
<binding>
<command>nasal</command>
@ -578,14 +674,19 @@
if (!modifier) {
controls.stepMagnetos(1);
} else {
engine_axis_mode = !engine_axis_mode;
engine_axis_mode = 2*!engine_axis_mode;
}
</script>
</binding>
</button>
<!-- Button: T8 -->
<button n="11">
<button>
<number>
<unix>11</unix>
<mac>11</mac>
<windows>11</windows>
</number>
<name>T8</name>
<desc>Decrease magnetos, +mod: Engine throttle/propeller axis swap</desc>
<binding>
@ -595,15 +696,20 @@
if (!modifier) {
controls.stepMagnetos(-1);
} else {
engine_axis_mode = !engine_axis_mode;
engine_axis_mode = 2*!engine_axis_mode;
}
</script>
</binding>
</button>
<!-- Button: 3-way Mode switch -->
<button n="12">
<button>
<name>Mode 1</name>
<number>
<unix>12</unix>
<mac>12</mac>
<windows>12</windows>
</number>
<desc>Engine 0/1 throttle mode</desc>
<binding>
<command>nasal</command>
@ -622,7 +728,13 @@
</binding>
</mod-up>
</button>
<button n="13">
<button>
<name>Mode 2</name>
<number>
<unix>13</unix>
<mac>13</mac>
<windows>13</windows>
</number>
<name>Mode 2</name>
<desc>Engine 2/3 throttle mode</desc>
<binding>

View file

@ -1,35 +1,122 @@
<?xml version="1.0"?>
<!-- Saitek Pro Flight Quadrant
Copyright (C) 2008 Ronald Jensen (wino(at)jentronics.com)
This file is released under the GPL license.
Copyright (C) 2008 Ronald Jensen (wino(at)jentronics.com)
Copyright (C) 2009 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
This file is released under the GPL license version 2.
-->
<PropertyList>
<name>Saitek Saitek Pro Flight Quadrant</name>
<name>Saitek Pro Flight Quadrant</name>
<name>Saitek Pro Flight Throttle Quadrant</name>
<axis n="0">
<desc>Throttle</desc>
<nasal>
<script>
<![CDATA[
var self = cmdarg().getParent();
var data = self.getNode("data");
var engine_select_mode = 0;
# TM0: All selected; TM1: #1-#3; TM2: #3-#6
var engine_axis_mode = 0;
# Valid only in TM1 and TM2.
# EA0: throttle
# EA1: mixure
# EA2: propeller
var pressed = [0,0,0,0,0,0];
var engine = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
# Do per-aircraft modifications
if (contains({"Aircraft/Short_Empire/Models/Short_Empire-model.xml" : 0,
"Aircraft/Lockheed1049/Models/Lockheed1049_twa.xml" : 0},
getprop("/sim/model/path"))) {
# Map port outer to axis 0, starboard outer to axis 2 and
# the inner engines to axis 1.
engine = [0, [1, 2], 3];
}
if (contains({"Aircraft/DO-X/Models/dox.xml" : 0},
getprop("/sim/model/path"))) {
engine = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]];
}
if (contains({"Aircraft/Nordstern/Models/Nordstern.xml" : 0},
getprop("/sim/model/path"))) {
engine = [0, 1, [2, 3]];
}
var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1);
var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1);
var axis_handler = func(axis) {
if (engine_select_mode == 0) {
if (axis == 0) {
controls.throttleAxis();
} elsif (axis == 1) {
controls.propellerAxis();
} elsif (axis == 2) {
controls.mixtureAxis();
}
} else {
controls.perEngineSelectedAxisHandler(engine_axis_mode)
(engine[axis + 3*(engine_select_mode - 1)]);
}
}
var trace = func(str) {
# Uncomment the line below to trace button presses.
#print("Pro-Flight-Quadrant.xml: " ~ str);
}
]]>
</script>
</nasal>
<!-- Levers left to right. -->
<axis>
<name>Left lever</name>
<number>
<unix>0</unix>
<mac>0</mac>
<windows>0</windows>
</number>
<desc>TM0: throttle, TM1: throttle/propeller 1, TM2: throttle/propeller 4</desc>
<binding>
<command>nasal</command>
<script>controls.throttleAxis()</script>
<script>axis_handler(0)</script>
</binding>
</axis>
<axis n="1">
<desc>Prop Pitch</desc>
<axis>
<name>Middle lever</name>
<number>
<unix>1</unix>
<mac>1</mac>
<windows>1</windows>
</number>
<desc>TM0: propeller, TM1: throttle/propeller 2, TM2: throttle/propeller 5</desc>
<binding>
<command>nasal</command>
<script>controls.propellerAxis()</script>
<script>axis_handler(1)</script>
</binding>
</axis>
<axis n="2">
<desc>Mixture </desc>
<axis>
<name>Right lever</name>
<number>
<unix>2</unix>
<mac>2</mac>
<windows>2</windows>
</number>
<desc>TM0: mixture, TM1: throttle/propeller 3, TM2: throttle/propeller 6</desc>
<binding>
<command>nasal</command>
<script>controls.mixtureAxis()</script>
<script>axis_handler(2)</script>
</binding>
</axis>
<button n="0">
<!-- 2-way rocker switches. Left to right. -->
<button>
<name>Left button up</name>
<number>
<unix>0</unix>
<mac>0</mac>
<windows>0</windows>
</number>
<desc>Flaps up</desc>
<repeatable>false</repeatable>
<binding>
@ -42,14 +129,40 @@
<script>controls.flapsDown(0)</script>
</binding>
</mod-up>
<mod-shift>
<binding>
<command>nasal</command>
<script>
trace("Button 0 + shift pressed!");
gui.popupTip("Saitek Quadrant: Throttle Mode 1");
engine_select_mode = 1;
</script>
</binding>
</mod-shift>
</button>
<button n="1">
<name>Left button down</name>
<number>
<unix>1</unix>
<mac>1</mac>
<windows>1</windows>
</number>
<desc>Flaps down</desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>controls.flapsDown(1)</script>
</binding>
<mod-shift>
<binding>
<command>nasal</command>
<script>
trace("Button 1 + shift pressed!");
gui.popupTip("Saitek Quadrant: Throttle Mode 0");
engine_select_mode = 0;
</script>
</binding>
</mod-shift>
<mod-up>
<binding>
<command>nasal</command>
@ -57,23 +170,64 @@
</binding>
</mod-up>
</button>
<button n="2">
<button>
<name>Middle button up</name>
<number>
<unix>2</unix>
<mac>2</mac>
<windows>2</windows>
</number>
<desc>Elevator trim up</desc>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(-0.75)</script>
</binding>
<mod-shift>
<binding>
<command>nasal</command>
<script>
trace("Button 2 + shift pressed!");
if (engine_select_mode) gui.popupTip("Saitek Quadrant: Throttle control");
engine_axis_mode = 0;
</script>
</binding>
</mod-shift>
</button>
<button n="3">
<button>
<name>Middle button down</name>
<number>
<unix>3</unix>
<mac>3</mac>
<windows>3</windows>
</number>
<desc>Elevator trim down</desc>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(0.75)</script>
</binding>
<mod-shift>
<binding>
<command>nasal</command>
<script>
trace("Button 3 + shift pressed!");
if (engine_select_mode)
gui.popupTip("Saitek Quadrant: Propeller control");
engine_axis_mode = 2;
</script>
</binding>
</mod-shift>
</button>
<button n="4">
<button>
<name>Right button up</name>
<number>
<unix>4</unix>
<mac>4</mac>
<windows>4</windows>
</number>
<desc>Gear up</desc>
<repeatable>false</repeatable>
<binding>
@ -81,7 +235,13 @@
<script>controls.gearDown(-1)</script>
</binding>
</button>
<button n="5">
<button>
<name>Right button down</name>
<number>
<unix>5</unix>
<mac>5</mac>
<windows>5</windows>
</number>
<desc>Gear down</desc>
<repeatable>false</repeatable>
<binding>
@ -89,4 +249,49 @@
<script>controls.gearDown(1)</script>
</binding>
</button>
<!-- Axis reverse area switches. -->
<button>
<name>Left lever reverse</name>
<number>
<unix>6</unix>
<mac>6</mac>
<windows>6</windows>
</number>
<desc></desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script></script>
</binding>
</button>
<button>
<name>Middle lever reverse</name>
<number>
<unix>7</unix>
<mac>7</mac>
<windows>7</windows>
</number>
<desc></desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script></script>
</binding>
</button>
<button>
<name>Right lever reverse</name>
<number>
<unix>8</unix>
<mac>8</mac>
<windows>8</windows>
</number>
<desc></desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script></script>
</binding>
</button>
</PropertyList>

View file

@ -74,6 +74,51 @@ var mixtureAxis = axisHandler("/controls/engines/engine[", "]/mixture");
var propellerAxis = axisHandler("/controls/engines/engine[", "]/propeller-pitch");
var carbHeatAxis = axisHandler("/controls/anti-ice/engine[", "]/carb-heat");
# Joystick axis handler for controlling subsets of similar properties.
# Shouldn't be called from other contexts.
# The argument engine can be either an index number or a list of
# index numbers.
# Use only when perEngineSelectedAxisHandler() below will not do.
var perIndexAxisHandler = func(pre, post) {
return
func(index, invert = 0) {
var val = cmdarg().getNode("setting").getValue();
if(invert) val = -val;
if (typeof(index) == "scalar") {
setprop(pre ~ index ~ post, (1 - val) / 2);
} else {
foreach (var e; index) {
setprop(pre ~ e ~ post, (1 - val) / 2);
}
}
};
}
# Joystick axis handler for controlling a selected axis on specific engines.
# Shouldn't be called from other contexts.
# The argument mode can be
# 0 - throttle
# 1 - mixture
# 2 - propeller-pitch
# The argument engine to the returned function can be either an
# engine number or a list of engine numbers.
# Usage example (controlling the mixture of engines 1 and 2):
# <script>
# controls.perEngineSelectedAxisHandler(1)([1,2]);
# </script>
var _axisMode = {
0: perIndexAxisHandler("/controls/engines/engine[",
"]/throttle"),
1: perIndexAxisHandler("/controls/engines/engine[",
"]/mixture"),
2: perIndexAxisHandler("/controls/engines/engine[",
"]/propeller-pitch")
};
var perEngineSelectedAxisHandler = func(mode) {
return _axisMode[mode];
}
##
# Wrapper around stepProps() which emulates the "old" flap behavior for
# configurations that aren't using the new mechanism.

View file

@ -71,4 +71,54 @@
<stretch>true</stretch>
</empty>
</group>
</PropertyList>
<group>
<layout>hbox</layout>
<default-padding>6</default-padding>
<empty>
<stretch>true</stretch>
</empty>
<button>
<legend>OK</legend>
<default>true</default>
<equal>true</equal>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>dialog-close</command>
</binding>
</button>
<button>
<legend>Apply</legend>
<equal>true</equal>
<binding>
<command>dialog-apply</command>
</binding>
</button>
<button>
<legend>Reset</legend>
<equal>true</equal>
<binding>
<command>dialog-update</command>
</binding>
</button>
<button>
<legend>Cancel</legend>
<equal>true</equal>
<key>Esc</key>
<binding>
<command>dialog-close</command>
</binding>
</button>
<empty>
<stretch>true</stretch>
</empty>
</group>
</PropertyList>

View file

@ -261,7 +261,7 @@
<command>nasal</command>
<script>
setprop("/sim/presets/parkpos", "");
if (!mode.airport.getBoolValue()) {
setprop("/sim/presets/airport-id", "");
setprop("/sim/presets/runway", "");

View file

@ -457,9 +457,9 @@
</menu>
<menu>
<label>ATC/AI</label>
<label>AI</label>
<item>
<label>ATC Options</label>
<label>AI Options</label>
<binding>
<command>dialog-show</command>
<dialog-name>ai</dialog-name>

View file

@ -1320,6 +1320,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -1332,7 +1335,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>1000000.0</wood-coverage>
<wood-size>20000.0</wood-size>
<tree-density>4000.0</tree-density>
@ -1383,6 +1386,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -1395,7 +1401,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>500000.0</wood-coverage>
<tree-texture>Textures/Trees/mixed-summer.png</tree-texture>
<tree-varieties>8</tree-varieties>
@ -1444,6 +1450,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -1456,7 +1465,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>500000.0</wood-coverage>
<wood-size>20000.0</wood-size>
<tree-density>5000.0</tree-density>
@ -2140,6 +2149,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -2152,7 +2164,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>1000000.0</wood-coverage>
<wood-size>20000.0</wood-size>
<tree-density>4000.0</tree-density>
@ -2202,6 +2214,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -2214,7 +2229,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>150000.0</wood-coverage>
<wood-size>10000.0</wood-size>
<tree-density>5000.0</tree-density>
@ -2264,6 +2279,9 @@ Shared parameters for various materials.
<heading-type>random</heading-type>
</object>
</object-group>
<!-- Disabled to avoid a tremendous osg performance penalty when
deleting scenery tiles, caused by tens of thousands of shared
horse/cow objects. Need a better implementation!
<object-group>
<range-m>1000</range-m>
<object>
@ -2276,7 +2294,7 @@ Shared parameters for various materials.
<coverage-m2>300000</coverage-m2>
<heading-type>random</heading-type>
</object>
</object-group>
</object-group> -->
<wood-coverage>150000.0</wood-coverage>
<wood-size>10000.0</wood-size>
<tree-density>5000.0</tree-density>

View file

@ -54,7 +54,7 @@ Started September 2000 by David Megginson, david@megginson.com
<terminal-ansi-colors type="bool">true</terminal-ansi-colors>
<season type="string">summer</season>
</startup>
<rendering> <multithreading-mode>AutomaticSelection</multithreading-mode>
<rendering>
<debug type="bool">false</debug>
<realism>5</realism>
<filtering>8</filtering>
@ -281,12 +281,11 @@ Started September 2000 by David Megginson, david@megginson.com
<systems>
<path>Aircraft/Generic/generic-systems.xml</path>
<autopilot>
<name>generic autopilot</name>
<path>Aircraft/Generic/generic-autopilot.xml</path>
</autopilot>
<!--
replace the hard coded helpers, which are gone now
-->
<autopilot>
<name>autopilot helpers</name>
<path>Aircraft/Generic/generic-autopilot-helper.xml</path>
</autopilot>
<property-rule>
@ -593,7 +592,7 @@ Started September 2000 by David Megginson, david@megginson.com
</airport>
<atc>
<enabled type="bool">false</enabled>
<enabled type="bool">true</enabled>
</atc>
<ai-traffic>
@ -602,7 +601,7 @@ Started September 2000 by David Megginson, david@megginson.com
</ai-traffic>
<traffic-manager>
<enabled type="bool">false</enabled>
<enabled type="bool">true</enabled>
<heuristics type="bool">true</heuristics>
<datafile type="string"></datafile>
<instantaneous-action type="bool">false</instantaneous-action>
@ -612,13 +611,12 @@ Started September 2000 by David Megginson, david@megginson.com
<ai>
<enabled type="bool">true</enabled>
<!-- <scenario>nimitz_demo</scenario> -->
<scenario>nimitz_demo</scenario>
<!-- <scenario>balloon_demo</scenario> -->
<!-- <scenario>aircraft_demo</scenario> -->
<!-- <scenario>refueling_demo</scenario> -->
<!-- <scenario>lead_aircraft</scenario> -->
<!-- <scenario>vinson_demo</scenario> -->
<!-- <scenario>mp-carriers</scenario> -->
</ai>
<multiplay>