diff --git a/Input/Event/GoFlight/EFIS.xml b/Input/Event/GoFlight/EFIS.xml
index 46c6ddef2..da075e72d 100644
--- a/Input/Event/GoFlight/EFIS.xml
+++ b/Input/Event/GoFlight/EFIS.xml
@@ -1,23 +1,70 @@
GoFlight GF EFIS
- true
+ false
+
+
+ input
+ 1
+ 16
+
+ 8
+ 2
+ true
+
+
+ 24
+
+
+
+
- rel-dial-4
+ rel-dial-0
property-adjust
/input/goflight/efis/height
0.0
+ true
00
11
22
@@ -26,146 +73,17 @@
-
- rel-dial-5
-
- property-adjust
- /input/goflight/efis/baro
- 108.0
- 117.95
- true
-
-
- 00
- 11
- 22
- 34
- 48
-
-
-
-
-
-
-
- STA Button
- button-1
+ rel-dial-1
- property-toggle
- /instrumentation/efis/inputs/sta
-
-
-
-
- WXR Button
- button-2
-
- property-toggle
- /instrumentation/efis/inputs/wxr
+ property-adjust
+ /instrumentation/efis[0]/inputs/baro-knob
TERR Button
- button-3
-
- nasal
-
-
-
-
-
- ARPT Button
- button-4
-
- property-toggle
- /instrumentation/efis/inputs/arpt
-
-
-
-
- ARPT Button
- button-5
-
- nasal
-
-
-
-
-
- ARPT Button
- button-6
-
- nasal
-
-
-
-
-
- ARPT Button
- button-7
-
- nasal
-
-
-
-
-
- ARPT Button
- button-8
-
- nasal
-
-
-
-
-
- TERR Button
- button-9
+ button-0
property-toggle
/instrumentation/efis/inputs/terr
@@ -174,7 +92,7 @@
POS Button
- button-10
+ button-1
property-toggle
/instrumentation/efis/inputs/pos
@@ -183,7 +101,7 @@
DATA Button
- button-11
+ button-2
property-toggle
/instrumentation/efis/inputs/data
@@ -192,7 +110,7 @@
ARPT Button
- button-12
+ button-3
property-toggle
/instrumentation/efis/inputs/arpt
@@ -201,7 +119,7 @@
WPT Button
- button-13
+ button-4
property-toggle
/instrumentation/efis/inputs/wpt
@@ -210,7 +128,7 @@
STA Button
- button-14
+ button-5
property-toggle
/instrumentation/efis/inputs/sta
@@ -219,7 +137,7 @@
WXR Button
- button-15
+ button-6
property-toggle
/instrumentation/efis/inputs/wxr
@@ -227,44 +145,56 @@
- ARPT Button
- button-16
+
+ button-7
nasal
-
+
- ARPT Button
- button-17
+
+ button-8
nasal
-
+
+
+
+ nasal
+
+
+
- ARPT Button
- button-18
+
+ button-9
nasal
-
+
+
+
+ nasal
+
+
+
- ARPT Button
- button-19
+
+ button-10
nasal
-
+
in/HPA toggle
- button-20
+ button-11
property-toggle
/instrumentation/efis/inputs/kpa-mode
@@ -272,48 +202,71 @@
- ARPT Button
- button-21
+ DH/MCA knob push
+ button-12
nasal
-
+
+
+
+
+ property-toggle
+ /instrumentation/efis/inputs/minimums-mode
- ARPT Button
- button-22
+
+ button-13
nasal
-
+
+
+
+ nasal
+
+
+
- ARPT Button
- button-23
+
+ button-14
nasal
-
+
+
+
+ nasal
+
+
+
- ARPT Button
- button-24
+
+ button-15
nasal
-
+
+
+
+ nasal
+
+
+
ADF-L switch
- button-25
+ button-16
property-assign
/instrumentation/efis/inputs/lh-vor-adf
- 2
+ -1
@@ -327,7 +280,7 @@
VOR-L switch
- button-26
+ button-17
property-assign
/instrumentation/efis/inputs/lh-vor-adf
@@ -344,11 +297,11 @@
ADF-R switch
- button-27
+ button-18
property-assign
/instrumentation/efis/inputs/rh-vor-adf
- 2
+ -1
@@ -361,7 +314,7 @@
VOR-R switch
- button-28
+ button-19
property-assign
/instrumentation/efis/inputs/rh-vor-adf
@@ -378,7 +331,7 @@
MTRS Button
- button-29
+ button-20
nasal
@@ -391,8 +344,8 @@
- MTRS Button
- button-30
+ FPV Button
+ button-21
nasal
@@ -404,17 +357,4 @@
-
- DH/MCA knob push
- button-21
-
- nasal
-
-
-
-
- property-toggle
- /instrumentation/efis/inputs/minimums-mode
-
-
diff --git a/Input/Event/GoFlight/MCP-pro.xml b/Input/Event/GoFlight/MCP-pro.xml
index 2fd1ed208..d51c4e3bf 100644
--- a/Input/Event/GoFlight/MCP-pro.xml
+++ b/Input/Event/GoFlight/MCP-pro.xml
@@ -1,257 +1,303 @@
GoFlight MCP Pro
- true
+ MCP Pro
+ false
0) {
- r ~= padChar;
- padCount -=1;
- }
-
- for (var i=0; i < size(s); i += 1) {
- if (s[i] == `.`) {
- # set the high bit to correspond to the decimal
- var lastIndex = size(r) - 1;
- r[lastIndex] = r[lastIndex] + 0x80;
- } elsif (s[i] == `-`) {
- r ~= chr(0x40);
- } else {
- var digitCode = s[i] - `0`;
- r ~= chr(translateDigitToSevenSegment[digitCode]);
- }
- }
-
- return r;
- }
-
- var altitudeAlphanumeric = func() {
- var alt = getprop("/autopilot/settings/target-altitude-ft");
- var altStr = sprintf("%d", alt);
- return encodeString(altStr, 5);
- }
-
- var headingAlphanumeric = func() {
- var hdg = getprop("/autopilot/settings/heading-bug-deg");
- return encodeString(sprintf("%d", hdg), 3);
- }
-
- var courseAlphanumeric = func() {
- var crs = getprop("/instrumentation/nav[0]/radials/selected-deg");
- return encodeString(sprintf("%d", crs), 3);
- }
-
- var course2Alphanumeric = func() {
- var crs = getprop("/instrumentation/nav[1]/radials/selected-deg");
- return encodeString(sprintf("%d", crs), 3);
- }
-
- var speedAlphanumeric = func() {
- var spd = getprop("/autopilot/settings/target-speed-kt");
- return encodeString(sprintf("%d", spd), 5);
- }
-
- var vspeedAlphanumeric = func() {
- var vs = getprop("/autopilot/settings/vertical-speed-fpm");
- return encodeString(sprintf("%d", vs), 5);
- }
-
- var ledState = func()
- {
- if (activeChannel == 1) return chr(0x04);
- return chr(0x2);
- }
]]>
- rel-dial
-
- true
- 00
- 11
- 25
- 310
- 420
-
+ display-brightness
+
+ /input/goflight/mcp/brightness
+
+
+
+
+
+ rel-dial-0
property-adjust
- /autopilot/settings/target-altitude-ft
- 100
+ /autopilot/settings/heading-bug-deg
+ true
0
+ 359
+
+
+ true
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 5
+
+
+ 3
+ 10
+
+
+ 4
+ 30
+
+
+
+
+
+ rel-dial-1
+
+ property-adjust
+ /instrumentation/nav[0]/radials/selected-deg
+ true
+ 0
+ 359
+
+
+ true
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 5
+
+
+ 3
+ 10
+
+
+ 4
+ 30
+
+
+
+
+
+ rel-dial-2
+
+ property-adjust
+ /autopilot/settings/vertical-speed-fpm
+ -50
+ -8000
+ 12000
+
+
+ true
+
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 2
+
+
+ 3
+ 4
+
+
+ 4
+ 10
+
+
+
+
+
+ rel-dial-3
+
+ nasal
+
+
+
+ true
+
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 5
+
+
+ 3
+ 10
+
+
+ 4
+ 20
+
+
+
+
+
+
+ rel-dial-4
+
+ property-adjust
+ /instrumentation/nav[1]/radials/selected-deg
+ true
+ 0
+ 359
+
+
+ true
+
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 5
+
+
+ 3
+ 10
+
+
+ 4
+ 30
+
+
+
+
+
+ rel-dial-5
+
+ true
+
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+ 2
+ 10
+
+
+ 3
+ 50
+
+
+ 4
+ 100
+
+
+
+ nasal
+
-
- rel-dial-1
-
- property-adjust
- /autopilot/settings/heading-bug-deg
- true
- 0
- 359
-
-
- true
- 00
- 11
- 25
- 310
- 420
-
-
+
+ 9
+ /input/goflight/mcp/refresh
+ altitudeAlphanumeric
+
-
- rel-dial-2
-
- property-adjust
- /instrumentation/nav[0]/radials/selected-deg
- true
- 0
- 359
-
-
- true
- 00
- 11
- 25
- 310
- 420
-
-
-
- rel-dial-3
-
- property-adjust
- /autopilot/settings/vertical-speed-fpm
- 10
-
-
- true
- 00
- 11
- 25
- 310
- 420
-
-
+
+ 7
+ /input/goflight/mcp/refresh-headings
+ headingAlphanumeric
+
-
- rel-dial-4
-
- property-adjust
- /autopilot/settings/target-speed-kt
- 0
-
-
- true
- 00
- 11
- 25
- 310
- 420
-
-
+
+ 3
+ /input/goflight/mcp/refresh-headings
+ courseAlphanumeric
+
-
- rel-dial-5
-
- property-adjust
- /instrumentation/nav[1]/radials/selected-deg
- true
- 0
- 359
-
-
- true
- 00
- 11
- 25
- 310
- 420
-
-
+
+ 11
+ /input/goflight/mcp/refresh
+ vspeedAlphanumeric
+
+
+ 5
+ /input/goflight/mcp/refresh
+ speedAlphanumeric
+
-
- 9
- /autopilot/settings/target-altitude-ft
- altitudeAlphanumeric
-
+
+ 13
+ /input/goflight/mcp/refresh-headings
+ course2Alphanumeric
+
-
- 7
- /autopilot/settings/heading-bug-deg
- headingAlphanumeric
-
-
-
- 3
- /instrumentation/nav[0]/radials/selected-deg
- courseAlphanumeric
-
-
-
- 11
- /autopilot/settings/vertical-speed-fpm
- vspeedAlphanumeric
-
-
-
- 5
- /autopilot/settings/target-speed-kt
- speedAlphanumeric
-
-
-
- 13
- /instrumentation/nav[1]/radials/selected-deg
- course2Alphanumeric
-
-
-
+
- led-misc
+ led-misc-0
- 1
-
- /gear/gear[0]/indicator-servicable
-
- /gear/gear[0]/position-norm
- 0.9
-
-
-
-
- 0
-
-
-
- /gear/gear[0]/indicator-servicable
-
- /gear/gear[0]/position-norm
- 0.9
-
-
-
-
+ /input/goflight/mcp/led[0]
+
+ led-misc-1
+
+ /input/goflight/mcp/led[1]
+
+
+
+
+ led-misc-2
+
+ /input/goflight/mcp/led[2]
+
+
+
+
+ led-misc-3
+
+ /input/goflight/mcp/led[3]
+
+
button-1
@@ -266,7 +312,7 @@
nasal
-
+ enable
@@ -321,8 +367,8 @@
Speed
button-9
- nasal
-
+ goflight-mcp-button
+
@@ -330,8 +376,8 @@
button-10
Level Change
- nasal
-
+ goflight-mcp-button
+
@@ -339,8 +385,8 @@
button-11
Heading
- nasal
-
+ goflight-mcp-button
+
@@ -348,8 +394,8 @@
button-12
Approach
- nasal
-
+ goflight-mcp-button
+
@@ -357,8 +403,8 @@
button-13
Altitude
- nasal
-
+ goflight-mcp-button
+
@@ -366,8 +412,8 @@
button-14
Vertical Speed
- nasal
-
+ goflight-mcp-button
+
@@ -375,9 +421,17 @@
button-15
Disengage Bar
- nasal
-
+ property-assign
+ /input/goflight/mcp/ap-disengage
+ 1
+
+
+ property-assign
+ /input/goflight/mcp/ap-disengage
+ 0
+
+
@@ -385,17 +439,25 @@
button-16
F/O FD Enable
- nasal
-
+ property-assign
+ /input/goflight/mcp/fo-fd-enabled
+ 1
+
+
+ property-assign
+ /input/goflight/mcp/fo-fd-enabled
+ 0
+
+
button-17
Altitude Intervention
- nasal
-
+ goflight-mcp-button
+
@@ -403,8 +465,8 @@
button-18
CWS-A
- nasal
-
+ goflight-mcp-button
+
@@ -412,8 +474,8 @@
button-19
CWS-B
- nasal
-
+ goflight-mcp-button
+
@@ -421,8 +483,8 @@
button-20
IAS knob push
- nasal
-
+ goflight-mcp-button
+
@@ -430,8 +492,8 @@
button-21
HDG knob push
- nasal
-
+ goflight-mcp-button
+
@@ -439,8 +501,8 @@
button-22
Altitude Knob Push
- nasal
-
+ goflight-mcp-button
+
@@ -448,17 +510,25 @@
button-23
Captain's FD Enable
- nasal
-
+ property-assign
+ /input/goflight/mcp/captain-fd-enabled
+ 1
+
+
+ property-assign
+ /input/goflight/mcp/captain-fd-enabled
+ 0
+
+
button-24
N1 select
- nasal
-
+ goflight-mcp-button
+
@@ -466,8 +536,8 @@
button-25
VNAV
- nasal
-
+ goflight-mcp-button
+
@@ -475,8 +545,8 @@
button-26
LNAV
- nasal
-
+ goflight-mcp-button
+
@@ -484,8 +554,8 @@
button-27
CMD A
- nasal
-
+ goflight-mcp-button
+
@@ -493,8 +563,8 @@
button-28
CMD B
- nasal
-
+ goflight-mcp-button
+
@@ -502,17 +572,25 @@
button-29
AT arm
- nasal
-
+ property-assign
+ /input/goflight/mcp/autothrottle-armed
+ 1
+
+
+ property-assign
+ /input/goflight/mcp/autothrottle-armed
+ 0
+
+
button-30
Soeed crossover
- nasal
-
+ goflight-mcp-button
+
@@ -520,8 +598,8 @@
button-31
Speed intervention
- nasal
-
+ goflight-mcp-button
+
@@ -529,8 +607,8 @@
button-32
VOR / Localizer
- nasal
-
+ goflight-mcp-button
+
diff --git a/Nasal/goflight.nas b/Nasal/goflight.nas
new file mode 100644
index 000000000..539e36026
--- /dev/null
+++ b/Nasal/goflight.nas
@@ -0,0 +1,314 @@
+# helpers for working with GoFlight input devices
+
+# map decimal digits 0..9 to standard 7-segment LCD pattern
+var translateDigitToSevenSegment = [0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67];
+
+var formatFrequencyMHz = func(freqMhz, fieldWidth)
+{
+ return bytesForString(sprintf("%.3f", freqMhz), fieldWidth);
+}
+
+var formatFrequencyKHz = func(freqKhz, fieldWidth)
+{
+ return bytesForString(sprintf("%6.2f", freqKhz), fieldWidth);
+}
+
+var bytesForString = func(s, fieldWidth)
+{
+ var padCount = fieldWidth - size(s);
+ var r = "";
+
+ while (padCount > 0) {
+ r ~= chr(0);
+ padCount -=1;
+ }
+
+ for (var i=0; i < size(s); i += 1) {
+ if (s[i] == `.`) {
+ # set the high bit to correspond to the decimal
+ var lastIndex = size(r) - 1;
+ r[lastIndex] = r[lastIndex] + 0x80;
+ } else if (s[i] == ` `) { # spaces
+ r ~= chr(0);
+ } else if (s[i] == `-`) { # negative
+ r ~= chr(0x40);
+ } else {
+ var digitCode = s[i] - `0`;
+ r ~= chr(translateDigitToSevenSegment[digitCode]);
+ }
+ }
+
+ return r;
+}
+
+# TEST
+# STBY
+# OFF
+# XPDR
+# TA
+# TA/RA
+
+
+var translateTo14Segment = {
+ 32: [0x0, 0x0], # space
+ 65: [0x22, 0x37], # A
+ 66: [0x0A, 0x8f],
+ 67: [0x00, 0x39],
+ 68: [0x08, 0x8f], # uppercase D
+ 69: [0x22, 0x39],
+ 70: [0x20, 0x31], # F
+ 77: [0x00, 0x00], # upper M
+ 78: [0x00, 0x00], # upper N
+ 79: [0x00, 0x3f], # upper O
+ 80: [0x22, 0x33], # upper P
+ 82: [0x26, 0x33], # upper R
+ 83: [0x22, 0x2d], # upper S
+ 84: [0x08, 0x81], # T
+ 88: [0x15, 0x40], # X
+ 89: [0x09, 0x40] # Y
+};
+
+var formatFourteenSegment = func(s, fieldWidth)
+{
+ var r = [];
+ for (var i=0; i < size(s); i += 1) {
+ var ch = s[i];
+ if (!contains(translateTo14Segment, ch)) {
+ debug.dump('No 14 segment mapping for:', ch);
+ } else {
+ var t = translateTo14Segment[s[i]];
+ append(r, t[0]);
+ append(r, t[1]);
+ }
+ }
+ return r;
+}
+
+var reverseBytes = func(bytes)
+{
+ var r=[];
+ for (var i = size(bytes) - 1; i >=0; i -=1) {
+ append(r, bytes[i]);
+ }
+ return r;
+}
+
+var MFRController = {
+
+ new: func(prefix)
+ {
+ var m = {
+ parents: [MFRController]
+ };
+
+ # m._hideTimer = maketimer(m.DELAY, m, Tooltip._hideTimeout);
+ # m._hideTimer.singleShot = 1;
+
+ return m;
+ }
+};
+
+var mcp = {
+ init: func()
+ {
+ me._speedKnotsProp = props.globals.getNode("/autopilot/settings/target-speed-kt", 1);
+ me._speedMachProp = props.globals.getNode("/autopilot/settings/target-speed-mach", 1);
+ me._altitudeFtProp = props.globals.getNode("/autopilot/settings/target-altitude-ft", 1);
+ me._vsFPMProp = props.globals.getNode("/autopilot/settings/vertical-speed-fpm", 1);
+ me._headingProp = props.globals.getNode("/autopilot/settings/heading-bug-deg", 1);
+ me._course1Prop = props.globals.getNode("/instrumentation/nav[0]/radials/selected-deg", 1);
+ me._course2Prop = props.globals.getNode("/instrumentation/nav[1]/radials/selected-deg", 1);
+
+ me._useMach = 0;
+ me._refreshProp = props.globals.getNode("/input/goflight/mcp/refresh", 1);
+ me._refreshHeadingProp = props.globals.getNode("/input/goflight/mcp/refresh-headings", 1);
+
+ me._blankVSWindow = props.globals.getNode("/input/goflight/mcp/blank-vs-window", 1);
+
+ me._ledProps = [];
+ for (var l=0; l<4; l+=1) {
+ var node = props.globals.getNode("/input/goflight/mcp/led[" ~ l ~ "]", 1);
+ node.setIntValue(0);
+ append(me._ledProps, node);
+ }
+
+ setlistener(me._speedKnotsProp, func { me.doRefresh(); } );
+ setlistener(me._speedMachProp, func { me.doRefresh(); });
+ setlistener(me._altitudeFtProp, func { me.doRefresh(); });
+ setlistener(me._vsFPMProp, func { me.doRefresh(); });
+ setlistener(me._blankVSWindow, func { me.doRefresh(); });
+
+ setlistener(me._headingProp, func { me.doRefreshHeading(); });
+ setlistener(me._course1Prop, func { me.doRefreshHeading(); });
+ setlistener(me._course2Prop, func { me.doRefreshHeading(); });
+
+ me.doRefresh();
+ me.doRefreshHeading();
+
+ print("GoFlight MCP init done");
+ },
+
+ setAltitudeFtProp: func(path)
+ {
+ me._altitudeFtProp = props.globals.getNode(path, 1);
+ setlistener(me._altitudeFtProp, func { me.doRefresh(); });
+ me.doRefresh();
+ },
+
+ doRefresh: func()
+ {
+ me._refreshProp.setIntValue(0);
+ },
+
+ doRefreshHeading: func()
+ {
+ me._refreshHeadingProp.setIntValue(0);
+ },
+
+ setMachMode: func(useMach)
+ {
+ me._useMach = useMach;
+ me.doRefresh();
+ },
+
+ altitudeData: func()
+ {
+ # if window is blanked, return empty data
+ var alt = me._altitudeFtProp.getValue();
+ return bytesForString(sprintf("%d", alt), 5);
+ },
+
+ vsData: func()
+ {
+ # if window is blanked, return empty data
+ if (me._blankVSWindow.getValue()) {
+ return bytesForString(" ", 5);
+ }
+
+ var vs = me._vsFPMProp.getValue();
+ return bytesForString(sprintf("%d", vs), 5);
+ },
+
+ speedData: func()
+ {
+ if (me._useMach) {
+ var mach = me._speedMachProp.getValue();
+ return bytesForString(sprintf("%0.3f ", mach), 5);
+ }
+
+ var spd = me._speedKnotsProp.getValue();
+ return bytesForString(sprintf("%d", spd), 5);
+ },
+
+ adjustSpeed: func(val)
+ {
+ if (me._useMach) {
+ var mach = me._speedMachProp.getValue();
+ me._speedMachProp.setDoubleValue(mach + (val * 0.01));
+ return;
+ }
+
+ var spd = me._speedKnotsProp.getValue();
+ me._speedKnotsProp.setIntValue(spd + val);
+ },
+
+ adjustAltitude: func(val)
+ {
+ var alt = me._altitudeFtProp.getValue();
+ me._altitudeFtProp.setIntValue(alt + val);
+ },
+
+ headingData: func()
+ {
+ var h = me._headingProp.getValue();
+ return bytesForString(sprintf("%0d", h), 3);
+ },
+
+ course1Data: func()
+ {
+ var h = me._course1Prop.getValue();
+ return bytesForString(sprintf("%0d", h), 3);
+ },
+
+ course2Data: func()
+ {
+ var h = me._course2Prop.getValue();
+ return bytesForString(sprintf("%0d", h), 3);
+ },
+
+ _ledNames: {
+ 'SPEED': [1, 0],
+ 'LVL-CHG': [1, 1],
+ 'HDG-SEL': [1, 2],
+ 'APP': [1,3],
+ 'ALT-HLD': [1,4],
+ 'V/S': [1,5],
+ 'F/O F/D': [1,7],
+ # bank 2
+ 'CWS A': [2,1],
+ 'CWS B': [2,2],
+ 'CAP F/D': [2,6],
+ 'N1': [2, 7],
+ # bank 3
+ 'VNAV': [3,0],
+ 'LNAV': [3,1],
+ 'CMD A': [3,2],
+ 'CMD B': [3,3],
+ 'A/T ARM': [3,4],
+ 'VOR-LOC': [3,7],
+ },
+
+ watchPropertyForLED: func(prop, ledName)
+ {
+ if (!contains(me._ledNames, ledName)) {
+ printlog('warn', 'Unknown GoFlight MCP LED:' ~ ledName);
+ return;
+ }
+
+ var ledData = me._ledNames[ledName];
+ setlistener(prop, func(n) { me.setLED(ledData, n.getValue()); });
+ },
+
+ setLED: func(data, b)
+ {
+ # data is a pair of ints; the LED node and the bit within
+ var node = me._ledProps[data[0]];
+ var ledBits = node.getValue();
+ node.setIntValue(bits.switch(ledBits, data[1], b));
+ }
+};
+
+var flapPositions = [];
+var flapsNode = nil;
+
+_setlistener("/sim/signals/nasal-dir-initialized", func {
+ mcp.init();
+
+ # build flap axis quantisation data
+ flapsNode = props.globals.getNode("/controls/flight/flaps");
+
+ foreach (var c; props.globals.getNode("/sim/flaps").getChildren("setting")) {
+ var step = c.getValue();
+ append(flapPositions, step);
+ }
+
+});
+
+var flapsAxisQuantized = func(val)
+{
+ var normVal = (val + 1) * 0.5;
+ var numSteps = size(flapPositions);
+ for (var i=1; i