diff --git a/A320-main.xml b/A320-main.xml index 356ab950..912044b7 100644 --- a/A320-main.xml +++ b/A320-main.xml @@ -1870,11 +1870,13 @@ Aircraft/A320-family/Nasal/FMGC/FCU.nas + Aircraft/A320-family/Nasal/FMGC/flightplan.nas Aircraft/A320-family/Nasal/FMGC/FMGC.nas Aircraft/A320-family/Nasal/FMGC/FMGC-b.nas Aircraft/A320-family/Nasal/FMGC/FMGC-c.nas + Aircraft/A320-family/Nasal/MCDU/LATREV.nas Aircraft/A320-family/Nasal/MCDU/MCDU.nas Aircraft/A320-family/Nasal/MCDU/INITA.nas Aircraft/A320-family/Nasal/MCDU/INITB.nas @@ -1885,6 +1887,7 @@ Aircraft/A320-family/Nasal/MCDU/RADNAV.nas Aircraft/A320-family/Nasal/MCDU/DATA.nas Aircraft/A320-family/Nasal/MCDU/STATUS.nas + Aircraft/A320-family/Nasal/MCDU/F-PLN.nas Aircraft/A320-family/Models/Instruments/PFD/PFD.nas diff --git a/Models/Instruments/MCDU/MCDU.nas b/Models/Instruments/MCDU/MCDU.nas index daa64326..fa283693 100644 --- a/Models/Instruments/MCDU/MCDU.nas +++ b/Models/Instruments/MCDU/MCDU.nas @@ -6,11 +6,25 @@ var MCDU_1 = nil; var MCDU_2 = nil; var MCDU1_display = nil; var MCDU2_display = nil; +var myLatRev = nil; var default = "BoeingCDU-Large.ttf"; var symbol = "helvetica_medium.txf"; var normal = 70; var small = 56; var page = ""; +var fplnLineSize = 0; +var fplnl1 = ""; +var fplnl1s = ""; +var fplnl2 = ""; +var fplnl2s = ""; +var fplnl3 = ""; +var fplnl3s = ""; +var fplnl4 = ""; +var fplnl4s = ""; +var fplnl5 = ""; +var fplnl5s = ""; +var fplnl6 = ""; +var fplnl6s = ""; setprop("/MCDUC/colors/wht/r", 1); setprop("/MCDUC/colors/wht/g", 1); setprop("/MCDUC/colors/wht/b", 1); @@ -27,9 +41,13 @@ setprop("/MCDUC/colors/yel/r", 0.9333); setprop("/MCDUC/colors/yel/g", 0.9333); setprop("/MCDUC/colors/yel/b", 0.0000); +var WHITE = [1.0000,1.0000,1.0000]; +var GREEN = [0.0509,0.7529,0.2941]; +var BLUE = [0.0901,0.6039,0.7176]; +var AMBER = [0.7333,0.3803,0.0000]; +var YELLOW = [0.9333,0.9333,0.0000]; + # Fetch nodes: -var ac1 = props.globals.getNode("/systems/electrical/bus/ac-1", 1); -var ac2 = props.globals.getNode("/systems/electrical/bus/ac-2", 1); var mcdu1_lgt = props.globals.getNode("/controls/lighting/DU/mcdu1", 1); var mcdu2_lgt = props.globals.getNode("/controls/lighting/DU/mcdu2", 1); var acType = props.globals.getNode("/MCDUC/type", 1); @@ -92,6 +110,7 @@ var engOutAcc = props.globals.getNode("/FMGC/internal/eng-out-reduc", 1); var engOutAccSet = props.globals.getNode("/MCDUC/reducacc-set", 1); var transAlt = props.globals.getNode("/FMGC/internal/trans-alt", 1); var managedSpeed = props.globals.getNode("/it-autoflight/input/spd-managed", 1); +var TMPYActive = [props.globals.getNode("/FMGC/internal/tmpy-active[0]"), props.globals.getNode("/FMGC/internal/tmpy-active[1]")]; # Fetch nodes into vectors var pageProp = [props.globals.getNode("/MCDU[0]/page", 1), props.globals.getNode("/MCDU[1]/page", 1)]; @@ -150,16 +169,16 @@ var canvas_MCDU_base = { "Simple_L1_Arrow","Simple_L2_Arrow","Simple_L3_Arrow","Simple_L4_Arrow","Simple_L5_Arrow","Simple_L6_Arrow","Simple_R1","Simple_R2","Simple_R3","Simple_R4","Simple_R5","Simple_R6","Simple_R1S","Simple_R2S","Simple_R3S","Simple_R4S","Simple_R5S", "Simple_R6S","Simple_R1_Arrow","Simple_R2_Arrow","Simple_R3_Arrow","Simple_R4_Arrow","Simple_R5_Arrow","Simple_R6_Arrow","Simple_C1","Simple_C2","Simple_C3","Simple_C4","Simple_C5","Simple_C6","Simple_C1S","Simple_C2S","Simple_C3S","Simple_C4S", "Simple_C5S","Simple_C6S","INITA","INITA_CoRoute","INITA_FltNbr","INITA_CostIndex","INITA_CruiseFLTemp","INITA_FromTo","INITA_InitRequest","INITA_AlignIRS","INITB","INITB_ZFWCG","INITB_ZFW","INITB_ZFW_S","INITB_Block","PERFTO","PERFTO_V1","PERFTO_VR", - "PERFTO_V2","PERFTO_FE","PERFTO_SE","PERFTO_OE"]; + "PERFTO_V2","PERFTO_FE","PERFTO_SE","PERFTO_OE","FPLN","FPLN_From","FPLN_TMPY_group","FPLN_Callsign","FPLN_L1","FPLN_L2","FPLN_L3","FPLN_L4","FPLN_L5","FPLN_L6","FPLN_L1S","FPLN_L2S","FPLN_L3S","FPLN_L4S","FPLN_L5S","FPLN_L6S","FPLN_6_group"]; }, update: func() { - if (ac1.getValue() >= 110 and mcdu1_lgt.getValue() > 0.01) { + if (systems.ELEC.Bus.ac1.getValue() >= 110 and mcdu1_lgt.getValue() > 0.01) { MCDU_1.update(); MCDU_1.page.show(); } else { MCDU_1.page.hide(); } - if (ac2.getValue() >= 110 and mcdu2_lgt.getValue() > 0.01) { + if (systems.ELEC.Bus.ac2.getValue() >= 110 and mcdu2_lgt.getValue() > 0.01) { MCDU_2.update(); MCDU_2.page.show(); } else { @@ -168,10 +187,174 @@ var canvas_MCDU_base = { }, updateCommon: func(i) { page = pageProp[i].getValue(); - if (page == "MCDU") { + if (page == "F-PLNA" or page == "F-PLNB") { + if (!pageSwitch[i].getBoolValue()) { + me["Simple"].hide(); + me["Simple_Center"].hide(); + me["FPLN"].show(); + me["INITA"].hide(); + me["INITB"].hide(); + me["PERFTO"].hide(); + me["Simple_PageNum"].hide(); + me["ArrowLeft"].show(); + me["ArrowRight"].show(); + + pageSwitch[i].setBoolValue(1); + } + + if (flightNumSet.getValue()) { + me["FPLN_Callsign"].setText(flightNum.getValue()); + me["FPLN_Callsign"].show(); + } else { + me["FPLN_Callsign"].hide(); + } + + fplnLineSize = size(mcdu.FPLNLines[i].output); + + if (fplnLineSize >= 1) { + fplnl1 = mcdu.FPLNLines[i].output[0].getText(); + if (fplnl1 != "") { + me["FPLN_L1"].setColor(mcdu.FPLNLines[i].output[0].getColor(i)); + me["FPLN_L1"].setText(fplnl1); + me["FPLN_L1"].show(); + } else { + me["FPLN_L1"].hide(); + } + fplnl1s = mcdu.FPLNLines[i].output[0].getSubText(i); + if (fplnl1s != "") { + me["FPLN_L1S"].setText(fplnl1s); + me["FPLN_L1S"].show(); + } else { + me["FPLN_L1S"].hide(); + } + } else { + me["FPLN_L1"].hide(); + me["FPLN_L1S"].hide(); + } + + if (fplnLineSize >= 2) { + fplnl2 = mcdu.FPLNLines[i].output[1].getText(); + if (fplnl2 != "") { + me["FPLN_L2"].setColor(mcdu.FPLNLines[i].output[1].getColor(i)); + me["FPLN_L2"].setText(fplnl2); + me["FPLN_L2"].show(); + } else { + me["FPLN_L2"].hide(); + } + fplnl2s = mcdu.FPLNLines[i].output[1].getSubText(i); + if (fplnl2s != "") { + me["FPLN_L2S"].setText(fplnl2s); + me["FPLN_L2S"].show(); + } else { + me["FPLN_L2S"].hide(); + } + } else { + me["FPLN_L2"].hide(); + me["FPLN_L2S"].hide(); + } + + if (fplnLineSize >= 3) { + fplnl3 = mcdu.FPLNLines[i].output[2].getText(); + if (fplnl3 != "") { + me["FPLN_L3"].setColor(mcdu.FPLNLines[i].output[2].getColor(i)); + me["FPLN_L3"].setText(fplnl3); + me["FPLN_L3"].show(); + } else { + me["FPLN_L3"].hide(); + } + fplnl3s = mcdu.FPLNLines[i].output[2].getSubText(i); + if (fplnl3s != "") { + me["FPLN_L3S"].setText(fplnl3s); + me["FPLN_L3S"].show(); + } else { + me["FPLN_L3S"].hide(); + } + } else { + me["FPLN_L3"].hide(); + me["FPLN_L3S"].hide(); + } + + if (fplnLineSize >= 4) { + fplnl4 = mcdu.FPLNLines[i].output[3].getText(); + if (fplnl4 != "") { + me["FPLN_L4"].setColor(mcdu.FPLNLines[i].output[3].getColor(i)); + me["FPLN_L4"].setText(fplnl4); + me["FPLN_L4"].show(); + } else { + me["FPLN_L4"].hide(); + } + fplnl4s = mcdu.FPLNLines[i].output[3].getSubText(i); + if (fplnl4s != "") { + me["FPLN_L4S"].setText(fplnl4s); + me["FPLN_L4S"].show(); + } else { + me["FPLN_L4S"].hide(); + } + } else { + me["FPLN_L4"].hide(); + me["FPLN_L4S"].hide(); + } + + if (fplnLineSize >= 5) { + fplnl5 = mcdu.FPLNLines[i].output[4].getText(); + if (fplnl5 != "") { + me["FPLN_L5"].setColor(mcdu.FPLNLines[i].output[4].getColor(i)); + me["FPLN_L5"].setText(fplnl5); + me["FPLN_L5"].show(); + } else { + me["FPLN_L5"].hide(); + } + fplnl5s = mcdu.FPLNLines[i].output[4].getSubText(i); + if (fplnl5s != "") { + me["FPLN_L5S"].setText(fplnl5s); + me["FPLN_L5S"].show(); + } else { + me["FPLN_L5S"].hide(); + } + } else { + me["FPLN_L5"].hide(); + me["FPLN_L5S"].hide(); + } + + if (fplnLineSize >= 6) { + fplnl6 = mcdu.FPLNLines[i].output[5].getText(); + if (fplnl6 != "") { + me["FPLN_L6"].setColor(mcdu.FPLNLines[i].output[5].getColor(i)); + me["FPLN_L6"].setText(fplnl6); + me["FPLN_L6"].show(); + } else { + me["FPLN_L6"].hide(); + } + fplnl6s = mcdu.FPLNLines[i].output[5].getSubText(i); + if (fplnl6s != "") { + me["FPLN_L6S"].setText(fplnl6s); + me["FPLN_L6S"].show(); + } else { + me["FPLN_L6S"].hide(); + } + } else { + me["FPLN_L6"].hide(); + me["FPLN_L6S"].hide(); + } + + if (mcdu.FPLNLines[i].index == 0) { + me["FPLN_From"].show(); + } else { + me["FPLN_From"].hide(); + } + + if (TMPYActive[i].getBoolValue()) { + me["FPLN_TMPY_group"].show(); + me["FPLN_6_group"].hide(); + } else { + me["FPLN_TMPY_group"].hide(); + me["FPLN_6_group"].show(); + } + } elsif (page == "MCDU") { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -253,6 +436,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -334,6 +518,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -413,6 +598,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -497,6 +683,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].show(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -593,6 +780,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -731,6 +919,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].hide(); + me["FPLN"].hide(); me["INITA"].show(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -885,6 +1074,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].show(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].show(); me["PERFTO"].hide(); @@ -1014,6 +1204,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].show(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -1125,6 +1316,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].show(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].show(); @@ -1282,6 +1474,7 @@ var canvas_MCDU_base = { if (!pageSwitch[i].getBoolValue()) { me["Simple"].show(); me["Simple_Center"].show(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); @@ -1399,9 +1592,244 @@ var canvas_MCDU_base = { me["Simple_C1"].setText("--- "); me["Simple_C5"].setText(" -350"); me["Simple_C1S"].setText("TIME "); + } elsif (page == "LATREV") { + if (!pageSwitch[i].getBoolValue()) { + me["Simple"].show(); + me["Simple_Center"].hide(); + me["FPLN"].hide(); + me["INITA"].hide(); + me["INITB"].hide(); + me["PERFTO"].hide(); + me["Simple_PageNum"].setText("X/X"); + me["Simple_PageNum"].hide(); + me["ArrowLeft"].hide(); + me["ArrowRight"].hide(); + + me.fontLeft(default, default, default, default, default, default); + me.fontLeftS(default, default, default, default, default, default); + me.fontRight(default, default, default, default, default, default); + me.fontRightS(default, default, default, default, default, default); + + me.fontSizeLeft(normal, normal, normal, normal, normal, normal); + me.fontSizeRight(normal, normal, normal, normal, normal, normal); + + me.colorLeftS("wht", "wht", "wht", "wht", "wht", "wht"); + me.colorLeftArrow("wht", "wht", "wht", "wht", "wht", "wht"); + me.colorRightS("wht", "wht", "wht", "wht", "wht", "wht"); + me.colorRightArrow("wht", "wht", "wht", "wht", "wht", "wht"); + + + if (myLatRev != nil) { + me["Simple_Title"].setText(sprintf("%s", myLatRev.title[0] ~ myLatRev.title[1] ~ myLatRev.title[2])); + + forindex (var matrixArrow; myLatRev.arrowsMatrix) { + if (matrixArrow == 0) { + var sign = "L"; + } else { + var sign = "R"; + } + forindex (var item; myLatRev.arrowsMatrix[matrixArrow]) { + if (myLatRev.arrowsMatrix[matrixArrow][item] == 1) { + me["Simple_" ~ sign ~ (item + 1) ~ "_Arrow"].show(); + } else { + me["Simple_" ~ sign ~ (item + 1) ~ "_Arrow"].hide(); + } + } + } + + forindex (var matrixFont; myLatRev.fontMatrix) { + if (matrixFont == 0) { + var sign = "L"; + } else { + var sign = "R"; + } + forindex (var item; myLatRev.fontMatrix[matrixFont]) { + if (myLatRev.fontMatrix[matrixFont][item] == 1) { + me["Simple_" ~ sign ~ (item + 1)].setFont(symbol); + me["Simple_" ~ sign ~ (item + 1)].setFontSize(small); + } else { + me["Simple_" ~ sign ~ (item + 1)].setFont(default); + me["Simple_" ~ sign ~ (item + 1)].setFontSize(normal); + } + } + } + + if (myLatRev.L1[0] == nil) { + me["Simple_L1"].hide(); + me["Simple_L1S"].hide(); + } else { + me["Simple_L1"].show(); + me["Simple_L1"].setText(myLatRev.L1[0]); + if (myLatRev.L1[1] != nil) { + me["Simple_L1S"].show(); + me["Simple_L1S"].setText(myLatRev.L1[1]); + } else { + me["Simple_L1S"].hide(); + } + } + + if (myLatRev.L2[0] == nil) { + me["Simple_L2"].hide(); + me["Simple_L2S"].hide(); + } else { + me["Simple_L2"].show(); + me["Simple_L2"].setText(myLatRev.L2[0]); + if (myLatRev.L2[1] != nil) { + me["Simple_L2S"].show(); + me["Simple_L2S"].setText(myLatRev.L2[1]); + } else { + me["Simple_L2S"].hide(); + } + } + + if (myLatRev.L3[0] == nil) { + me["Simple_L3"].hide(); + me["Simple_L3S"].hide(); + } else { + me["Simple_L3"].show(); + me["Simple_L3"].setText(myLatRev.L3[0]); + if (myLatRev.L3[1] != nil) { + me["Simple_L3S"].show(); + me["Simple_L3S"].setText(myLatRev.L3[1]); + } else { + me["Simple_L3S"].hide(); + } + } + + if (myLatRev.L4[0] == nil) { + me["Simple_L4"].hide(); + me["Simple_L4S"].hide(); + } else { + me["Simple_L4"].show(); + me["Simple_L4"].setText(myLatRev.L4[0]); + if (myLatRev.L4[1] != nil) { + me["Simple_L4S"].show(); + me["Simple_L4S"].setText(myLatRev.L4[1]); + } else { + me["Simple_L4S"].hide(); + } + } + + if (myLatRev.L5[0] == nil) { + me["Simple_L5"].hide(); + me["Simple_L5S"].hide(); + } else { + me["Simple_L5"].show(); + me["Simple_L5"].setText(myLatRev.L5[0]); + if (myLatRev.L5[1] != nil) { + me["Simple_L5S"].show(); + me["Simple_L5S"].setText(myLatRev.L5[1]); + } else { + me["Simple_L5S"].hide(); + } + } + + if (myLatRev.L6[0] == nil) { + me["Simple_L6"].hide(); + me["Simple_L6S"].hide(); + } else { + me["Simple_L6"].show(); + me["Simple_L6"].setText(myLatRev.L6[0]); + if (myLatRev.L6[1] != nil) { + me["Simple_L6S"].show(); + me["Simple_L6S"].setText(myLatRev.L6[1]); + } else { + me["Simple_L6S"].hide(); + } + } + me.colorLeft(myLatRev.L1[2],myLatRev.L2[2],myLatRev.L3[2],myLatRev.L4[2],myLatRev.L5[2],myLatRev.L6[2]); + + if (myLatRev.R1[0] == nil) { + me["Simple_R1"].hide(); + me["Simple_R1S"].hide(); + } else { + me["Simple_R1"].show(); + me["Simple_R1"].setText(myLatRev.R1[0]); + if (myLatRev.R1[1] != nil) { + me["Simple_R1S"].show(); + me["Simple_R1S"].setText(myLatRev.R1[1]); + } else { + me["Simple_R1S"].hide(); + } + } + + if (myLatRev.R2[0] == nil) { + me["Simple_R2"].hide(); + me["Simple_R2S"].hide(); + } else { + me["Simple_R2"].show(); + me["Simple_R2"].setText(myLatRev.R2[0]); + if (myLatRev.R2[1] != nil) { + me["Simple_R2S"].show(); + me["Simple_R2S"].setText(myLatRev.R2[1]); + } else { + me["Simple_R2S"].hide(); + } + } + + if (myLatRev.R3[0] == nil) { + me["Simple_R3"].hide(); + me["Simple_R3S"].hide(); + } else { + me["Simple_R3"].show(); + me["Simple_R3"].setText(myLatRev.R3[0]); + if (myLatRev.R3[1] != nil) { + me["Simple_R3S"].show(); + me["Simple_R3S"].setText(myLatRev.R3[1]); + } else { + me["Simple_R3S"].hide(); + } + } + + if (myLatRev.R4[0] == nil) { + me["Simple_R4"].hide(); + me["Simple_R4S"].hide(); + } else { + me["Simple_R4"].show(); + me["Simple_R4"].setText(myLatRev.R4[0]); + if (myLatRev.R4[1] != nil) { + me["Simple_R4S"].show(); + me["Simple_R4S"].setText(myLatRev.R4[1]); + } else { + me["Simple_R4S"].hide(); + } + } + + if (myLatRev.R5[0] == nil) { + me["Simple_R5"].hide(); + me["Simple_R5S"].hide(); + } else { + me["Simple_R5"].show(); + me["Simple_R5"].setText(myLatRev.R5[0]); + if (myLatRev.R5[1] != nil) { + me["Simple_R5S"].show(); + me["Simple_R5S"].setText(myLatRev.R5[1]); + } else { + me["Simple_R5S"].hide(); + } + } + + if (myLatRev.R6[0] == nil) { + me["Simple_R6"].hide(); + me["Simple_R6S"].hide(); + } else { + me["Simple_R6"].show(); + me["Simple_R6"].setText(myLatRev.R6[0]); + if (myLatRev.R6[1] != nil) { + me["Simple_R6S"].show(); + me["Simple_R6S"].setText(myLatRev.R6[1]); + } else { + me["Simple_R6S"].hide(); + } + } + me.colorRight(myLatRev.R1[2],myLatRev.R2[2],myLatRev.R3[2],myLatRev.R4[2],myLatRev.R5[2],myLatRev.R6[2]); + } + pageSwitch[i].setBoolValue(1); + } } else { if (!pageSwitch[i].getBoolValue()) { me["Simple"].hide(); + me["FPLN"].hide(); me["INITA"].hide(); me["INITB"].hide(); me["PERFTO"].hide(); diff --git a/Models/Instruments/MCDU/res/mcdu.svg b/Models/Instruments/MCDU/res/mcdu.svg index 6895e780..f45606fc 100644 --- a/Models/Instruments/MCDU/res/mcdu.svg +++ b/Models/Instruments/MCDU/res/mcdu.svg @@ -14,6 +14,33 @@ id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="mcdu.svg"> + + + @@ -28,1455 +55,1454 @@ - - - SCRATCHPAD + x="20.138426" + y="836.87567" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:70px;font-family:BoeingCDULarge;-inkscape-font-specification:BoeingCDULarge;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;">SCRATCHPAD + id="ArrowLeft"> + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> - - - - - - - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - - TITLE - X/X - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - - - - - TEXT - TEXT - TEXT - TEXT - TEXT - TEXT + id="ArrowRight" + inkscape:label="#g4241" + transform="matrix(-1,0,0,1,1911.9173,-0.2)"> + + + + inkscape:label="Simple" + id="Simple" + inkscape:groupmode="layer"> + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + + TITLE + X/X + + + + + TEXT + + transform="matrix(1.0000018,0,0,0.99998906,-895.98862,118.48532)"> + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + + + + + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + / + + . + / + + + + + + + + + + + + + . + + + . + + + + + + + + + - - - - - - / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - / - - - - / - - . - / - - - - - - - - - - - - - . - - - . - - - - - - - - - - - + + + + + + - - - - - - + transform="translate(-833.84951,236.72)"> + F - S + x="309.12155" + y="187.10254" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:70px;font-family:BoeingCDULarge;-inkscape-font-specification:BoeingCDULarge;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1">F O + id="tspan4395" + sodipodi:role="line">S = + id="tspan4399" + x="307.8522" + y="422.15305" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:70px;font-family:BoeingCDULarge;-inkscape-font-specification:BoeingCDULarge;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1">O = = + = + + + FROM + CALLSIG + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + TEXT + + TEXT + TEXT + + + TMPY + + ERASE + TMPY + + + + + + + + TMPY + INSERT + + + + + + + + diff --git a/Models/Instruments/ND/canvas/A3XX_ND.nas b/Models/Instruments/ND/canvas/A3XX_ND.nas index ab682866..4d82cdbb 100644 --- a/Models/Instruments/ND/canvas/A3XX_ND.nas +++ b/Models/Instruments/ND/canvas/A3XX_ND.nas @@ -5,8 +5,8 @@ # Copyright (c) 2019 Joshua Davidson (Octal450) var get_local_path = func(file){ - var aircraft_dir = split("/", getprop("/sim/aircraft-dir"))[-1]; - return "Aircraft/" ~ aircraft_dir ~ "/Models/Instruments/ND/canvas/"~ file; + var aircraft_dir = split("/", getprop("/sim/aircraft-dir"))[-1]; + return "Aircraft/" ~ aircraft_dir ~ "/Models/Instruments/ND/canvas/"~ file; }; var version = getprop("sim/version/flightgear"); diff --git a/Models/Instruments/ND/canvas/A3XX_ND_drivers.nas b/Models/Instruments/ND/canvas/A3XX_ND_drivers.nas index eca43a4e..baf7179b 100644 --- a/Models/Instruments/ND/canvas/A3XX_ND_drivers.nas +++ b/Models/Instruments/ND/canvas/A3XX_ND_drivers.nas @@ -5,107 +5,118 @@ # Copyright (c) 2019 Joshua Davidson (Octal450) var A3XXRouteDriver = { - new: func(){ - var m = { - parents: [A3XXRouteDriver], - }; - m.init(); - return m; - }, - init: func(){ - me.update(); - }, - update: func(){ - me.flightplan = flightplan(); - }, - getNumberOfFlightPlans: func(){1}, - getFlightPlanType: func(fpNum){"current"}, - getFlightPlan: func(fpNum){me.flightplan}, - getPlanSize: func(fpNum){me.flightplan.getPlanSize()}, - getWP: func(fpNum, idx){me.flightplan.getWP(idx)}, - getPlanModeWP: func(plan_wp_idx){me.flightplan.getWP(plan_wp_idx)}, - hasDiscontinuity: func(fpNum, wptID){0}, - getListeners: func(){[]}, - shouldUpdate: func 1 + new: func(){ + var m = { + parents: [A3XXRouteDriver], + }; + m.init(); + return m; + }, + init: func(){ + me.update(); + }, + update: func(){ + me.flightplan = fmgc.fp[2]; + }, + getNumberOfFlightPlans: func(){1}, + getFlightPlanType: func(fpNum){"current"}, + getFlightPlan: func(fpNum){me.flightplan}, + getPlanSize: func(fpNum){me.flightplan.getPlanSize()}, + getWP: func(fpNum, idx){me.flightplan.getWP(idx)}, + getPlanModeWP: func(plan_wp_idx){me.flightplan.getWP(plan_wp_idx)}, + hasDiscontinuity: func(fpNum, wptID){0}, + triggerSignal: func(signal){ + setprop(me.signalPath(signal),1); + setprop(me.signalPath(signal),0); + }, + signalPath: func(signal){ + "autopilot/route-manager/signals/rd-"~ signal; + }, + getListeners: func(){[ + me.signalPath("fp-added"), + me.signalPath("fp-removed") + ]}, + shouldUpdate: func 1 }; var MultiA3XXRouteDriver = { - parents: [A3XXRouteDriver], - new: func(){ - var m = { - parents: [MultiA3XXRouteDriver], - _flightplans: [], - currentFlightPlan: 0 - }; - m.init(); - return m; - }, - addFlightPlan: func(type, plan){ - append(me._flightplans, { - type: type, - flightplan: plan - }); - }, - removeFlightPlanAtIndex: func(idx){ - var sz = size(me._flightplans); - if(idx < sz){ - if(sz == 1) - me._flightplans = []; - elsif(sz == 2 and idx == 0) - me._flightplans = [me._flightplans[1]]; - elsif(sz == 2 and idx == 1) - pop(me._flightplans); - else { - var subv_l = subvec(me._flightplans, 0, idx); - var subv_r = subvec(me._flightplans, idx + 1); - me._flightplans = subv_l ~ subv_r; - } - } - me.triggerSignal("fp-added"); - }, - removeFlightPlanOfType: func(type){ - var new_vec = []; - foreach(var fp; me._flightplans){ - if(fp["type"] != type) - append(new_vec, fp); - } - me._flightplans = new_vec; - me.triggerSignal("fp-removed"); - }, - getNumberOfFlightPlans: func(){ - size(me._flightplans); - }, - getFlightPlanType: func(fpNum){ - if(fpNum >= size(me._flightplans)) return nil; - var fp = me._flightplans[fpNum]; - return fp.type; - }, - getFlightPlan: func(fpNum){ - if(fpNum >= size(me._flightplans)) return nil; - return me._flightplans[fpNum]; - }, - getPlanSize: func(fpNum){ - if(fpNum >= size(me._flightplans)) return 0; - return me._flightplans[fpNum].getPlanSize(); - }, - getWP: func(fpNum, idx){ - if(fpNum >= size(me._flightplans)) return nil; - var fp = me._flightplans[fpNum].getPlanSize(); - return fp.getWP(idx); - }, - getPlanModeWP: func(idx){ - if(me.currentFlightPlan >= size(me._flightplans)) return nil; - var fp = me._flightplans[me.currentFlightPlan]; - return fp.getWP(idx); - }, - triggerSignal: func(signal){ - setprop(me.signalPath(signal)); - }, - signalPath: func(signal){ - "autopilot/route-manager/signals/rd-"~ signal; - }, - getListeners: func(){[ - me.getSignal("fp-added"), - me.getSignal("fp-removed") - ]} + parents: [A3XXRouteDriver], + new: func(){ + var m = { + parents: [MultiA3XXRouteDriver], + _flightplans: [], + currentFlightPlan: 0 + }; + m.init(); + return m; + }, + addFlightPlan: func(type, plan){ + append(me._flightplans, { + type: type, + flightplan: plan + }); + }, + removeFlightPlanAtIndex: func(idx){ + var sz = size(me._flightplans); + if(idx < sz){ + if(sz == 1) + me._flightplans = []; + elsif(sz == 2 and idx == 0) + me._flightplans = [me._flightplans[1]]; + elsif(sz == 2 and idx == 1) + pop(me._flightplans); + else { + var subv_l = subvec(me._flightplans, 0, idx); + var subv_r = subvec(me._flightplans, idx + 1); + me._flightplans = subv_l ~ subv_r; + } + } + me.triggerSignal("fp-added"); + }, + removeFlightPlanOfType: func(type){ + var new_vec = []; + foreach(var fp; me._flightplans){ + if(fp["type"] != type) + append(new_vec, fp); + } + me._flightplans = new_vec; + me.triggerSignal("fp-removed"); + }, + getNumberOfFlightPlans: func(){ + size(me._flightplans); + }, + getFlightPlanType: func(fpNum){ + if(fpNum >= size(me._flightplans)) return nil; + var fp = me._flightplans[fpNum]; + return fp.type; + }, + getFlightPlan: func(fpNum){ + if(fpNum >= size(me._flightplans)) return nil; + return me._flightplans[fpNum]; + }, + getPlanSize: func(fpNum){ + if(fpNum >= size(me._flightplans)) return 0; + return me._flightplans[fpNum].getPlanSize(); + }, + getWP: func(fpNum, idx){ + if(fpNum >= size(me._flightplans)) return nil; + var fp = me._flightplans[fpNum].getPlanSize(); + return fp.getWP(idx); + }, + getPlanModeWP: func(idx){ + if(me.currentFlightPlan >= size(me._flightplans)) return nil; + var fp = me._flightplans[me.currentFlightPlan]; + return fp.getWP(idx); + }, + triggerSignal: func(signal){ + setprop(me.signalPath(signal), 1); + setprop(me.signalPath(signal), 0); + }, + signalPath: func(signal){ + "autopilot/route-manager/signals/rd-"~ signal; + }, + getListeners: func(){[ + me.getSignal("fp-added"), + me.getSignal("fp-removed") + ]} }; diff --git a/Models/Instruments/ND/canvas/ND_config.nas b/Models/Instruments/ND/canvas/ND_config.nas index ef122e70..af7281f8 100644 --- a/Models/Instruments/ND/canvas/ND_config.nas +++ b/Models/Instruments/ND/canvas/ND_config.nas @@ -5,23 +5,23 @@ # Copyright (c) 2019 Joshua Davidson (Octal450) canvas.NDConfig = { - properties: { - des_apt: "/autopilot/route-manager/destination/airport", - dep_apt: "/autopilot/route-manager/departure/airport", - des_rwy: "/autopilot/route-manager/destination/runway", - dep_rwy: "/autopilot/route-manager/departure/runway", - fplan_active: "autopilot/route-manager/active", - athr: "/it-autoflight/output/athr", - cur_wp: "/autopilot/route-manager/current-wp", - vnav_node: "/autopilot/route-manager/vnav/", - spd_node: "/autopilot/route-manager/spd/", - holding: "/flight-management/hold", - holding_points: "/flight-management/hold/points", - adf1_frq: "instrumentation/adf[0]/frequencies/selected-khz", - adf2_frq: "instrumentation/adf[1]/frequencies/selected-khz", - nav1_frq: "instrumentation/nav[0]/frequencies/selected-mhz", - nav2_frq: "instrumentation/nav[1]/frequencies/selected-mhz", - lat_ctrl: "/it-autoflight/output/lat", - ver_ctrl: "/it-autoflight/output/vert", - } + properties: { + des_apt: "/autopilot/route-manager/destination/airport", + dep_apt: "/autopilot/route-manager/departure/airport", + des_rwy: "/autopilot/route-manager/destination/runway", + dep_rwy: "/autopilot/route-manager/departure/runway", + fplan_active: "autopilot/route-manager/active", + athr: "/it-autoflight/output/athr", + cur_wp: "/autopilot/route-manager/current-wp", + vnav_node: "/autopilot/route-manager/vnav/", + spd_node: "/autopilot/route-manager/spd/", + holding: "/flight-management/hold", + holding_points: "/flight-management/hold/points", + adf1_frq: "instrumentation/adf[0]/frequencies/selected-khz", + adf2_frq: "instrumentation/adf[1]/frequencies/selected-khz", + nav1_frq: "instrumentation/nav[0]/frequencies/selected-mhz", + nav2_frq: "instrumentation/nav[1]/frequencies/selected-mhz", + lat_ctrl: "/it-autoflight/output/lat", + ver_ctrl: "/it-autoflight/output/vert", + } }; diff --git a/Models/Instruments/ND/canvas/helpers.nas b/Models/Instruments/ND/canvas/helpers.nas index 44eb38d2..c6a890a3 100644 --- a/Models/Instruments/ND/canvas/helpers.nas +++ b/Models/Instruments/ND/canvas/helpers.nas @@ -5,141 +5,141 @@ # Copyright (c) 2019 Joshua Davidson (Octal450) var SymbolPainter = { - aircraft_dir: nil, - getOpts: func(opts){ - if(opts == nil) opts = {}; - var defOpts = {id:nil,color:nil,scale:1,create_group:0,update_center:0}; - if(contains(opts, "id")) - defOpts.id = opts.id; - if(contains(opts, "color")) - defOpts.color = opts.color; - if(contains(opts, "scale")) - defOpts.scale = opts.scale; - if(contains(opts, "create_group")) - defOpts.create_group = opts.create_group; - if(contains(opts, "update_center")) - defOpts.update_center = opts.update_center; - return defOpts; - }, - getAircraftDir: func(){ - if(me.aircraft_dir == nil) - me.aircraft_dir = split("/", getprop("/sim/aircraft-dir"))[-1]; - return me.aircraft_dir; - }, - svgPath: func(file){ - return "Aircraft/" ~ me.getAircraftDir() ~ "/Models/Instruments/ND/canvas/res/"~file; - }, - drawFIX : func(grp, opts = nil){ - var icon_fix = nil; - opts = me.getOpts(opts); - var sym_id = opts.id; - if(sym_id != nil) - icon_fix = grp.createChild("path", sym_id); - else - icon_fix = grp.createChild("path"); - var color = opts.color; - if(color == nil){ - color = { - r: 0.69, - g: 0, - b: 0.39 - }; - } - var scale = opts.scale; - if(scale == nil) scale = 0.8; - icon_fix.moveTo(-10,0) - .lineTo(0,-17) - .lineTo(10,0) - .lineTo(0,17) - .close() - .setStrokeLineWidth(3) - .setColor(color.r,color.g,color.b) - .setScale(scale,scale); - return icon_fix; - }, - drawVOR: func(grp, opts = nil){ - opts = me.getOpts(opts); - if(opts.create_group){ - var sym_id = opts.id; - if(sym_id != nil) - grp = grp.createChild("group", sym_id); - else - grp = grp.createChild("group"); - } - var svg_path = me.svgPath("airbus_vor.svg"); - canvas.parsesvg(grp, svg_path); - var scale = opts.scale; - if(scale == nil) scale = 0.8; - grp.setScale(scale,scale); - if(opts.update_center) - grp.setTranslation(-24 * scale,-24 * scale); - if(!contains(grp, "setColor")){ - grp.setColor = func { - var layer1 = grp.getElementById("layer1"); - if(layer1 == nil) return; - var children = layer1.getChildren(); - foreach(var c; children){ - if(isa(c, canvas.Path)) - c.setColor(arg); - } - }; - } - return grp; - }, - drawNDB: func(grp, opts = nil){ - var icon_ndb = nil; - opts = me.getOpts(opts); - var sym_id = opts.id; - if(sym_id != nil) - icon_ndb = grp.createChild("path", sym_id); - else - icon_ndb = grp.createChild("path"); - var color = opts.color; - var color = opts.color; - if(color == nil){ - color = { - r: 0.69, - g: 0, - b: 0.39 - }; - } - var scale = opts.scale; - if(scale == nil) scale = 0.8; - icon_ndb.moveTo(-15,15) - .lineTo(0,-15) - .lineTo(15,15) - .close() - .setStrokeLineWidth(3) - .setColor(color.r,color.g,color.b) - .setScale(scale,scale); - return icon_ndb; - }, - drawAirport: func(grp, opts = nil){ - opts = me.getOpts(opts); - if(opts.create_group){ - var sym_id = opts.id; - if(sym_id != nil) - grp = grp.createChild("group", sym_id); - else - grp = grp.createChild("group"); - } - var svg_path = me.svgPath("airbus_airport.svg"); - canvas.parsesvg(grp, svg_path); - var scale = opts.scale; - if(scale == nil) scale = 0.8; - grp.setScale(scale,scale); - if(opts.update_center) - grp.setTranslation(-24 * scale,-24 * scale); - return grp; - }, - draw: func(type, grp, opts = nil){ - if(type == "VOR" or type == "vor") - return me.drawVOR(grp, opts); - elsif(type == "NDB" or type == "ndb") - return me.drawNDB(grp, opts); - elsif(type == "ARPT" or type == "arpt") - return me.drawAirport(grp, opts); - else - return me.drawFIX(grp, opts); - } + aircraft_dir: nil, + getOpts: func(opts){ + if(opts == nil) opts = {}; + var defOpts = {id:nil,color:nil,scale:1,create_group:0,update_center:0}; + if(contains(opts, "id")) + defOpts.id = opts.id; + if(contains(opts, "color")) + defOpts.color = opts.color; + if(contains(opts, "scale")) + defOpts.scale = opts.scale; + if(contains(opts, "create_group")) + defOpts.create_group = opts.create_group; + if(contains(opts, "update_center")) + defOpts.update_center = opts.update_center; + return defOpts; + }, + getAircraftDir: func(){ + if(me.aircraft_dir == nil) + me.aircraft_dir = split("/", getprop("/sim/aircraft-dir"))[-1]; + return me.aircraft_dir; + }, + svgPath: func(file){ + return "Aircraft/" ~ me.getAircraftDir() ~ "/Models/Instruments/ND/canvas/res/"~file; + }, + drawFIX : func(grp, opts = nil){ + var icon_fix = nil; + opts = me.getOpts(opts); + var sym_id = opts.id; + if(sym_id != nil) + icon_fix = grp.createChild("path", sym_id); + else + icon_fix = grp.createChild("path"); + var color = opts.color; + if(color == nil){ + color = { + r: 0.69, + g: 0, + b: 0.39 + }; + } + var scale = opts.scale; + if(scale == nil) scale = 0.8; + icon_fix.moveTo(-10,0) + .lineTo(0,-17) + .lineTo(10,0) + .lineTo(0,17) + .close() + .setStrokeLineWidth(3) + .setColor(color.r,color.g,color.b) + .setScale(scale,scale); + return icon_fix; + }, + drawVOR: func(grp, opts = nil){ + opts = me.getOpts(opts); + if(opts.create_group){ + var sym_id = opts.id; + if(sym_id != nil) + grp = grp.createChild("group", sym_id); + else + grp = grp.createChild("group"); + } + var svg_path = me.svgPath("airbus_vor.svg"); + canvas.parsesvg(grp, svg_path); + var scale = opts.scale; + if(scale == nil) scale = 0.8; + grp.setScale(scale,scale); + if(opts.update_center) + grp.setTranslation(-24 * scale,-24 * scale); + if(!contains(grp, "setColor")){ + grp.setColor = func { + var layer1 = grp.getElementById("layer1"); + if(layer1 == nil) return; + var children = layer1.getChildren(); + foreach(var c; children){ + if(isa(c, canvas.Path)) + c.setColor(arg); + } + }; + } + return grp; + }, + drawNDB: func(grp, opts = nil){ + var icon_ndb = nil; + opts = me.getOpts(opts); + var sym_id = opts.id; + if(sym_id != nil) + icon_ndb = grp.createChild("path", sym_id); + else + icon_ndb = grp.createChild("path"); + var color = opts.color; + var color = opts.color; + if(color == nil){ + color = { + r: 0.69, + g: 0, + b: 0.39 + }; + } + var scale = opts.scale; + if(scale == nil) scale = 0.8; + icon_ndb.moveTo(-15,15) + .lineTo(0,-15) + .lineTo(15,15) + .close() + .setStrokeLineWidth(3) + .setColor(color.r,color.g,color.b) + .setScale(scale,scale); + return icon_ndb; + }, + drawAirport: func(grp, opts = nil){ + opts = me.getOpts(opts); + if(opts.create_group){ + var sym_id = opts.id; + if(sym_id != nil) + grp = grp.createChild("group", sym_id); + else + grp = grp.createChild("group"); + } + var svg_path = me.svgPath("airbus_airport.svg"); + canvas.parsesvg(grp, svg_path); + var scale = opts.scale; + if(scale == nil) scale = 0.8; + grp.setScale(scale,scale); + if(opts.update_center) + grp.setTranslation(-24 * scale,-24 * scale); + return grp; + }, + draw: func(type, grp, opts = nil){ + if(type == "VOR" or type == "vor") + return me.drawVOR(grp, opts); + elsif(type == "NDB" or type == "ndb") + return me.drawNDB(grp, opts); + elsif(type == "ARPT" or type == "arpt") + return me.drawAirport(grp, opts); + else + return me.drawFIX(grp, opts); + } }; diff --git a/Models/Instruments/ND/canvas/loaders.nas b/Models/Instruments/ND/canvas/loaders.nas index 72b56df7..ba07c923 100644 --- a/Models/Instruments/ND/canvas/loaders.nas +++ b/Models/Instruments/ND/canvas/loaders.nas @@ -10,78 +10,78 @@ version = num(v[0]~"."~v[1]); setlistener("/nasal/canvas/loaded", func() { - ####### LOAD FILES ####### - #print("loading files"); - (func { - var aircraft_root = getprop("/sim/aircraft-dir"); + ####### LOAD FILES ####### + #print("loading files"); + (func { + var aircraft_root = getprop("/sim/aircraft-dir"); - var load = func(file, name) { - #print("Loading ..." ~ file); - if (name == nil) - var name = split("/", file)[-1]; - if (substr(name, size(name)-4) == ".draw") - name = substr(name, 0, size(name)-5); - #print("reading file"); - var code = io.readfile(file); - #print("compiling file"); - # This segfaults for some reason: - #var code = call(compile, [code], var err=[]); - var code = call(func compile(code, file), [code], var err=[]); - if (size(err)) { - #print("handling error"); - if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature - var e = split(" at line ", err[0]); - if (size(e) == 2) - err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]); - } - for (var i = 1; (var c = caller(i)) != nil; i += 1) - err ~= subvec(c, 2, 2); - debug.printerror(err); - return; - } - #print("calling code"); - call(code, nil, nil, var hash = {}); - #debug.dump(keys(hash)); - return hash; - }; + var load = func(file, name) { + #print("Loading ..." ~ file); + if (name == nil) + var name = split("/", file)[-1]; + if (substr(name, size(name)-4) == ".draw") + name = substr(name, 0, size(name)-5); + #print("reading file"); + var code = io.readfile(file); + #print("compiling file"); + # This segfaults for some reason: + #var code = call(compile, [code], var err=[]); + var code = call(func compile(code, file), [code], var err=[]); + if (size(err)) { + #print("handling error"); + if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature + var e = split(" at line ", err[0]); + if (size(e) == 2) + err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]); + } + for (var i = 1; (var c = caller(i)) != nil; i += 1) + err ~= subvec(c, 2, 2); + debug.printerror(err); + return; + } + #print("calling code"); + call(code, nil, nil, var hash = {}); + #debug.dump(keys(hash)); + return hash; + }; - var load_deps = func(name) { - print("Loading MapStructure Layer: "~ name); - load(aircraft_root~"/Models/Instruments/ND/map/"~name~".lcontroller", name); - load(aircraft_root~"/Models/Instruments/ND/map/"~name~".symbol", name); - if(version < 3.2) - load(aircraft_root~"/Models/Instruments/ND/map/"~name~".scontroller", name); - } + var load_deps = func(name) { + print("Loading MapStructure Layer: "~ name); + load(aircraft_root~"/Models/Instruments/ND/map/"~name~".lcontroller", name); + load(aircraft_root~"/Models/Instruments/ND/map/"~name~".symbol", name); + if(version < 3.2) + load(aircraft_root~"/Models/Instruments/ND/map/"~name~".scontroller", name); + } - #foreach( var name; ["APS","ALT-profile","SPD-profile","RTE","WPT","DECEL","NDB"] ) - #load_deps( name ); - var dep_names = [ - # With these extensions, in this order: - "lcontroller", - "symbol", - "scontroller", - "controller", - ]; - var map_root = aircraft_root~"/Models/Instruments/ND/canvas/map/"; - var files = directory(map_root); - var deps = {}; - foreach (var d; dep_names) deps[d] = []; - foreach(var f; files){ - var ext = size(var s=split(".", f)) > 1 ? s[-1] : nil; - foreach (var d; dep_names) { - if (ext == d) { - append(deps[d], f); - break - } - } - } + #foreach( var name; ["APS","ALT-profile","SPD-profile","RTE","WPT","DECEL","NDB"] ) + #load_deps( name ); + var dep_names = [ + # With these extensions, in this order: + "lcontroller", + "symbol", + "scontroller", + "controller", + ]; + var map_root = aircraft_root~"/Models/Instruments/ND/canvas/map/"; + var files = directory(map_root); + var deps = {}; + foreach (var d; dep_names) deps[d] = []; + foreach(var f; files){ + var ext = size(var s=split(".", f)) > 1 ? s[-1] : nil; + foreach (var d; dep_names) { + if (ext == d) { + append(deps[d], f); + break + } + } + } - foreach (var d; dep_names) { - foreach (var f; deps[d]) { - var name = split(".", f)[0]; - load(map_root~f, name); - } - } + foreach (var d; dep_names) { + foreach (var f; deps[d]) { + var name = split(".", f)[0]; + load(map_root~f, name); + } + } })(); diff --git a/Models/Instruments/ND/canvas/map/ALT-profile.scontroller b/Models/Instruments/ND/canvas/map/ALT-profile.scontroller index 1bd3fee3..a880967c 100644 --- a/Models/Instruments/ND/canvas/map/ALT-profile.scontroller +++ b/Models/Instruments/ND/canvas/map/ALT-profile.scontroller @@ -8,5 +8,5 @@ var new = func(model) ; # this controller doesn't need an instance var LayerController = SymbolLayer.Controller.registry[name]; var isActive = func(model) {return 1};#LayerController.a_instance.isActive(model); var query_range = func() - die(name~".scontroller.query_range /MUST/ be provided by implementation"); + die(name~".scontroller.query_range /MUST/ be provided by implementation"); #var model = props.globals.getNode('/position'); diff --git a/Models/Instruments/ND/canvas/map/APS.scontroller b/Models/Instruments/ND/canvas/map/APS.scontroller index e82d4c0a..8af1c96f 100644 --- a/Models/Instruments/ND/canvas/map/APS.scontroller +++ b/Models/Instruments/ND/canvas/map/APS.scontroller @@ -8,5 +8,5 @@ var new = func(model) ; # this controller doesn't need an instance var LayerController = canvas.SymbolLayer.Controller.registry[name]; var isActive = func(model) {return 1};#LayerController.a_instance.isActive(model); var query_range = func() - die(name~".scontroller.query_range /MUST/ be provided by implementation"); + die(name~".scontroller.query_range /MUST/ be provided by implementation"); #var model = props.globals.getNode('/position'); diff --git a/Models/Instruments/ND/canvas/map/APT.scontroller b/Models/Instruments/ND/canvas/map/APT.scontroller index d41a6049..48ed05d7 100644 --- a/Models/Instruments/ND/canvas/map/APT.scontroller +++ b/Models/Instruments/ND/canvas/map/APT.scontroller @@ -11,6 +11,6 @@ var query_range = func() die(name~".scontroller.query_range /MUST/ be provided by implementation"); var getpos = func(model){ - [model.lat, model.lon]; + [model.lat, model.lon]; } diff --git a/Models/Instruments/ND/canvas/map/DEBUG.lcontroller b/Models/Instruments/ND/canvas/map/DEBUG.lcontroller index 9d427ba2..3b1fce73 100644 --- a/Models/Instruments/ND/canvas/map/DEBUG.lcontroller +++ b/Models/Instruments/ND/canvas/map/DEBUG.lcontroller @@ -6,66 +6,66 @@ var __self__ = caller(0)[0]; canvas.SymbolLayer.Controller.add(name, __self__); canvas.SymbolLayer.add(name, { - parents: [canvas.MultiSymbolLayer], - type: name, # Symbol type - df_controller: __self__, # controller to use by default -- this one - df_options: { - update_t : 'autopilot/route-manager/debug/update_t', - listen: ['update_t'] - }, - df_style: { - default_color: [1,0,0], - } + parents: [canvas.MultiSymbolLayer], + type: name, # Symbol type + df_controller: __self__, # controller to use by default -- this one + df_options: { + update_t : 'autopilot/route-manager/debug/update_t', + listen: ['update_t'] + }, + df_style: { + default_color: [1,0,0], + } }); var new = func(layer) { - var m = { - parents: [__self__], - layer: layer, - map: layer.map, - listeners: [], - }; - layer.searcher._equals = func(a,b) a.equals(b); + var m = { + parents: [__self__], + layer: layer, + map: layer.map, + listeners: [], + }; + layer.searcher._equals = func(a,b) a.equals(b); - return m; + return m; }; var del = func() { - foreach (var l; me.listeners) - removelistener(l); + foreach (var l; me.listeners) + removelistener(l); }; var searchCmd = func { - var result = []; - #return result; - var node = me['node']; - if (node == nil) { - node = props.globals.getNode('autopilot/route-manager/debug/', 1); - me.node = node; - } - var points = me.node.getNode('points', 1).getChildren(); - #var count = getprop('autopilot/route-manager/debug/num') or 0; - var count = size(points); - #print('Map DEBUG: querying '~ count ~' results.'); - for(var idx = 0; idx < count; idx += 1){ - var point = points[idx]; - #var id = getprop('autopilot/route-manager/debug/point['~idx~']/id'); - #var lat = getprop('autopilot/route-manager/debug/point['~idx~']/lat'); - #var lon = getprop('autopilot/route-manager/debug/point['~idx~']/lon'); - var id = point.getValue('id'); - var lat = point.getValue('lat'); - var lon = point.getValue('lon'); - if (id == nil or id == '') continue; - #print('Map DEBUG: found '~ id ~' debug point.'); - var model = { - id: id, - lat: lat, - lon: lon, - equals: func(o){ - me.id == o.id and me.lat == o.lat and me.lon == o.lon - } - }; - append(result, model); - } - return result; + var result = []; + #return result; + var node = me['node']; + if (node == nil) { + node = props.globals.getNode('autopilot/route-manager/debug/', 1); + me.node = node; + } + var points = me.node.getNode('points', 1).getChildren(); + #var count = getprop('autopilot/route-manager/debug/num') or 0; + var count = size(points); + #print('Map DEBUG: querying '~ count ~' results.'); + for(var idx = 0; idx < count; idx += 1){ + var point = points[idx]; + #var id = getprop('autopilot/route-manager/debug/point['~idx~']/id'); + #var lat = getprop('autopilot/route-manager/debug/point['~idx~']/lat'); + #var lon = getprop('autopilot/route-manager/debug/point['~idx~']/lon'); + var id = point.getValue('id'); + var lat = point.getValue('lat'); + var lon = point.getValue('lon'); + if (id == nil or id == '') continue; + #print('Map DEBUG: found '~ id ~' debug point.'); + var model = { + id: id, + lat: lat, + lon: lon, + equals: func(o){ + me.id == o.id and me.lat == o.lat and me.lon == o.lon + } + }; + append(result, model); + } + return result; } diff --git a/Models/Instruments/ND/canvas/map/DEBUG.symbol b/Models/Instruments/ND/canvas/map/DEBUG.symbol index b58444d7..12fc978f 100644 --- a/Models/Instruments/ND/canvas/map/DEBUG.symbol +++ b/Models/Instruments/ND/canvas/map/DEBUG.symbol @@ -8,20 +8,20 @@ canvas.DotSym.makeinstance( name, __self__ ); var element_type = "group"; var init = func { - me.text_wps = me.element.createChild("text", "dbg-text-" ~ me.model.id) - .setDrawMode( canvas.Text.TEXT ) - .setText(me.model.id) - .setFont("LiberationFonts/LiberationSans-Regular.ttf") - .setFontSize(28) - .setTranslation(25,15) - .setColor(1,0,0); - me.text_alt = nil; - me.sym = me.element.createChild("path"). - setStrokeLineWidth(4). - moveTo(-16,0). - arcSmallCW(16,16,0,32,0). - arcSmallCW(16,16,0,-32,0). - setColor(1,0,0); + me.text_wps = me.element.createChild("text", "dbg-text-" ~ me.model.id) + .setDrawMode( canvas.Text.TEXT ) + .setText(me.model.id) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") + .setFontSize(28) + .setTranslation(25,15) + .setColor(1,0,0); + me.text_alt = nil; + me.sym = me.element.createChild("path"). + setStrokeLineWidth(4). + moveTo(-16,0). + arcSmallCW(16,16,0,32,0). + arcSmallCW(16,16,0,-32,0). + setColor(1,0,0); } var draw = func{ diff --git a/Models/Instruments/ND/canvas/map/DECEL.lcontroller b/Models/Instruments/ND/canvas/map/DECEL.lcontroller index a4ec57a1..8a5d302a 100644 --- a/Models/Instruments/ND/canvas/map/DECEL.lcontroller +++ b/Models/Instruments/ND/canvas/map/DECEL.lcontroller @@ -6,32 +6,32 @@ var __self__ = caller(0)[0]; canvas.SymbolLayer.Controller.add(name, __self__); canvas.SymbolLayer.add(name, { - parents: [MultiSymbolLayer], - type: name, # Symbol type - df_controller: __self__, # controller to use by default -- this one - df_options : { # default configuration options - decel_node: "/autopilot/route-manager/vnav/decel/" - } + parents: [MultiSymbolLayer], + type: name, # Symbol type + df_controller: __self__, # controller to use by default -- this one + df_options : { # default configuration options + decel_node: "/autopilot/route-manager/vnav/decel/" + } }); var new = func(layer) { - var m = { - parents: [__self__], - layer: layer, - map: layer.map, - listeners: [], - }; - layer.searcher._equals = func(a,b) a.getName() == b.getName(); - return m; + var m = { + parents: [__self__], + layer: layer, + map: layer.map, + listeners: [], + }; + layer.searcher._equals = func(a,b) a.getName() == b.getName(); + return m; }; var del = func() { - foreach (var l; me.listeners) - removelistener(l); + foreach (var l; me.listeners) + removelistener(l); }; var searchCmd = func { - var results = []; - var symNode = props.globals.getNode(me.layer.options.decel_node); - if (symNode != nil and symNode.getValue('longitude-deg') != nil) - append(results, symNode); - return results; + var results = []; + var symNode = props.globals.getNode(me.layer.options.decel_node); + if (symNode != nil and symNode.getValue('longitude-deg') != nil) + append(results, symNode); + return results; } diff --git a/Models/Instruments/ND/canvas/map/DECEL.scontroller b/Models/Instruments/ND/canvas/map/DECEL.scontroller index 4e749b10..7d66482a 100644 --- a/Models/Instruments/ND/canvas/map/DECEL.scontroller +++ b/Models/Instruments/ND/canvas/map/DECEL.scontroller @@ -8,5 +8,5 @@ var new = func(model) ; # this controller doesn't need an instance var LayerController = canvas.SymbolLayer.Controller.registry[name]; var isActive = func(model) {return 1};#LayerController.a_instance.isActive(model); var query_range = func() - die(name~".scontroller.query_range /MUST/ be provided by implementation"); + die(name~".scontroller.query_range /MUST/ be provided by implementation"); #var model = props.globals.getNode('/position'); diff --git a/Models/Instruments/ND/canvas/map/DECEL.symbol b/Models/Instruments/ND/canvas/map/DECEL.symbol index cc39fd65..c0a65b20 100644 --- a/Models/Instruments/ND/canvas/map/DECEL.symbol +++ b/Models/Instruments/ND/canvas/map/DECEL.symbol @@ -12,21 +12,21 @@ canvas.DotSym.makeinstance( name, __self__ ); var element_type = "group"; var init = func { - var svg_path = me.getStyle('svg_path'); - if(svg_path == nil) - svg_path = get_local_path('res/airbus_decel.svg'); - me.decel_grp = me.element.createChild("group","decel"); - canvas.parsesvg(me.decel_grp, svg_path); - me.decel_grp.set('z-index', 5); + var svg_path = me.getStyle('svg_path'); + if(svg_path == nil) + svg_path = get_local_path('res/airbus_decel.svg'); + me.decel_grp = me.element.createChild("group","decel"); + canvas.parsesvg(me.decel_grp, svg_path); + me.decel_grp.set('z-index', 5); } var draw = func{ - if(me.decel_grp != nil){ - var spd_ctrl = getprop(me.options.spd_ctrl); - var spd_managed = (spd_ctrl == me.options.managed_val); - if(spd_managed) - me.decel_grp.setColor(me.style.managed_color); - else - me.decel_grp.setColor(me.style.selected_color); - } + if(me.decel_grp != nil){ + var spd_ctrl = getprop(me.options.spd_ctrl); + var spd_managed = (spd_ctrl == me.options.managed_val); + if(spd_managed) + me.decel_grp.setColor(me.style.managed_color); + else + me.decel_grp.setColor(me.style.selected_color); + } } diff --git a/Models/Instruments/ND/canvas/map/RTE.lcontroller b/Models/Instruments/ND/canvas/map/RTE.lcontroller index 7c4979d7..04dd5eab 100644 --- a/Models/Instruments/ND/canvas/map/RTE.lcontroller +++ b/Models/Instruments/ND/canvas/map/RTE.lcontroller @@ -12,9 +12,9 @@ SymbolLayer.add(name, { type: name, # Symbol type df_controller: __self__, # controller to use by default -- this one df_options: { # default configuration options - active_node: "/autopilot/route-manager/active", - current_wp_node: "/autopilot/route-manager/current-wp", - wp_num: "/autopilot/route-manager/route/num", + active_node: "/FMGC/flightplan[2]/active", + current_wp_node: "/FMGC/flightplan[2]/current-wp", + wp_num: "/FMGC/flightplan[2]/num", display_inactive_rte: 0 } }); @@ -74,12 +74,12 @@ var searchCmd = func { path = [{},{lon:leg.wp_lon, lat:leg.wp_lat}]; else path = leg.path(); - if(i == (fpSize - 1) and !discontinuity){# WORKAROUND FOR FG BUG - var ltype = leg.wp_type; - var path_l = size(path); - if(ltype != 'runway' and path_l >= 2) - path = subvec(path, 0, 1) ~ subvec(path, path_l - 1, 1); - } +# if(i == (fpSize - 1) and !discontinuity){# WORKAROUND FOR FG BUG -- we don't need it anymore (I think)! +# var ltype = leg.wp_type; +# var path_l = size(path); +# if(ltype != 'runway' and path_l >= 2) +# path = subvec(path, 0, 1) ~ subvec(path, path_l - 1, 1); +# } coords ~= path; discontinuity = driver.hasDiscontinuity(idx, leg); } diff --git a/Models/Instruments/ND/canvas/map/RTE.scontroller b/Models/Instruments/ND/canvas/map/RTE.scontroller index 7890370b..968becb8 100644 --- a/Models/Instruments/ND/canvas/map/RTE.scontroller +++ b/Models/Instruments/ND/canvas/map/RTE.scontroller @@ -8,5 +8,5 @@ var new = func(model) ; # this controller doesn't need an instance var LayerController = canvas.SymbolLayer.Controller.registry[name]; var isActive = func(model) {return 1};#LayerController.a_instance.isActive(model); var query_range = func() - die(name~".scontroller.query_range /MUST/ be provided by implementation"); + die(name~".scontroller.query_range /MUST/ be provided by implementation"); #var model = props.globals.getNode('/position'); diff --git a/Models/Instruments/ND/canvas/map/RWY-profile.symbol b/Models/Instruments/ND/canvas/map/RWY-profile.symbol index 41987a75..59ce331e 100644 --- a/Models/Instruments/ND/canvas/map/RWY-profile.symbol +++ b/Models/Instruments/ND/canvas/map/RWY-profile.symbol @@ -9,72 +9,72 @@ DotSym.makeinstance( name, __self__ ); var element_type = "group"; var style = { # style to use by default - zoom: 20, - color: [1,1,1], - center_line_len: 0.75, - line_width: 3 + zoom: 20, + color: [1,1,1], + center_line_len: 0.75, + line_width: 3 }; SymbolLayer.get(name).df_style = style; #var already_drawn = 0; var init = func { - #if(me.already_drawn) return; - var lat = me.model.lat; - var lon = me.model.lon; - var rwyhdg = me.model.heading; - var width = me.model.width; - var length = me.model.length; - var group = me.element; - var ctr_len = length * me.getStyle('center_line_len', 0.75); - var crds = []; - var coord = geo.Coord.new(); - width = width * me.getStyle('zoom', 20); # Else rwy is too thin to be visible - var line_w = me.getStyle('line_width', 3); - var color = me.getStyle('color', [1,1,1]); - coord.set_latlon(lat, lon); - coord.apply_course_distance(rwyhdg, -(ctr_len / 2)); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg, (ctr_len)); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - icon_rwy = group.createChild("path", "rwy-cl") - .setStrokeLineWidth(line_w) - .setDataGeo([2,4],crds) - .setColor(color); - #.setStrokeDashArray([10, 20, 10, 20, 10]); - #icon_rwy.hide(); - var crds = []; - coord.set_latlon(lat, lon); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg + 90, width/2); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg, length); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - icon_rwy = group.createChild("path", "rwy") - .setStrokeLineWidth(line_w) - .setDataGeo([2,4,4],crds) - .setColor(color); - var crds = []; - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg - 90, width); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg, -length); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - coord.apply_course_distance(rwyhdg + 90, width / 2); - append(crds,"N"~coord.lat()); - append(crds,"E"~coord.lon()); - icon_rwy = group.createChild("path", "rwy") - .setStrokeLineWidth(line_w) - .setDataGeo([2,4,4,4],crds) - .setColor(color); + #if(me.already_drawn) return; + var lat = me.model.lat; + var lon = me.model.lon; + var rwyhdg = me.model.heading; + var width = me.model.width; + var length = me.model.length; + var group = me.element; + var ctr_len = length * me.getStyle('center_line_len', 0.75); + var crds = []; + var coord = geo.Coord.new(); + width = width * me.getStyle('zoom', 20); # Else rwy is too thin to be visible + var line_w = me.getStyle('line_width', 3); + var color = me.getStyle('color', [1,1,1]); + coord.set_latlon(lat, lon); + coord.apply_course_distance(rwyhdg, -(ctr_len / 2)); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg, (ctr_len)); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + icon_rwy = group.createChild("path", "rwy-cl") + .setStrokeLineWidth(line_w) + .setDataGeo([2,4],crds) + .setColor(color); + #.setStrokeDashArray([10, 20, 10, 20, 10]); + #icon_rwy.hide(); + var crds = []; + coord.set_latlon(lat, lon); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg + 90, width/2); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg, length); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + icon_rwy = group.createChild("path", "rwy") + .setStrokeLineWidth(line_w) + .setDataGeo([2,4,4],crds) + .setColor(color); + var crds = []; + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg - 90, width); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg, -length); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + coord.apply_course_distance(rwyhdg + 90, width / 2); + append(crds,"N"~coord.lat()); + append(crds,"E"~coord.lon()); + icon_rwy = group.createChild("path", "rwy") + .setStrokeLineWidth(line_w) + .setDataGeo([2,4,4,4],crds) + .setColor(color); }; var draw = func{} diff --git a/Models/Instruments/ND/canvas/map/SPD-profile.lcontroller b/Models/Instruments/ND/canvas/map/SPD-profile.lcontroller index 65d08ad6..f4a6d392 100644 --- a/Models/Instruments/ND/canvas/map/SPD-profile.lcontroller +++ b/Models/Instruments/ND/canvas/map/SPD-profile.lcontroller @@ -5,47 +5,47 @@ var parents = [canvas.SymbolLayer.Controller]; var __self__ = caller(0)[0]; var _options = { # default configuration options - alts: [100,140,250,260,'wp'] + alts: [100,140,250,260,'wp'] }; canvas.SymbolLayer.Controller.add(name, __self__); canvas.SymbolLayer.add(name, { - parents: [MultiSymbolLayer], - type: name, # Symbol type - df_controller: __self__, # controller to use by default -- this one - df_options: _options + parents: [MultiSymbolLayer], + type: name, # Symbol type + df_controller: __self__, # controller to use by default -- this one + df_options: _options }); var new = func(layer) { - var m = { - parents: [__self__], - layer: layer, - #map: layer.map, - listeners: [], - }; - layer.searcher._equals = func(a,b) a.getName() == b.getName(); - #append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() )); - #m.addVisibilityListener(); + var m = { + parents: [__self__], + layer: layer, + #map: layer.map, + listeners: [], + }; + layer.searcher._equals = func(a,b) a.getName() == b.getName(); + #append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() )); + #m.addVisibilityListener(); - return m; + return m; }; var del = func() { - foreach (var l; me.listeners) - removelistener(l); + foreach (var l; me.listeners) + removelistener(l); }; var searchCmd = func { - var results = []; - var spdNode = props.globals.getNode(me.layer.options.spd_node); - if (spdNode != nil) { - var limits = spdNode.getChildren(); - foreach (var limit; limits) { - #t = 'spd-change-point' ~ '-' ~ alt; - #print('SPD-Controller, search for '~t); - #var n = spdNode.getNode(t); - if (limit != nil and limit.getValue('longitude-deg') != nil){ - #print('SPD-Controller -> Append'); - append(results, limit); - } - } - } - return results; + var results = []; + var spdNode = props.globals.getNode(me.layer.options.spd_node); + if (spdNode != nil) { + var limits = spdNode.getChildren(); + foreach (var limit; limits) { + #t = 'spd-change-point' ~ '-' ~ alt; + #print('SPD-Controller, search for '~t); + #var n = spdNode.getNode(t); + if (limit != nil and limit.getValue('longitude-deg') != nil){ + #print('SPD-Controller -> Append'); + append(results, limit); + } + } + } + return results; } diff --git a/Models/Instruments/ND/canvas/map/SPD-profile.scontroller b/Models/Instruments/ND/canvas/map/SPD-profile.scontroller index 191945db..018d3633 100644 --- a/Models/Instruments/ND/canvas/map/SPD-profile.scontroller +++ b/Models/Instruments/ND/canvas/map/SPD-profile.scontroller @@ -8,5 +8,5 @@ var new = func(model) ; # this controller doesn't need an instance var LayerController = canvas.SymbolLayer.Controller.registry[name]; var isActive = func(model) {return 1};#LayerController.a_instance.isActive(model); var query_range = func() - die(name~".scontroller.query_range /MUST/ be provided by implementation"); + die(name~".scontroller.query_range /MUST/ be provided by implementation"); #var model = props.globals.getNode('/position'); diff --git a/Models/Instruments/ND/canvas/map/SPD-profile.symbol b/Models/Instruments/ND/canvas/map/SPD-profile.symbol index deffbafe..96aefdff 100644 --- a/Models/Instruments/ND/canvas/map/SPD-profile.symbol +++ b/Models/Instruments/ND/canvas/map/SPD-profile.symbol @@ -32,9 +32,9 @@ var draw = func{ # var name = me.model.getName(); # var sym_group = me.element.getElementById(name); # sym_group.set('z-index', 5); - if(me.spd_sym == nil){ - me.spd_sym = me.getElementById("airbus-spd-sym"); - me.spd_sym.setTranslation(-24, -24).set('z-index', 5); - } - + if(me.spd_sym == nil){ + me.spd_sym = me.getElementById("airbus-spd-sym"); + me.spd_sym.setTranslation(-24, -24).set('z-index', 5); + } + } diff --git a/Models/Instruments/ND/canvas/map/VOR-airbus.lcontroller b/Models/Instruments/ND/canvas/map/VOR-airbus.lcontroller index 75290cc3..f254aacc 100644 --- a/Models/Instruments/ND/canvas/map/VOR-airbus.lcontroller +++ b/Models/Instruments/ND/canvas/map/VOR-airbus.lcontroller @@ -5,58 +5,58 @@ var parents = [SymbolLayer.Controller]; var __self__ = caller(0)[0]; SymbolLayer.Controller.add(name, __self__); SymbolLayer.add(name, { - parents: [NavaidSymbolLayer], - type: name, # Symbol type - df_controller: __self__, # controller to use by default -- this one - df_options: { - vor1_frq: 'instrumentation/nav[2]/frequencies/selected-mhz', - vor2_frq: 'instrumentation/nav[3]/frequencies/selected-mhz' - }, - df_style: { - scale: 1 - } + parents: [NavaidSymbolLayer], + type: name, # Symbol type + df_controller: __self__, # controller to use by default -- this one + df_options: { + vor1_frq: 'instrumentation/nav[2]/frequencies/selected-mhz', + vor2_frq: 'instrumentation/nav[3]/frequencies/selected-mhz' + }, + df_style: { + scale: 1 + } }); var new = func(layer) { - var m = { - parents: [__self__], - layer: layer, - map: layer.map, - active_vors: [], - navNs: props.globals.getNode("instrumentation").getChildren("nav"), - listeners: [], - query_type:'vor', - }; - setsize(m.active_vors, size(m.navNs)); - foreach (var navN; m.navNs) { - append(m.listeners, setlistener( - navN.getNode("frequencies/selected-mhz"), - func m.changed_freq() - )); - } - #call(debug.dump, keys(layer)); - m.changed_freq(update:0); - m.addVisibilityListener(); + var m = { + parents: [__self__], + layer: layer, + map: layer.map, + active_vors: [], + navNs: props.globals.getNode("instrumentation").getChildren("nav"), + listeners: [], + query_type:'vor', + }; + setsize(m.active_vors, size(m.navNs)); + foreach (var navN; m.navNs) { + append(m.listeners, setlistener( + navN.getNode("frequencies/selected-mhz"), + func m.changed_freq() + )); + } + #call(debug.dump, keys(layer)); + m.changed_freq(update:0); + m.addVisibilityListener(); - return m; + return m; }; var del = func() { - printlog(_MP_dbg_lvl, name,".lcontroller.del()"); - foreach (var l; me.listeners) - removelistener(l); + printlog(_MP_dbg_lvl, name,".lcontroller.del()"); + foreach (var l; me.listeners) + removelistener(l); }; # Controller methods var isActive = func(model) { - var my_freq = model.frequency/100; - foreach (var freq; me.active_vors) - if (freq == my_freq) return 1; - return 0; + var my_freq = model.frequency/100; + foreach (var freq; me.active_vors) + if (freq == my_freq) return 1; + return 0; }; var changed_freq = func(update=1) { - #debug.dump(me.active_vors); - foreach (var navN; me.navNs) - me.active_vors[ navN.getIndex() ] = navN.getValue("frequencies/selected-mhz"); - if (update) me.layer.update(); + #debug.dump(me.active_vors); + foreach (var navN; me.navNs) + me.active_vors[ navN.getIndex() ] = navN.getValue("frequencies/selected-mhz"); + if (update) me.layer.update(); }; var searchCmd = NavaidSymbolLayer.make('vor'); \ No newline at end of file diff --git a/Models/Instruments/ND/canvas/map/VOR-airbus.symbol b/Models/Instruments/ND/canvas/map/VOR-airbus.symbol index bdd8f7ca..4782fbb6 100644 --- a/Models/Instruments/ND/canvas/map/VOR-airbus.symbol +++ b/Models/Instruments/ND/canvas/map/VOR-airbus.symbol @@ -11,33 +11,33 @@ var svg_path = get_local_path('res/airbus_vor.svg'); var vor_sym = nil; var draw = func{ - if(me.vor_sym == nil) - me.vor_sym = me.element.getElementById("airbus-vor-sym"); - me.vor_sym.setTranslation(-24,-24); - if(me.text_vor == nil){ - var transl = me.getStyle('translation', [25,10]); - var text_color = me.getStyle('text_color', [1,1,1]); - me.text_vor = me.element.createChild("text") - .setDrawMode( canvas.Text.TEXT ) - .setText(me.model.id) - .setFont("LiberationFonts/LiberationSans-Regular.ttf") - .setFontSize(28) - .setColor(text_color) - .setTranslation(transl); - } - - var frq = me.model.frequency; - if(frq != nil){ - var dfcolor = me.getStyle('color', [0.9,0,0.47]); - var tuned_color = me.getStyle('tuned_color', [0,0.62,0.84]); - frq = frq / 100; - var vor1_frq = getprop(me.options.vor1_frq); - var vor2_frq = getprop(me.options.vor2_frq); - if(vor1_frq == frq or vor2_frq == frq){ - me.element.setColor(tuned_color); - } else { - me.element.setColor(dfcolor); - } - } - me.text_vor.setColor(me.getStyle('text_color', [1,1,1])); + if(me.vor_sym == nil) + me.vor_sym = me.element.getElementById("airbus-vor-sym"); + me.vor_sym.setTranslation(-24,-24); + if(me.text_vor == nil){ + var transl = me.getStyle('translation', [25,10]); + var text_color = me.getStyle('text_color', [1,1,1]); + me.text_vor = me.element.createChild("text") + .setDrawMode( canvas.Text.TEXT ) + .setText(me.model.id) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") + .setFontSize(28) + .setColor(text_color) + .setTranslation(transl); + } + + var frq = me.model.frequency; + if(frq != nil){ + var dfcolor = me.getStyle('color', [0.9,0,0.47]); + var tuned_color = me.getStyle('tuned_color', [0,0.62,0.84]); + frq = frq / 100; + var vor1_frq = getprop(me.options.vor1_frq); + var vor2_frq = getprop(me.options.vor2_frq); + if(vor1_frq == frq or vor2_frq == frq){ + me.element.setColor(tuned_color); + } else { + me.element.setColor(dfcolor); + } + } + me.text_vor.setColor(me.getStyle('text_color', [1,1,1])); } \ No newline at end of file diff --git a/Models/Instruments/ND/canvas/map/WPT-airbus.lcontroller b/Models/Instruments/ND/canvas/map/WPT-airbus.lcontroller index 2ca8d845..7f510dc4 100644 --- a/Models/Instruments/ND/canvas/map/WPT-airbus.lcontroller +++ b/Models/Instruments/ND/canvas/map/WPT-airbus.lcontroller @@ -6,132 +6,132 @@ var __self__ = caller(0)[0]; canvas.SymbolLayer.Controller.add(name, __self__); canvas.SymbolLayer.add(name, { - parents: [canvas.MultiSymbolLayer], - type: name, # Symbol type - df_controller: __self__, # controller to use by default -- this one - df_options: { # default configuration options - fix_symbol: func(group){ - group.createChild('path') - .moveTo(-10,0) - .lineTo(0,-17) - .lineTo(10,0) - .lineTo(0,17) - .close() - .setStrokeLineWidth(3) - .setColor(1,1,1) - .setScale(1,1); - }, - vor_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg', - airport_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_airport.svg', - ndb_symbol: func(group){ - group.createChild('path') - .moveTo(-15,15) - .lineTo(0,-15) - .lineTo(15,15) - .close() - .setStrokeLineWidth(3) - #.setColor(0.69,0,0.39) - #.setTranslation(-24, -24), - .setScale(1,1); - } - }, - df_style: { - active_wp_color: [0.4,0.7,0.4], - current_wp_color: [1,1,1], - translation: { - 'airport': [-24,-24], - 'vor': [-24,-24] - } - }, - toggle_cstr: 0 + parents: [canvas.MultiSymbolLayer], + type: name, # Symbol type + df_controller: __self__, # controller to use by default -- this one + df_options: { # default configuration options + fix_symbol: func(group){ + group.createChild('path') + .moveTo(-10,0) + .lineTo(0,-17) + .lineTo(10,0) + .lineTo(0,17) + .close() + .setStrokeLineWidth(3) + .setColor(1,1,1) + .setScale(1); + }, + vor_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg', + airport_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_airport.svg', + ndb_symbol: func(group){ + group.createChild('path') + .moveTo(-15,15) + .lineTo(0,-15) + .lineTo(15,15) + .close() + .setStrokeLineWidth(3) + #.setColor(0.69,0,0.39) + #.setTranslation(-24, -24), + .setScale(1,1); + } + }, + df_style: { + active_wp_color: [0.4,0.7,0.4], + current_wp_color: [1,1,1], + translation: { + 'airport': [-24,-24], + 'vor': [-24,-24] + } + }, + toggle_cstr: 0 }); var new = func(layer) { - var m = { - parents: [__self__], - layer: layer, - map: layer.map, - listeners: [], - }; - layer.searcher._equals = func(a,b) a.equals(b); - var driver = opt_member(m.layer.options, 'route_driver'); - if(driver == nil){ - driver = RouteDriver.new(); - } - var driver_listeners = driver.getListeners(); - foreach(var listener; driver_listeners){ - append(m.listeners, setlistener(listener, func m.layer.update())); - } - m.route_driver = driver; - return m; + var m = { + parents: [__self__], + layer: layer, + map: layer.map, + listeners: [], + }; + layer.searcher._equals = func(a,b) a.equals(b); + var driver = opt_member(m.layer.options, 'route_driver'); + if(driver == nil){ + driver = RouteDriver.new(); + } + var driver_listeners = driver.getListeners(); + foreach(var listener; driver_listeners){ + append(m.listeners, setlistener(listener, func m.layer.update())); + } + m.route_driver = driver; + return m; }; var del = func() { - foreach (var l; me.listeners) - removelistener(l); + foreach (var l; me.listeners) + removelistener(l); }; var WPTModel = { - new: func(fp, idx) { - var m = { parents:[WPTModel] }; - var wp = fp.getWP(idx); + new: func(fp, idx) { + var m = { parents:[WPTModel] }; + var wp = fp.getWP(idx); - m.id = wp.id; - m.name = wp.wp_name; - m.alt = wp.alt_cstr; - m.spd = wp.speed_cstr; - m.type = wp.wp_type; + m.id = wp.id; + m.name = wp.wp_name; + m.alt = wp.alt_cstr; + m.spd = wp.speed_cstr; + m.type = wp.wp_type; - (m.lat,m.lon) = (wp.wp_lat,wp.wp_lon); - var is_rwy = (m.type == 'runway'); - var id_len = size(m.id); - if(!is_rwy and id_len < 5){ - if(id_len == 4 and airportinfo(m.id) != nil) - m.navtype = 'airport'; - else { - var navaid = nil; - foreach(var t; ['vor', 'ndb']){ - navaid = navinfo(m.lat, m.lon, t, m.id); - if(navaid != nil and size(navaid)){ - m.navtype = t; - break; - } - } - if(navaid == nil or !size(navaid)) m.navtype = 'fix'; - } - } else { - m.navtype = (is_rwy ? 'rwy' : 'fix'); - } - - m.wp = wp; - idx = wp.index; - m.idx = idx; - m.is_departure = (idx == 0 and is_rwy); - m.is_destination = (idx > 0 and is_rwy); - return m; - }, - equals: func(other) { - # this is set on symbol init, so use this for equality... - me.name == other.name and me.alt == other.alt and - me.type == other.type and me.idx == other.idx and - me.navtype == other.navtype - }, + (m.lat,m.lon) = (wp.wp_lat,wp.wp_lon); + var is_rwy = (m.type == 'runway'); + var id_len = size(m.id); + if(!is_rwy and id_len < 5){ + if(id_len == 4 and airportinfo(m.id) != nil) + m.navtype = 'airport'; + else { + var navaid = nil; + foreach(var t; ['vor', 'ndb']){ + navaid = navinfo(m.lat, m.lon, t, m.id); + if(navaid != nil and size(navaid)){ + m.navtype = t; + break; + } + } + if(navaid == nil or !size(navaid)) m.navtype = 'fix'; + } + } else { + m.navtype = (is_rwy ? 'rwy' : 'fix'); + } + + m.wp = wp; + idx = wp.index; + m.idx = idx; + m.is_departure = (idx == 0 and is_rwy); + m.is_destination = (idx > 0 and is_rwy); + return m; + }, + equals: func(other) { + # this is set on symbol init, so use this for equality... + me.name == other.name and me.alt == other.alt and + me.type == other.type and me.idx == other.idx and + me.navtype == other.navtype + }, }; var searchCmd = func { - var driver = me.route_driver; - if(!driver.shouldUpdate()) return []; - driver.update(); - var result = []; - var planCount = driver.getNumberOfFlightPlans(); - for(var idx = 0; idx < planCount; idx += 1){ - var fp = driver.getFlightPlan(idx); - if(fp == nil) continue; - var fpSize = fp.getPlanSize(idx); - for (var i = 0; i < fpSize; i+=1){ - if(!driver.shouldUpdate()) return[]; - append(result, WPTModel.new(fp, i)); - } - } - return result; + var driver = me.route_driver; + if(!driver.shouldUpdate()) return []; + driver.update(); + var result = []; + var planCount = driver.getNumberOfFlightPlans(); + for(var idx = 0; idx < planCount; idx += 1){ + var fp = driver.getFlightPlan(idx); + if(fp == nil) continue; + var fpSize = fp.getPlanSize(idx); + for (var i = 0; i < fpSize; i+=1){ + if(!driver.shouldUpdate()) return[]; + append(result, WPTModel.new(fp, i)); + } + } + return result; } diff --git a/Models/Instruments/ND/canvas/map/WPT-airbus.symbol b/Models/Instruments/ND/canvas/map/WPT-airbus.symbol index 29f6fe26..439e8e1e 100644 --- a/Models/Instruments/ND/canvas/map/WPT-airbus.symbol +++ b/Models/Instruments/ND/canvas/map/WPT-airbus.symbol @@ -8,130 +8,130 @@ canvas.DotSym.makeinstance( name, __self__ ); var element_type = "group"; var init = func { - var name = me.model.name; - var alt = me.model.alt; - var spd = me.model.spd; - var wp_group = me.element; - me.alt_path = nil; + var name = me.model.name; + var alt = me.model.alt; + var spd = me.model.spd; + var wp_group = me.element; + me.alt_path = nil; - var colors = [ - 'wp_color', - 'current_wp_color', - 'constraint_color', - 'active_constraint_color', - 'missed_constraint_color' - ]; - foreach(col; colors){ - me[col] = me.getStyle(col, me.getOption(col)); - } + var colors = [ + 'wp_color', + 'current_wp_color', + 'constraint_color', + 'active_constraint_color', + 'missed_constraint_color' + ]; + foreach(col; colors){ + me[col] = me.getStyle(col, me.getOption(col)); + } - var idLen = size(me.model.id); - var draw_sym = nil; - var navtype = me.model.navtype; - if (navtype == nil) navtype = 'fix'; - if(navtype == 'airport') - draw_sym = me.options.airport_symbol; - elsif(navtype == 'vor') - draw_sym = me.options.vor_symbol; - elsif(navtype == 'ndb') - draw_sym = me.options.ndb_symbol; - else - draw_sym = me.options.fix_symbol; - me.wp_sym = me.element.createChild('group', 'wp-'~ me.model.idx); - if(typeof(draw_sym) == 'func') - draw_sym(me.wp_sym); - elsif(typeof(draw_sym) == 'scalar') - canvas.parsesvg(me.wp_sym, draw_sym); - var translation = me.getStyle('translation', {}); - if(contains(translation, navtype)){ - me.wp_sym.setTranslation(translation[navtype]); - } - me.text_wps = wp_group.createChild("text", "wp-text-" ~ me.model.idx) - .setDrawMode( canvas.Text.TEXT ) - .setText(me.model.name) - .setFont("LiberationFonts/LiberationSans-Regular.ttf") - .setFontSize(28) - .setTranslation(25,15) - .setColor(1,1,1); - me.text_alt = nil; - if(alt > 0 or spd > 0){ - var cstr_txt = "\n"; - if(alt > 0){ - if(alt > 10000) - cstr_txt ~= sprintf('FL%3.0f', int(alt / 100)); - else - cstr_txt ~= sprintf('%4.0f', int(alt)); - } - if(spd > 0){ - if(alt > 0) cstr_txt ~= "\n"; - if(spd <= 1) - cstr_txt ~= sprintf('%1.2fM', spd); - else - cstr_txt ~= sprintf('%3.0fKT', int(spd)); - } - me.text_alt = wp_group.createChild("text", "wp-alt-text-" ~ me.model.idx) - .setDrawMode( canvas.Text.TEXT ) - .setText(cstr_txt) - .setFont("LiberationFonts/LiberationSans-Regular.ttf") - .setFontSize(28) - .setTranslation(25,15); - } + var idLen = size(me.model.id); + var draw_sym = nil; + var navtype = me.model.navtype; + if (navtype == nil) navtype = 'fix'; + if(navtype == 'airport') + draw_sym = me.options.airport_symbol; + elsif(navtype == 'vor') + draw_sym = me.options.vor_symbol; + elsif(navtype == 'ndb') + draw_sym = me.options.ndb_symbol; + else + draw_sym = me.options.fix_symbol; + me.wp_sym = me.element.createChild('group', 'wp-'~ me.model.idx); + if(typeof(draw_sym) == 'func') + draw_sym(me.wp_sym); + elsif(typeof(draw_sym) == 'scalar') + canvas.parsesvg(me.wp_sym, draw_sym); + var translation = me.getStyle('translation', {}); + if(contains(translation, navtype)){ + me.wp_sym.setTranslation(translation[navtype]); + } + me.text_wps = wp_group.createChild("text", "wp-text-" ~ me.model.idx) + .setDrawMode( canvas.Text.TEXT ) + .setText(me.model.name) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") + .setFontSize(28) + .setTranslation(25,15) + .setColor(1,1,1); + me.text_alt = nil; + if(alt > 0 or spd > 0){ + var cstr_txt = "\n"; + if(alt > 0){ + if(alt > 10000) + cstr_txt ~= sprintf('FL%3d', int(alt / 100)); + else + cstr_txt ~= sprintf('%4d', int(alt)); + } + if(spd > 0){ + if(alt > 0) cstr_txt ~= "\n"; + if(spd <= 1) + cstr_txt ~= sprintf('%4.2fM', spd); + else + cstr_txt ~= sprintf('%3dKT', int(spd)); + } + me.text_alt = wp_group.createChild("text", "wp-alt-text-" ~ me.model.idx) + .setDrawMode( canvas.Text.TEXT ) + .setText(cstr_txt) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") + .setFontSize(28) + .setTranslation(25,15); + } } var draw = func{ - var wp_group = me.element; - var alt = me.model.alt; - var i = me.model.idx; - var vnav_actv = getprop(me.options.ver_ctrl) == me.options.managed_val; - var curwp = getprop(me.options.current_wp); - if(alt > 0){ - var wp_d = me.model.wp.distance_along_route; - var lvl_off_at = getprop(me.options.level_off_alt); - if(lvl_off_at == nil) lvl_off_at = 0; - if(me.alt_path == nil){ - me.alt_path = wp_group.createChild("path"). - setStrokeLineWidth(4). - moveTo(-22,0). - arcSmallCW(22,22,0,44,0). - arcSmallCW(22,22,0,-44,0); - } - if(vnav_actv){ - if(lvl_off_at and (lvl_off_at - wp_d) > 0.5 and curwp == i) - me.alt_path.setColor(me.missed_constraint_color); - else - me.alt_path.setColor(me.active_constraint_color); - } - else - me.alt_path.setColor(me.constraint_color); - if(me.layer.toggle_cstr) - me.alt_path.show(); - else - me.alt_path.hide(); - } else { - if(me.alt_path != nil) me.alt_path.hide(); - } - wp_group.set("z-index",4); - #var sym = me.element.getElementById('wp-' ~ me.model.idx); - if(alt > 0 and me.text_alt != nil){ - if(vnav_actv) - me.text_alt.setColor(me.active_constraint_color); - else - me.text_alt.setColor(me.constraint_color); - } - if(i == curwp) { - me.wp_sym.setColor(me.current_wp_color); - me.text_wps.setColor(me.current_wp_color); - } else { - me.wp_sym.setColor(me.wp_color); - me.text_wps.setColor(me.wp_color); - } - if(me.model.is_departure or me.model.is_destination){ - var prop = (me.model.is_departure ? 'departure' : 'destination'); - var rwy = getprop("/autopilot/route-manager/"~prop~"/runway"); - if(rwy != nil and size(rwy) > 0){ - me.wp_sym.hide(); - } else { - me.wp_sym.show(); - } - } + var wp_group = me.element; + var alt = me.model.alt; + var i = me.model.idx; + var vnav_actv = getprop(me.options.ver_ctrl) == me.options.managed_val; + var curwp = getprop(me.options.current_wp); + if(alt > 0){ + var wp_d = me.model.wp.distance_along_route; + var lvl_off_at = getprop(me.options.level_off_alt); + if(lvl_off_at == nil) lvl_off_at = 0; + if(me.alt_path == nil){ + me.alt_path = wp_group.createChild("path"). + setStrokeLineWidth(4). + moveTo(-22,0). + arcSmallCW(22,22,0,44,0). + arcSmallCW(22,22,0,-44,0); + } + if(vnav_actv){ + if(lvl_off_at and (lvl_off_at - wp_d) > 0.5 and curwp == i) + me.alt_path.setColor(me.missed_constraint_color); + else + me.alt_path.setColor(me.active_constraint_color); + } + else + me.alt_path.setColor(me.constraint_color); + if(me.layer.toggle_cstr) + me.alt_path.show(); + else + me.alt_path.hide(); + } else { + if(me.alt_path != nil) me.alt_path.hide(); + } + wp_group.set("z-index",4); + #var sym = me.element.getElementById('wp-' ~ me.model.idx); + if(alt > 0 and me.text_alt != nil){ + if(vnav_actv) + me.text_alt.setColor(me.active_constraint_color); + else + me.text_alt.setColor(me.constraint_color); + } + if(i == curwp) { + me.wp_sym.setColor(me.current_wp_color); + me.text_wps.setColor(me.current_wp_color); + } else { + me.wp_sym.setColor(me.wp_color); + me.text_wps.setColor(me.wp_color); + } + if(me.model.is_departure or me.model.is_destination){ + var prop = (me.model.is_departure ? 'departure' : 'destination'); + var rwy = getprop("/autopilot/route-manager/"~prop~"/runway"); + if(rwy != nil and size(rwy) > 0){ + me.wp_sym.hide(); + } else { + me.wp_sym.show(); + } + } } diff --git a/Models/Instruments/ND/canvas/style.nas b/Models/Instruments/ND/canvas/style.nas index 7c452162..25d6a4f0 100644 --- a/Models/Instruments/ND/canvas/style.nas +++ b/Models/Instruments/ND/canvas/style.nas @@ -46,12 +46,12 @@ canvas.NDStyles["Airbus"] = { # that the lateral flight mode is managed. # You can easily override these options before creating the ND, example: # canvas.NDStyles["Airbus"].options.defaults.fplan_active = "my/autpilot/f-plan/active" - fplan_active: "autopilot/route-manager/active", + fplan_active: "/FMGC/flightplan[2]/active", lat_ctrl: "/it-autoflight/output/lat", managed_val: 1, ver_ctrl: "/it-autoflight/output/vert", spd_ctrl: "/flight-management/control/spd-ctrl", - current_wp: "/autopilot/route-manager/current-wp", + current_wp: "/FMGC/flightplan[2]/current-wp", ap1: "/it-autoflight/output/ap1", ap2: "/it-autoflight/output/ap2", nav1_frq: "/instrumentation/nav[0]/frequencies/selected-mhz", @@ -740,11 +740,11 @@ canvas.NDStyles["Airbus"] = { id: "wpActiveId", impl: { init: func(nd,symbol), - predicate: func(nd) getprop("/autopilot/route-manager/wp/id") != nil and - getprop("autopilot/route-manager/active") and + predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg") != nil and + getprop("FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), is_true: func(nd) { - nd.symbols.wpActiveId.setText(getprop("/autopilot/route-manager/wp/id")); + nd.symbols.wpActiveId.setText(getprop("/FMGC/flightplan[2]/current-leg")); nd.symbols.wpActiveId.show(); }, is_false: func(nd) nd.symbols.wpActiveId.hide(), @@ -754,12 +754,16 @@ canvas.NDStyles["Airbus"] = { id: "wpActiveCrs", impl: { init: func(nd,symbol), - predicate: func(nd) getprop("/autopilot/route-manager/wp/id") != nil and - getprop("autopilot/route-manager/active") and + predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg") != nil and + getprop("FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), is_true: func(nd) { #var cur_wp = getprop("autopilot/route-manager/current-wp"); - var deg = int(getprop("/autopilot/route-manager/wp/bearing-deg")); + if (nd.get_switch("toggle_true_north")) { + var deg = math.round(getprop("/FMGC/flightplan[2]/current-leg-course")); + } else { + var deg = math.round(getprop("/FMGC/flightplan[2]/current-leg-course-mag")); + } nd.symbols.wpActiveCrs.setText((deg or "")~"°"); nd.symbols.wpActiveCrs.show(); }, @@ -770,11 +774,11 @@ canvas.NDStyles["Airbus"] = { id: "wpActiveDist", impl: { init: func(nd,symbol), - predicate: func(nd) getprop("/autopilot/route-manager/wp/dist") != nil and - getprop("autopilot/route-manager/active") and + predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg-dist") != nil and + getprop("FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), is_true: func(nd) { - var dst = getprop("/autopilot/route-manager/wp/dist"); + var dst = getprop("/FMGC/flightplan[2]/current-leg-dist"); nd.symbols.wpActiveDist.setText(sprintf("%3.01f",dst)); nd.symbols.wpActiveDist.show(); }, @@ -785,10 +789,10 @@ canvas.NDStyles["Airbus"] = { id: "wpActiveDistLbl", impl: { init: func(nd,symbol), - predicate: func(nd) getprop("/autopilot/route-manager/wp/dist") != nil and getprop("autopilot/route-manager/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), + predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg-dist") != nil and getprop("FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), is_true: func(nd) { nd.symbols.wpActiveDistLbl.show(); - if(getprop("/autopilot/route-manager/wp/dist") > 1000) + if(getprop("/FMGC/flightplan[2]/current-leg-dist") > 1000) nd.symbols.wpActiveDistLbl.setText(" NM"); }, is_false: func(nd) nd.symbols.wpActiveDistLbl.hide(), @@ -798,7 +802,7 @@ canvas.NDStyles["Airbus"] = { id: "eta", impl: { init: func(nd,symbol), - predicate: func(nd) getprop("autopilot/route-manager/wp/eta") != nil and getprop("autopilot/route-manager/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), + predicate: func(nd) getprop("autopilot/route-manager/wp/eta") != nil and getprop("FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]), is_true: func(nd) { var etaSec = getprop("/sim/time/utc/day-seconds")+ getprop("autopilot/route-manager/wp/eta-seconds"); @@ -1679,7 +1683,7 @@ canvas.NDStyles["Airbus"] = { init: func(nd,symbol), predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and !nd.get_switch("toggle_centered")), is_true: func(nd){ - var active = getprop("autopilot/route-manager/active"); + var active = getprop("FMGC/flightplan[2]/active"); var lat_ctrl = getprop(nd.options.defaults.lat_ctrl); var managed_v = nd.options.defaults.managed_val; var is_managed = (lat_ctrl == managed_v); @@ -1708,7 +1712,7 @@ canvas.NDStyles["Airbus"] = { init: func(nd,symbol), predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and !nd.get_switch("toggle_centered")), is_true: func(nd){ - var active = getprop("autopilot/route-manager/active"); + var active = getprop("FMGC/flightplan[2]/active"); var lat_ctrl = getprop(nd.options.defaults.lat_ctrl); var managed_v = nd.options.defaults.managed_val; var is_managed = (lat_ctrl == managed_v); @@ -1737,7 +1741,7 @@ canvas.NDStyles["Airbus"] = { init: func(nd,symbol), predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and nd.get_switch("toggle_centered")), is_true: func(nd){ - var active = getprop("autopilot/route-manager/active"); + var active = getprop("FMGC/flightplan[2]/active"); var lat_ctrl = getprop(nd.options.defaults.lat_ctrl); var managed_v = nd.options.defaults.managed_val; var is_managed = (lat_ctrl == managed_v); @@ -1766,7 +1770,7 @@ canvas.NDStyles["Airbus"] = { init: func(nd,symbol), predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and nd.get_switch("toggle_centered")), is_true: func(nd){ - var active = getprop("autopilot/route-manager/active"); + var active = getprop("FMGC/flightplan[2]/active"); var lat_ctrl = getprop(nd.options.defaults.lat_ctrl); var managed_v = nd.options.defaults.managed_val; var is_managed = (lat_ctrl == managed_v); @@ -1795,7 +1799,7 @@ canvas.NDStyles["Airbus"] = { init: func(nd,symbol), predicate: func(nd) (nd.in_mode("toggle_display_mode", ["MAP", "PLAN"])), is_true: func(nd){ - var active = getprop("autopilot/route-manager/active"); + var active = getprop("FMGC/flightplan[2]/active"); var lat_ctrl = getprop(nd.options.defaults.lat_ctrl); var managed_v = nd.options.defaults.managed_val; var is_managed = (lat_ctrl == managed_v); diff --git a/Nasal/FMGC/FMGC-b.nas b/Nasal/FMGC/FMGC-b.nas index f7b8be0e..a8817970 100644 --- a/Nasal/FMGC/FMGC-b.nas +++ b/Nasal/FMGC/FMGC-b.nas @@ -48,10 +48,10 @@ var Radio = { }; var FPLN = { - active: props.globals.getNode("/autopilot/route-manager/active", 1), + active: props.globals.getNode("/FMGC/flightplan[2]/active", 1), activeTemp: 0, currentCourse: 0, - currentWP: props.globals.getNode("/autopilot/route-manager/current-wp", 1), + currentWP: props.globals.getNode("/FMGC/flightplan[2]/current-wp", 1), currentWPTemp: 0, deltaAngle: 0, deltaAngleRad: 0, @@ -59,12 +59,12 @@ var FPLN = { maxBank: 0, maxBankLimit: 0, nextCourse: 0, - num: props.globals.getNode("/autopilot/route-manager/route/num", 1), + num: props.globals.getNode("/FMGC/flightplan[2]/num", 1), numTemp: 0, R: 0, radius: 0, turnDist: 0, - wp0Dist: props.globals.getNode("/autopilot/route-manager/wp/dist", 1), + wp0Dist: props.globals.getNode("/FMGC/flightplan[2]/current-leg-dist", 1), wpFlyFrom: 0, wpFlyTo: 0, }; @@ -406,12 +406,12 @@ var ITAF = { if (FPLN.wpFlyFrom < 0) { FPLN.wpFlyFrom = 0; } - FPLN.currentCourse = getprop("/autopilot/route-manager/route/wp[" ~ FPLN.wpFlyFrom ~ "]/leg-bearing-true-deg"); # Best left at getprop + FPLN.currentCourse = getprop("/FMGC/flightplan[2]/wp[" ~ FPLN.wpFlyFrom ~ "]/course"); # Best left at getprop FPLN.wpFlyTo = FPLN.currentWPTemp + 1; if (FPLN.wpFlyTo < 0) { FPLN.wpFlyTo = 0; } - FPLN.nextCourse = getprop("/autopilot/route-manager/route/wp[" ~ FPLN.wpFlyTo ~ "]/leg-bearing-true-deg"); # Best left at getprop + FPLN.nextCourse = getprop("/FMGC/flightplan[2]/wp[" ~ FPLN.wpFlyTo ~ "]/course"); # Best left at getprop FPLN.maxBankLimit = Internal.bankLimit.getValue(); FPLN.deltaAngle = math.abs(geo.normdeg180(FPLN.currentCourse - FPLN.nextCourse)); @@ -433,7 +433,11 @@ var ITAF = { Internal.lnavAdvanceNm.setValue(FPLN.turnDist); if (FPLN.wp0Dist.getValue() <= FPLN.turnDist) { - FPLN.currentWP.setValue(FPLN.currentWPTemp + 1); + if (currentWP[2] < 1) { + currentWP[2] = 1; + } else if (num_out[2].getValue() > 2) { # The Airbus doesn't display anything past the previous waypoint after advancing + flightplan.advanceDelete(2); + } } } } @@ -649,7 +653,10 @@ var ITAF = { Text.vert.setValue("ALT CAP"); } else if (n == 4) { # FLCH Output.apprArm.setBoolValue(0); - if (abs(Input.altDiff) >= 125) { # SPD CLB or SPD DES + Output.vert.setValue(1); + Internal.alt.setValue(Input.alt.getValue()); + Internal.altDiff = Internal.alt.getValue() - Position.indicatedAltitudeFt.getValue(); + if (abs(Internal.altDiff) >= 250) { # SPD CLB or SPD DES if (Input.alt.getValue() >= Position.indicatedAltitudeFt.getValue()) { # Usually set Thrust Mode Selector, but we do it now due to timer lag Text.vert.setValue("SPD CLB"); } else { diff --git a/Nasal/FMGC/FMGC.nas b/Nasal/FMGC/FMGC.nas index 8b983ef8..a01452ea 100644 --- a/Nasal/FMGC/FMGC.nas +++ b/Nasal/FMGC/FMGC.nas @@ -148,24 +148,6 @@ var trimReset = func { } } -############### -# MCDU Inputs # -############### - -var updateARPT = func { - dep = getprop("/FMGC/internal/dep-arpt"); - arr = getprop("/FMGC/internal/arr-arpt"); - setprop("/autopilot/route-manager/departure/airport", dep); - setprop("/autopilot/route-manager/destination/airport", arr); - if (getprop("/autopilot/route-manager/active") != 1) { - fgcommand("activate-flightplan", props.Node.new({"activate": 1})); - } -} - -setlistener("/FMGC/internal/cruise-ft", func { - setprop("/autopilot/route-manager/cruise/altitude-ft", getprop("/FMGC/internal/cruise-ft")); -}); - ############################ # Flight Phase and Various # ############################ @@ -248,7 +230,7 @@ var masterFMGC = maketimer(0.2, func { setprop("/FMGC/status/phase", "5"); } - if (getprop("/autopilot/route-manager/route/num") > 0 and getprop("/autopilot/route-manager/active") == 1 and getprop("/autopilot/route-manager/distance-remaining-nm") <= 15) { + if (getprop("/FMGC/flightplan[2]/num") > 0 and getprop("/FMGC/flightplan[2]/active") == 1 and getprop("/FMGC/flightplan[2]/arrival-leg-dist") <= 15) { setprop("/FMGC/internal/decel", 1); } else if (getprop("/FMGC/internal/decel") == 1 and (phase == 0 or phase == 6)) { setprop("/FMGC/internal/decel", 0); @@ -302,6 +284,7 @@ var reset_FMGC = func { alt = getprop("/it-autoflight/input/alt"); ITAF.init(); FMGCinit(); + flightplan.reset(); mcdu.MCDU_reset(0); mcdu.MCDU_reset(1); setprop("/it-autoflight/input/fd1", fd1); diff --git a/Nasal/FMGC/flightplan.nas b/Nasal/FMGC/flightplan.nas new file mode 100644 index 00000000..19d9a7a8 --- /dev/null +++ b/Nasal/FMGC/flightplan.nas @@ -0,0 +1,314 @@ +# A3XX FMGC Flightplan Driver + +# Copyright (c) 2019 Joshua Davidson (Octal450) +# This thing replaces the Route Manager, it's far from finished though + +# 0 = TEMP FP Captain MCDU +# 1 = TEMP FP First Officer MCDU +# 2 = ACTIVE FP +var fp = [createFlightplan(), createFlightplan(), createFlightplan()]; +var wpDep = nil; +var wpArr = nil; +var pos = nil; +var geoPos = nil; +var geoPosPrev = geo.Coord.new(); +var currentLegCourseDist = nil; +var courseDistanceFrom = nil; +var courseDistanceFromPrev = nil; +var sizeWP = nil; +var magTrueError = 0; +var arrivalAirportI = [0, 0, 0]; + +# Vars for MultiFlightplan +var currentWP = [nil, nil, 0]; +var currentLeg = [nil, nil, ""]; + +# Create/Fetch props.nas for MultiFlightplan +var altFeet = props.globals.getNode("/instrumentation/altimeter/indicated-altitude-ft", 1); +var active_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/active", 0, "BOOL")]; +var currentWP_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/current-wp", 0, "INT")]; +var currentLeg_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/current-leg", "", "STRING")]; +var currentLegCourse_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/current-leg-course", 0, "DOUBLE")]; +var currentLegDist_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/current-leg-dist", 0, "DOUBLE")]; +var currentLegCourseMag_out = [nil, nil, props.globals.initNode("/FMGC/flightplan[2]/current-leg-course-mag", 0, "DOUBLE")]; +var arrivalLegDist_out = [props.globals.initNode("/FMGC/flightplan[0]/arrival-leg-dist", 0, "DOUBLE"), props.globals.initNode("/FMGC/flightplan[1]/arrival-leg-dist", 0, "DOUBLE"), props.globals.initNode("/FMGC/flightplan[2]/arrival-leg-dist", 0, "DOUBLE")]; +var num_out = [props.globals.initNode("/FMGC/flightplan[0]/num", 0, "INT"), props.globals.initNode("/FMGC/flightplan[1]/num", 0, "INT"), props.globals.initNode("/FMGC/flightplan[2]/num", 0, "INT")]; +var toFromSet = props.globals.initNode("/FMGC/internal/tofrom-set", 0, "BOOL"); +var magHDG = props.globals.getNode("/orientation/heading-magnetic-deg", 1); +var trueHDG = props.globals.getNode("/orientation/heading-deg", 1); +var FMGCdep = props.globals.getNode("/FMGC/internal/dep-arpt", 1); +var FMGCarr = props.globals.getNode("/FMGC/internal/arr-arpt", 1); +var TMPYActive = [props.globals.initNode("/FMGC/internal/tmpy-active[0]", 0, "BOOL"), props.globals.initNode("/FMGC/internal/tmpy-active[1]", 0, "BOOL")]; + +# Create props.nas for flightplan +# Vectors inside vectors, so we can use as many flightplans or waypoints as we want +var wpID = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/id", "", "STRING")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/id", "", "STRING")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/id", "", "STRING")]]; +var wpLat = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/lat", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/lat", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/lat", 0, "DOUBLE")]]; +var wpLon = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/lon", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/lon", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/lon", 0, "DOUBLE")]]; +var wpCourse = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/course", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/course", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/course", 0, "DOUBLE")]]; +var wpDistance = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/distance", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/distance", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/distance", 0, "DOUBLE")]]; +var wpCoursePrev = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/course-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/course-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/course-from-prev", 0, "DOUBLE")]]; +var wpDistancePrev = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/distance-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/distance-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/distance-from-prev", 0, "DOUBLE")]]; + +var flightplan = { + reset: func() { + TMPYActive[0].setBoolValue(0); + TMPYActive[1].setBoolValue(0); + me.reset0(); + me.reset1(); + me.reset2(); + }, + reset0: func() { + fp[0].cleanPlan(); + fp[0].departure = nil; + fp[0].destination = nil; + }, + reset1: func() { + fp[1].cleanPlan(); + fp[1].departure = nil; + fp[1].destination = nil; + }, + reset2: func() { + fp[2].cleanPlan(); + fp[2].departure = nil; + fp[2].destination = nil; + currentWP[2] = 0; + currentLeg[2] = ""; + }, + initTempFP: func(f, n) { # f is temp, n is active + fp[f] = fp[n].clone(); + TMPYActive[f].setBoolValue(1); + me.checkWPOutputs(f); + }, + eraseTempFP: func(f, n) { # f is temp, n is active + TMPYActive[f].setBoolValue(0); + if (f == 0) { + me.reset0(); + } else if (f == 1) { + me.reset1(); + } + me.checkWPOutputs(n); + }, + executeTempFP: func(f, n) { # f is temp, n is active + fp[n] = fp[f].clone(); + TMPYActive[f].setBoolValue(0); + if (f == 0) { + me.reset0(); + } else if (f == 1) { + me.reset1(); + } + me.checkWPOutputs(n); + }, + advanceDelete: func(n) { + if (num_out[n].getValue() > 2) { + if (TMPYActive[0].getBoolValue() and wpID[0][0] == wpID[n][0]) { + me.deleteWP(0, 0); + } + if (TMPYActive[1].getBoolValue() and wpID[1][0] == wpID[n][0]) { + me.deleteWP(0, 1); + } + me.deleteWP(0, n, 1); + } + }, + updateARPT: func(dep, arr, n) { + if (n == 2) { # Which flightplan? + me.reset2(); + + # Set Departure ARPT + if (dep != nil) { + fp[2].departure = airportinfo(dep); + } else { + fp[2].departure = nil; + } + + # Set Arrival ARPT + if (arr != nil) { + fp[2].destination = airportinfo(arr); + } else { + fp[2].destination = nil; + } + + currentWP[2] = 0; + } + + me.checkWPOutputs(n); + }, + # return 1 will cause NOT IN DATABASE, return 2 will cause NOT ALLOWED + insertFix: func(wp, i, n) { + var pos = findFixesByID(wp); + if (i == 0) { + return 2; + } else if (pos != nil and size(pos) > 0) { + fp[n].insertWP(createWPFrom(pos[0]), i); + me.checkWPOutputs(n); + return 0; + } else { + return 1; + } + }, + insertArpt: func(wp, i, n) { + var pos = findAirportsByICAO(wp); + if (i == 0) { + return 2; + } else if (pos != nil and size(pos) > 0) { + fp[n].insertWP(createWPFrom(pos[0]), i); + me.checkWPOutputs(n); + return 0; + } else { + return 1; + } + }, + insertNavaid: func(nav, i, n) { + var pos = findNavaidsByID(nav); + if (i == 0) { + return 2; + } else if (pos != nil and size(pos) > 0) { + fp[n].insertWP(createWPFrom(pos[0]), i); + me.checkWPOutputs(n); + return 0; + } else { + return 1; + } + }, + insertPPOS: func(n) { + fp[n].insertWP(createWP(geo.aircraft_position(), "PPOS"), 0); + me.checkWPOutputs(n); + }, + insertTP: func(n) { + fp[n].insertWP(createWP(geo.aircraft_position(), "T/P"), 0); + me.checkWPOutputs(n); + }, + deleteWP: func(i, n, t) { + var wp = wpID[n][i].getValue(); + if (t == 1) { + fp[n].deleteWP(i); + me.outputProps(); # Make sure everything is updated before we update the MCDUs. + me.updateMCDUDriver(n); + canvas_nd.A3XXRouteDriver.triggerSignal("fp-removed"); + return 0; + } else { + if (i == 0) { + return 2; + } else if (fp[n].getPlanSize() > 2 and wp != FMGCdep.getValue() and wp != FMGCarr.getValue() and wp != "T/P" and wp != "PPOS") { + fp[n].deleteWP(i); + me.outputProps(); # Make sure everything is updated before we update the MCDUs. + me.updateMCDUDriver(n); + canvas_nd.A3XXRouteDriver.triggerSignal("fp-removed"); + return 0; + } else { + return 2; + } + } + }, + checkWPOutputs: func(n) { + sizeWP = size(wpID[n]); + for (var counter = sizeWP; counter < fp[n].getPlanSize(); counter += 1) { + append(wpID[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/id", "", "STRING")); + append(wpLat[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/lat", 0, "DOUBLE")); + append(wpLon[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/lon", 0, "DOUBLE")); + append(wpCourse[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/course", 0, "DOUBLE")); + append(wpDistance[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/distance", 0, "DOUBLE")); + append(wpCoursePrev[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/course-from-prev", 0, "DOUBLE")); + append(wpDistancePrev[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/distance-from-prev", 0, "DOUBLE")); + } + me.outputProps(); # Make sure everything is updated before we update the MCDUs. + me.updateMCDUDriver(n); + canvas_nd.A3XXRouteDriver.triggerSignal("fp-added"); # Update the NDs + }, + updateMCDUDriver: func(n) { + for (var i = 0; i < 2; i += 1) { # Update the 2 MCDUs + if (TMPYActive[i].getBoolValue()) { + mcdu.FPLNLines[i].replacePlan(i, mcdu.TMPY, mcdu.FPLNLines[i].index); + } else { + mcdu.FPLNLines[i].replacePlan(2, mcdu.MAIN, mcdu.FPLNLines[i].index); + } + } + }, + outputProps: func() { + geoPos = geo.aircraft_position(); + + for (var n = 0; n < 3; n += 1) { # Note: Some things don't get done for TMPY (0) hence all the if (n > 1) {} + if (((n == 0 and TMPYActive[0].getBoolValue()) or (n == 1 and TMPYActive[1].getBoolValue()) or n > 1) and toFromSet.getBoolValue() and fp[n].departure != nil and fp[n].destination != nil) { + if (n > 1) { + if (currentWP[n] > fp[n].getPlanSize()) { + currentWP[n] = fp[n].getPlanSize(); + } + + if (active_out[n].getBoolValue() != 1) { + active_out[n].setBoolValue(1); + } + + currentLeg[n] = fp[n].getWP(currentWP[n]).wp_name; + + if (currentLeg_out[n].getValue() != currentLeg[n]) { + currentLeg_out[n].setValue(currentLeg[n]); + } + + currentLegCourseDist = fp[n].getWP(currentWP[n]).courseAndDistanceFrom(geoPos); + currentLegCourse_out[n].setValue(currentLegCourseDist[0]); + currentLegDist_out[n].setValue(currentLegCourseDist[1]); + + magTrueError = magHDG.getValue() - trueHDG.getValue(); + currentLegCourseMag_out[n].setValue(currentLegCourseDist[0] + magTrueError); # Convert to Magnetic + } + + if (num_out[n].getValue() != fp[n].getPlanSize()) { + num_out[n].setValue(fp[n].getPlanSize()); + } + + for (var i = 0; i < fp[n].getPlanSize(); i += 1) { + wpID[n][i].setValue(fp[n].getWP(i).wp_name); + wpLat[n][i].setValue(fp[n].getWP(i).wp_lat); + wpLon[n][i].setValue(fp[n].getWP(i).wp_lon); + courseDistanceFrom = fp[n].getWP(i).courseAndDistanceFrom(geoPos); + wpCourse[n][i].setValue(courseDistanceFrom[0]); + wpDistance[n][i].setValue(courseDistanceFrom[1]); + + if (i > 0) { # Impossible to do from the first WP + geoPosPrev.set_latlon(fp[n].getWP(i - 1).lat, fp[n].getWP(i - 1).lon, altFeet.getValue() * 0.3048); + courseDistanceFromPrev = fp[n].getWP(i).courseAndDistanceFrom(geoPosPrev); + wpCoursePrev[n][i].setValue(courseDistanceFromPrev[0]); + wpDistancePrev[n][i].setValue(courseDistanceFromPrev[1]); + } else { # So if its the first WP, we just use current position instead + wpCoursePrev[n][i].setValue(courseDistanceFrom[0]); + wpDistancePrev[n][i].setValue(courseDistanceFrom[1]); + } + + if (wpID[n][i].getValue() == FMGCarr.getValue()) { + arrivalAirportI[n] = i; + } + } + + arrivalLegDist_out[n].setValue(wpDistance[n][arrivalAirportI[n]].getValue()); + } else { + if (n > 1) { + if (active_out[n].getBoolValue() != 0) { + active_out[n].setBoolValue(0); + } + + if (currentLeg_out[n].getValue() != "") { + currentLeg_out[n].setValue(""); + } + } + + if (num_out[n].getValue() != 0) { + num_out[n].setValue(0); + } + } + + if (n > 1) { + if (currentWP[n] != nil) { + if (currentWP_out[n].getValue() != currentWP[n]) { + currentWP_out[n].setValue(currentWP[n]); + } + } else { + if (currentWP_out[n].getValue() != 0) { + currentWP_out[n].setValue(0); + } + } + } + } + }, +}; + +var outputPropsTimer = maketimer(0.1, flightplan.outputProps); diff --git a/Nasal/MCDU/F-PLN.nas b/Nasal/MCDU/F-PLN.nas new file mode 100644 index 00000000..3e841584 --- /dev/null +++ b/Nasal/MCDU/F-PLN.nas @@ -0,0 +1,536 @@ +# Airbus A3XX FMGC MCDU Bridge + +# Copyright (c) 2019 Joshua Davidson (Octal450) and Nikolai V. Chr. (Necolatis) + +# Lowercase "g" is a degree symbol in the MCDU font. + +var TMPY = 5; +var MAIN = 6; +var debug = 0; # Set to 1 to check inner functionality +var insertReturn = nil; +var active_out = [nil, nil, props.globals.getNode("/FMGC/flightplan[2]/active")]; +var num_out = [props.globals.getNode("/FMGC/flightplan[0]/num"), props.globals.getNode("/FMGC/flightplan[1]/num"), props.globals.getNode("/FMGC/flightplan[2]/num")]; +var TMPYActive = [props.globals.getNode("/FMGC/internal/tmpy-active[0]"), props.globals.getNode("/FMGC/internal/tmpy-active[1]")]; + +var clearFPLNComputer = func { + FPLNLines[0].clear(); + FPLNLines[1].clear(); +} + +var StaticText = { + new: func(computer, type) { + var in = {parents:[StaticText]}; + in.type = type; + in.computer = computer; + return in; + }, + getText: func() { + if (me.type == "discontinuity") { + return "---F-PLN DISCONTINUITY--"; + } else if (me.type == "fplnEnd") { + return "------END OF F-PLN------"; + } else if (me.type == "altnFplnEnd") { + return "----END OF ALTN F-PLN---"; + } else if (me.type == "noAltnFpln") { + return "------NO ALTN F-PLN-----"; + } else if (me.type == "empty") { + return ""; + } + }, + getColor: func() { + return canvas_mcdu.WHITE; + }, + getSubText: func() { + return ""; + }, + type: nil, + pushButtonLeft: func() { + notAllowed(me.computer.mcdu); + }, + pushButtonRight: func() { + notAllowed(me.computer.mcdu); + }, +}; + +var FPLNText = { + new: func(computer, wp, dest, fp, wpIndex) { + var in = {parents:[FPLNText]}; + in.wp = wp; + in.dest = dest; + in.fp = fp; + in.index = wpIndex; + in.computer = computer; + return in; + }, + getText: func() { + return me.wp.wp_name; + }, + getColor: func(i) { + if (TMPYActive[i].getBoolValue()) { + if (me.dest) { + return canvas_mcdu.WHITE; + } else { + return canvas_mcdu.YELLOW; + } + } else { + if (me.dest) { + return canvas_mcdu.WHITE; + } else { + return canvas_mcdu.GREEN; + } + } + }, + getSubText: func(i) { + if (me.index == 0) { + return ""; + } else if (TMPYActive[i].getBoolValue()) { + if (fmgc.arrivalAirportI[i] == me.index) { + return "DEST"; + } else { + return "C" ~ sprintf("%03d", fmgc.wpCoursePrev[me.fp][me.index].getValue()) ~ "g"; + } + } else { + if (fmgc.arrivalAirportI[2] == me.index) { + return "DEST"; + } else { + return "C" ~ sprintf("%03d", fmgc.wpCoursePrev[me.fp][me.index].getValue()) ~ "g"; + } + } + }, + wp: nil, + pushButtonLeft: func() { + var scratchpad = getprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad"); + if (me.computer.lines == MAIN and scratchpad != "") { + fmgc.flightplan.initTempFP(me.computer.mcdu, 2); + } + if (scratchpad == "CLR") { + if (fmgc.flightplan.deleteWP(me.index, me.computer.mcdu, 0) != 0) { + notAllowed(me.computer.mcdu); + } else { + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad-msg", 0); + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad", ""); + } + } else { + if (size(scratchpad) == 5) { + var insertReturn = fmgc.flightplan.insertFix(scratchpad, me.index, me.computer.mcdu); + if (insertReturn == 2) { + notAllowed(me.computer.mcdu); + } else if (insertReturn == 1) { + notInDataBase(me.computer.mcdu); + } else { + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad", ""); + } + } else if (size(scratchpad) == 4) { + var insertReturn = fmgc.flightplan.insertArpt(scratchpad, me.index, me.computer.mcdu); + if (insertReturn == 2) { + notAllowed(me.computer.mcdu); + } else if (insertReturn == 1) { + notInDataBase(me.computer.mcdu); + } else { + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad", ""); + } + } else if (size(scratchpad) == 3 or size(scratchpad) == 2) { + var insertReturn = fmgc.flightplan.insertNavaid(scratchpad, me.index, me.computer.mcdu); + if (insertReturn == 2) { + notAllowed(me.computer.mcdu); + } else if (insertReturn == 1) { + notInDataBase(me.computer.mcdu); + } else { + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/scratchpad", ""); + } + } else if (size(scratchpad) == 1) { + formatError(me.computer.mcdu); + } else { + if (me.getText() == fmgc.fp[2].departure.id) { + if (canvas_mcdu.myLatRev != nil) { + canvas_mcdu.myLatRev.del(); + } + canvas_mcdu.myLatRev = nil; + canvas_mcdu.myLatRev = latRev.new(0, me.getText()); + } elsif (me.index == fmgc.arrivalAirportI[2]) { + if (canvas_mcdu.myLatRev != nil) { + canvas_mcdu.myLatRev.del(); + } + canvas_mcdu.myLatRev = nil; + canvas_mcdu.myLatRev = latRev.new(1, me.getText()); + } elsif (me.index == fmgc.currentWP[2]) { + if (canvas_mcdu.myLatRev != nil) { + canvas_mcdu.myLatRev.del(); + } + canvas_mcdu.myLatRev = nil; + canvas_mcdu.myLatRev = latRev.new(2, me.getText()); + } else { + if (canvas_mcdu.myLatRev != nil) { + canvas_mcdu.myLatRev.del(); + } + canvas_mcdu.myLatRev = nil; + canvas_mcdu.myLatRev = latRev.new(3, me.getText()); + } + setprop("/MCDU[" ~ me.computer.mcdu ~ "]/page", "LATREV"); + } + } + }, + pushButtonRight: func() { + notAllowed(me.computer.mcdu); + }, +}; + +var FPLNLineComputer = { + new: func(mcdu) { + var in = {parents:[FPLNLineComputer]}; + in.mcdu = mcdu; + in.planEnd = StaticText.new(in, "fplnEnd"); + in.planNoAlt = StaticText.new(in, "noAltnFpln"); + if (debug == 1) printf("%d: Line computer created.", in.mcdu); + return in; + }, + index: 0, + planList: [], + destination: nil, + destIndex: nil, + planEnd: nil, + planNoAlt: nil, + lines: nil, + output: [], + mcdu: nil, + fplnID: nil, + enableScroll: 0, + clear: func() { + me.planList = []; + me.destIndex = -1; + me.destination = nil; + me.index = 0; + me.output = []; + me.enableScroll = 0; + if (me.lines == nil) { + me.lines = MAIN; + } + me.updateScroll(); + }, + replacePlan: func(fplnID, lines, firstLineIndex) { + # Here you set another plan, do this when changing plan on display or when destination changes + if (debug == 1) printf("%d: replacePlan called for %d lines and firstLine %d", me.mcdu, lines, firstLineIndex); + var fpln = nil; + + me.planList = []; + + if (!fmgc.active_out[2].getBoolValue()) { + me.destIndex = -1; + me.destination = nil; + } else { + fpln = fmgc.fp[fplnID]; # Get the Nasal Flightplan + me.destIndex = fmgc.arrivalAirportI[fplnID]; + me.destination = FPLNText.new(me, fpln.getWP(me.destIndex), 1, fplnID, me.destIndex); + for (var j = 0; j < fpln.getPlanSize(); j += 1) { + me.dest = 0; + if (j == me.destIndex) { + me.dest = 1; + } + append(me.planList, FPLNText.new(me, fpln.getWP(j), me.dest, fplnID, j)); + } + if (debug == 1) printf("%d: dest is: %s", me.mcdu, fpln.getWP(me.destIndex).wp_name); + } + me.index = firstLineIndex; + me.lines = lines; + me.initScroll(); + }, + initScroll: func() { + me.maxItems = size(me.planList) + 2; # + 2 is for end of plan line and altn end of plan. + me.enableScroll = me.lines < me.maxItems; + me.checkIndex(); + if (debug == 1) printf("%d: scroll is %d. Size of plan is %d", me.mcdu, me.enableScroll, size(me.planList)); + me.updateScroll(); + }, + checkIndex: func() { + if (!me.enableScroll) { + me.index = 0; + if (debug == 1) printf("%d: index forced to 0",me.mcdu); + } elsif (me.index > size(me.planList) + 2 - me.lines) { + me.index = size(me.planList) + 2 - me.lines; + if (debug == 1) printf("%d: index forced to %d",me.mcdu,me.index); + } + }, + scrollDown: func() { # Scroll Up in Thales Manual + if (debug == 1) printf("%d: scroll down", me.mcdu); + me.extra = 1; + if (!me.enableScroll) { + me.index = 0; + } else { + me.index += 1; + if (me.index > size(me.planList) + 2 - me.lines) { + me.index = 0; + } + } + me.updateScroll(); + }, + scrollUp: func() { # Scroll Down in Thales Manual + if (debug == 1) printf("%d: scroll up", me.mcdu); + me.extra = 1; + if (!me.enableScroll) { + me.index = 0; + } else { + me.index -= 1; + if (me.index < 0) { + me.index = size(me.planList) + 2 - me.lines; + } + } + me.updateScroll(); + }, + updateScroll: func() { + me.output = []; + if (me.index <= size(me.planList) + 1) { + var i = 0; + me.realIndex = me.index - 1; + if (debug == 1) printf("%d: updating display from index %d", me.mcdu, me.realIndex); + for (i = me.index; i < math.min(size(me.planList), me.index + 5); i += 1) { + append(me.output, me.planList[i]); + me.realIndex = i; + } + if (debug == 1) printf("%d: populated until wp index %d", me.mcdu,me.realIndex); + if (me.realIndex < me.destIndex and me.lines == MAIN) { + # Destination has not been shown yet, now its time (if we show 6 lines) + append(me.output, me.destination); + if (debug == 1) printf("%d: added dest at bottom for total of %d lines", me.mcdu, size(me.output)); + return; + } else if (size(me.output) < me.lines) { + for (i = me.realIndex + 1; size(me.output) < me.lines and i < size(me.planList); i += 1) { + append(me.output, me.planList[i]); + me.realIndex = i; + } + if (debug == 1) printf("%d: populated after until wp index %d", me.mcdu,me.realIndex); + if (size(me.output) < me.lines) { + if (me.realIndex == size(me.planList)-1) { + # Show the end of plan + append(me.output, me.planEnd); + me.realIndex += 1; + if (debug == 1) printf("%d: added end, wp index=%d", me.mcdu, me.realIndex); + } + if (size(me.output) < me.lines and (me.realIndex == size(me.planList))) { + append(me.output, me.planNoAlt); + me.realIndex += 1; + if (debug == 1) printf("%d: added no-alt, wp index=%d", me.mcdu,me.realIndex); + if (me.enableScroll and size(me.output) < me.lines) { + # We start wrapping + for (var j = 0; size(me.output) < me.lines; j += 1) { + append(me.output, me.planList[j]); + } + } + } + } + } + } + while (size(me.output) < me.lines) { + append(me.output, StaticText.new(me, "empty")); + } + if (debug == 1) printf("%d: %d lines", me.mcdu, size(me.output)); + }, +}; + +var FPLNLines = [FPLNLineComputer.new(0), FPLNLineComputer.new(1)]; +clearFPLNComputer(); # Just in case, we have it in the clear state. + +var slewFPLN = func(d, i) { # Scrolling function. d is -1 or 1 for direction, and i is instance. + if (d == 1) { + FPLNLines[i].scrollDown(); # Scroll Up in Thales Manual + } else if (d == -1) { + FPLNLines[i].scrollUp(); # Scroll Down in Thales Manual + } +} + +# Button and Inputs +var FPLNButton = func(s, key, i) { + var scratchpad = getprop("/MCDU[" ~ i ~ "]/scratchpad"); + if (s == "L") { + if (key == 6 and TMPYActive[i].getBoolValue()) { + fmgc.flightplan.eraseTempFP(i, 2); + } else { + if (size(FPLNLines[i].output) >= key) { + FPLNLines[i].output[key - 1].pushButtonLeft(); + } + } + } else if (s == "R") { + if (key == 6 and TMPYActive[i].getBoolValue()) { + fmgc.flightplan.executeTempFP(i, 2); + } else { +# if (scratchpad != "") { +# if (size(FPLNLines[i].output) >= key) { +# FPLNLines[i].output[key - 1].pushButtonRight(); +# } +# } else { + notAllowed(i); # Remove when has functionality + # FIXME: Add VERT REV Logic +# } + } + } +} + +var notInDataBase = func(i) { + if (getprop("/MCDU[" ~ i ~ "]/scratchpad-msg") == 1) { # Messages clear after NOT IN DATABASE + setprop("/MCDU[" ~ i ~ "]/last-scratchpad", "NOT IN DATABASE"); + } else { + setprop("/MCDU[" ~ i ~ "]/last-scratchpad", getprop("/MCDU[" ~ i ~ "]/scratchpad")); + } + setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 1); + setprop("/MCDU[" ~ i ~ "]/scratchpad", "NOT IN DATABASE"); +} + +# For testing purposes only -- do not touch! +var test = func { + var fp = createFlightplan(getprop("sim/aircraft-dir")~"/plan.gpx"); + var desti = int(fp.getPlanSize()*0.5); + FPLNLines[0].replacePlan(fp,6,desti,0); + print("Display:"); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("down");FPLNLines[0].scrollDown(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } + print("up");FPLNLines[0].scrollUp(); + foreach(line;FPLNLines[0].output) { + printf("line: %s",line.getText()); + } +} + +#test(); diff --git a/Nasal/MCDU/INITA.nas b/Nasal/MCDU/INITA.nas index 82aed56b..b88a759c 100644 --- a/Nasal/MCDU/INITA.nas +++ b/Nasal/MCDU/INITA.nas @@ -70,10 +70,11 @@ var initInputA = func(key, i) { } } else if (key == "R1") { if (scratchpad == "CLR") { + clearFPLNComputer(); setprop("/FMGC/internal/dep-arpt", ""); setprop("/FMGC/internal/arr-arpt", ""); setprop("/FMGC/internal/tofrom-set", 0); - fmgc.updateARPT(); + fmgc.flightplan.reset(); setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 0); setprop("/MCDU[" ~ i ~ "]/scratchpad", ""); } else { @@ -87,7 +88,7 @@ var initInputA = func(key, i) { setprop("/FMGC/internal/arr-arpt", fromto[1]); setprop("/FMGC/internal/tofrom-set", 1); setprop("/MCDU[" ~ i ~ "]/scratchpad", ""); - fmgc.updateARPT(); + fmgc.flightplan.updateARPT(fromto[0], fromto[1], 2); } else { notAllowed(i); } diff --git a/Nasal/MCDU/LATREV.nas b/Nasal/MCDU/LATREV.nas new file mode 100644 index 00000000..309e7e39 --- /dev/null +++ b/Nasal/MCDU/LATREV.nas @@ -0,0 +1,98 @@ +var latRev = { + title: [nil, nil, nil], + subtitle: [nil, nil], + fontMatrix: [[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]], + arrowsMatrix: [[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]], + L1: [nil, nil, "ack"], # content, title, colour + L2: [nil, nil, "ack"], + L3: [nil, nil, "ack"], + L4: [nil, nil, "ack"], + L5: [nil, nil, "ack"], + L6: [nil, nil, "ack"], + R1: [nil, nil, "ack"], + R2: [nil, nil, "ack"], + R3: [nil, nil, "ack"], + R4: [nil, nil, "ack"], + R5: [nil, nil, "ack"], + R6: [nil, nil, "ack"], + depAirport: nil, + arrAirport: nil, + new: func(type, id) { + var lr = {parents:[latRev]}; + lr.type = type; # 0 = origin 1 = destination 2 = ppos (from waypoint) 3 = generic wpt + lr.id = id; + lr._setupPageWithData(); + return lr; + }, + del: func() { + return nil; + }, + _setupPageWithData: func() { + if (me.type == 2) { + me.title = ["LAT REV", " FROM ", "PPOS"]; + me.L2 = [" OFFSET", nil, "wht"]; + me.L3 = [" HOLD", nil, "wht"]; + me.L6 = [" RETURN", nil, "wht"]; + me.R1 = ["FIX INFO ", nil, "wht"]; + me.R2 = ["[ ]°/[ ]°/[ ]", "LL XING/INCR/NO", "blu"]; + me.arrowsMatrix = [[0, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0]]; + me.fontMatrix = [[0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0]]; + } else { + me.title = ["LAT REV", " FROM ", me.id]; + + if (me.type == 0) { + me.depAirport = findAirportsByICAO(me.id); + me.subtitle = [dmsToString(sprintf(me.depAirport[0].lat), "lat"), dmsToString(sprintf(me.depAirport[0].lon), "lon")]; + me.L1 = [" DEPARTURE", nil, "wht"]; + me.L2 = [" OFFSET", nil, "wht"]; + me.L6 = [" RETURN", nil, "wht"]; + me.R1 = ["FIX INFO ", nil, "wht"]; + me.R2 = ["[ ]°/[ ]°/[ ]", "LL XING/INCR/NO", "blu"]; + me.R3 = ["[ ]", "NEXT WPT ", "blu"]; + me.R4 = ["[ ]", "NEW DEST", "blu"]; + me.arrowsMatrix = [[1, 1, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0]]; + me.fontMatrix = [[0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0]]; + } elsif (me.type == 1) { + me.arrAirport = findAirportsByICAO(me.id); + me.subtitle = [dmsToString(sprintf(me.arrAirport[0].lat), "lat"), dmsToString(sprintf(me.arrAirport[0].lon), "lon")]; + me.L3 = [" ALTN", nil, "wht"]; + me.L4 = [" ALTN", "ENABLE", "blu"]; + me.L6 = [" RETURN", nil, "wht"]; + me.R1 = ["ARRIVAL ", nil, "wht"]; + me.R3 = ["[ ]", "NEXT WPT ", "blu"]; + me.arrowsMatrix = [[0, 0, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0]]; + me.fontMatrix = [[0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0]]; + } elsif (me.type == 3) { + if (size(me.id) == 2 or size(me.id) == 3) { + me.wpt = findNavaidsByID(me.id); + } elsif (size(me.id) == 4) { + me.wpt = findAirportsByICAO(me.id); + } elsif (size(me.id) == 5) { + me.wpt = findFixesByID(me.id); + } + me.subtitle = [dmsToString(sprintf(me.wpt[0].lat), "lat"), dmsToString(sprintf(me.wpt[0].lon), "lon")]; + me.L3 = [" HOLD", nil, "wht"]; + me.L4 = [" ALTN", "ENABLE", "blu"]; + me.L6 = [" RETURN", nil, "wht"]; + me.R1 = ["FIX INFO ", nil, "wht"]; + me.R3 = ["[ ]", "NEXT WPT ", "blu"]; + me.R4 = ["[ ]", "NEW DEST", "blu"]; + me.R5 = ["AIRWAYS ", nil, "wht"]; + me.arrowsMatrix = [[0, 0, 1, 1, 0, 1], [1, 0, 0, 0, 1, 0]]; + me.fontMatrix = [[0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0]]; + } + } + }, +}; + +var dmsToString = func(dms, type) { + var decimalSplit = split(".", dms); + var degrees = decimalSplit[0]; + var minutes = decimalSplit[1] * 60; + if (type == "lat") { + var sign = degrees >= 0 ? "N" : "S"; + } else { + var sign = degrees >= 0 ? "E" : "W"; + } + return degrees ~ "g" ~ minutes ~ " " ~ sign; +} \ No newline at end of file diff --git a/Nasal/MCDU/MCDU.nas b/Nasal/MCDU/MCDU.nas index 134eaea8..62c094fd 100644 --- a/Nasal/MCDU/MCDU.nas +++ b/Nasal/MCDU/MCDU.nas @@ -96,53 +96,59 @@ var lskbutton = func(btn, i) { setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 0); } } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("L1",i); + perfTOInput("L1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("L1",i); + radnavInput("L1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DATA") { - dataInput("L1",i); + dataInput("L1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("L1",i); + printInput("L1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L1",i); + printInput2("L1", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 1, i); } else { notAllowed(i); } } else if (btn == "2") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - PerfInput("L2",i); + PerfInput("L2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("L2",i); + perfTOInput("L2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("L2",i); + radnavInput("L2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CLB") { - initInputA("L5",i); # Does the same thing as on the INIT page + initInputA("L5", i); # Does the same thing as on the INIT page } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CRZ") { - initInputA("L5",i); + initInputA("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DES") { - initInputA("L5",i); + initInputA("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DATA") { - dataInput("L2",i); + dataInput("L2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("L2",i); + printInput("L2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L2",i); + printInput2("L2", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 2, i); } else { notAllowed(i); } } else if (btn == "3") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("L3",i); + initInputA("L3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("L3",i); + perfTOInput("L3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "STATUS") { - statusInput("L3",i); + statusInput("L3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("L3",i); + radnavInput("L3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("L3",i); + printInput("L3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L3",i); + printInput2("L3", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 3, i); } else { notAllowed(i); } @@ -150,45 +156,53 @@ var lskbutton = func(btn, i) { if (getprop("/MCDU[" ~ i ~ "]/page") == "DATA") { setprop("/MCDU[" ~ i ~ "]/page", "STATUS"); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("L4",i); + perfTOInput("L4", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("L4",i); + radnavInput("L4", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L4",i); + printInput2("L4", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 4, i); } else { notAllowed(i); } } else if (btn == "5") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("L5",i); + initInputA("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("L5",i); + perfTOInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CLB") { - perfCLBInput("L5",i); + perfCLBInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CRZ") { - perfCRZInput("L5",i); + perfCRZInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DES") { - perfDESInput("L5",i); + perfDESInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("L5",i); + radnavInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("L5",i); + printInput("L5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L5",i); + printInput2("L5", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 5, i); } else { notAllowed(i); } } else if (btn == "6") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("L6",i); + initInputA("L6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CLB") { - perfCLBInput("L6",i); + perfCLBInput("L6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CRZ") { - perfCRZInput("L6",i); + perfCRZInput("L6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DES") { - perfDESInput("L6",i); + perfDESInput("L6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("L6",i); + printInput2("L6", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("L", 6, i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "LATREV") { + setprop("/MCDU[" ~ i ~ "]/page", "F-PLNA"); } else { notAllowed(i); } @@ -202,59 +216,59 @@ var lskbutton_b = func(btn, i) { var rskbutton = func(btn, i) { if (btn == "1") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("R1",i); + initInputA("R1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "INITB") { - initInputB("R1",i); + initInputB("R1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("R1",i); + radnavInput("R1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("R1",i); + printInput("R1", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("R1",i); + printInput2("R1", i); } else { notAllowed(i); } } else if (btn == "2") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITB") { - initInputB("R2",i); + initInputB("R2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("R2",i); + radnavInput("R2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("R2",i); + printInput("R2", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("R2",i); + printInput2("R2", i); } else { notAllowed(i); } } else if (btn == "3") { if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("R3",i); + initInputA("R3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("R3",i); + perfTOInput("R3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") { - printInput("R3",i); + printInput("R3", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("R3",i); + printInput2("R3", i); } else { notAllowed(i); } } else if (btn == "4") { if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("R4",i); + perfTOInput("R4", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("R4",i); + radnavInput("R4", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2") { - printInput2("R4",i); + printInput2("R4", i); } else { notAllowed(i); } } else if (btn == "5") { if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("R5",i); + perfTOInput("R5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "RADNAV") { - radnavInput("R5",i); + radnavInput("R5", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "DATA") { - dataInput("R5",i); + dataInput("R5", i); } else { notAllowed(i); } @@ -268,11 +282,11 @@ var rskbutton = func(btn, i) { notAllowed(i); } } else if (getprop("/MCDU[" ~ i ~ "]/page") == "TO") { - perfTOInput("R6",i); + perfTOInput("R6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CLB") { - perfCLBInput("R6",i); + perfCLBInput("R6", i); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "CRZ") { - perfCRZInput("R6",i); + perfCRZInput("R6", i); } else if ((getprop("/MCDU[" ~ i ~ "]/page") == "DATA") or (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC") or (getprop("/MCDU[" ~ i ~ "]/page") == "PRINTFUNC2")) { if (getprop("/MCDU[" ~ i ~ "]/scratchpad") != "AOC DISABLED") { if (getprop("/MCDU[" ~ i ~ "]/scratchpad-msg") == 1) { @@ -284,7 +298,9 @@ var rskbutton = func(btn, i) { setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 1); setprop("/MCDU[" ~ i ~ "]/scratchpad", "AOC DISABLED"); } else if (getprop("/MCDU[" ~ i ~ "]/page") == "INITA") { - initInputA("R6",i); + initInputA("R6", i); + } else if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + FPLNButton("R", 6, i); } else { notAllowed(i); } @@ -333,9 +349,13 @@ var arrowbutton = func(btn, i) { setprop("/MCDU[" ~ i ~ "]/page", "PRINTFUNC"); } } else if (btn == "up") { - # Nothing for now + if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + slewFPLN(1, i); + } } else if (btn == "down") { - # Nothing for now + if (getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNA" or getprop("/MCDU[" ~ i ~ "]/page") == "F-PLNB") { + slewFPLN(-1, i); + } } } @@ -363,7 +383,12 @@ var pagebutton = func(btn, i) { setprop("/MCDU[" ~ i ~ "]/scratchpad", "SELECT DESIRED SYSTEM"); setprop("/MCDU[" ~ i ~ "]/page", "MCDU"); } else if (btn == "f-pln") { - setprop("/MCDU[" ~ i ~ "]/page", "F-PLNA"); + if (active_out[2].getBoolValue()) { + setprop("/MCDU[" ~ i ~ "]/page", "F-PLNA"); + } else { + setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 1); + setprop("/MCDU[" ~ i ~ "]/scratchpad", "ERROR. INITIALIZE ROUTE"); # Should be ERROR:, but the : character doesn't show in our MCDU font right now... + } } else if (btn == "fuel-pred") { setprop("/MCDU[" ~ i ~ "]/page", "FUELPRED"); } @@ -534,6 +559,18 @@ var notAllowed = func(i) { setprop("/MCDU[" ~ i ~ "]/scratchpad", "NOT ALLOWED"); } +var formatError = func(i) { + if (getprop("/MCDU[" ~ i ~ "]/scratchpad") != "FORMAT ERROR") { + if (getprop("/MCDU[" ~ i ~ "]/scratchpad-msg") == 1) { + setprop("/MCDU[" ~ i ~ "]/last-scratchpad", ""); + } else { + setprop("/MCDU[" ~ i ~ "]/last-scratchpad", getprop("/MCDU[" ~ i ~ "]/scratchpad")); + } + } + setprop("/MCDU[" ~ i ~ "]/scratchpad-msg", 1); + setprop("/MCDU[" ~ i ~ "]/scratchpad", "FORMAT ERROR"); +} + var screenFlash = func(time, i) { var page = getprop("/MCDU[" ~ i ~ "]/page"); setprop("/MCDU[" ~ i ~ "]/page", "NONE"); diff --git a/Nasal/Sim/libraries.nas b/Nasal/Sim/libraries.nas index 3a0737c8..26b21ac2 100644 --- a/Nasal/Sim/libraries.nas +++ b/Nasal/Sim/libraries.nas @@ -205,6 +205,7 @@ var systemsInit = func { systems.eng_init(); systems.fire_init(); systems.autobrake_init(); + fmgc.flightplan.reset(); fadec.FADEC.init(); fmgc.ITAF.init(); fmgc.FMGCinit(); diff --git a/Systems/fmgc-drivers.xml b/Systems/fmgc-drivers.xml index 16346fac..97a13834 100644 --- a/Systems/fmgc-drivers.xml +++ b/Systems/fmgc-drivers.xml @@ -449,7 +449,7 @@ - /autopilot/route-manager/wp[0]/true-bearing-deg + /FMGC/flightplan[2]/current-leg-course /it-autoflight/internal/drift-angle-deg -1.0