diff --git a/nasal_builtin.h b/nasal_builtin.h index 642c67d..12b455a 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -208,12 +208,13 @@ int nasal_runtime::builtin_finput(int local_scope_addr) if(!fin.fail()) while(!fin.eof()) { - file_content.push_back(fin.get()); + char c=fin.get(); if(fin.eof()) break; + file_content.push_back(c); } else - file_content="cannot open file named \'"+filename+"\'."; + file_content=""; fin.close(); int ret_addr=nasal_vm.gc_alloc(); nasal_vm.gc_get(ret_addr).set_type(vm_string); @@ -347,10 +348,10 @@ int nasal_runtime::builtin_rand(int local_scope_addr) } int nasal_runtime::builtin_id(int local_scope_addr) { - int value_addr=in_builtin_find("id"); + int value_addr=in_builtin_find("thing"); if(value_addr<0) { - std::cout<<">> [runtime] builtin_id: cannot find \"id\".\n"; + std::cout<<">> [runtime] builtin_id: cannot find \"thing\".\n"; ++error; return -1; } diff --git a/nasal_gc.h b/nasal_gc.h index bdfc36c..36ba61e 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -286,6 +286,8 @@ int nasal_hash::get_value_address(std::string key) } } } + else + std::cout<<">> [runtime] cannot find hash member \""<=0) { nasal_vm.add_reference(last_call_hash_addr); run_closure.add_new_value("me",last_call_hash_addr); } + else if(func_name.length()) + { + // when hash.me does not exist,set self + nasal_vm.add_reference(base_value_addr); + run_closure.add_new_value(func_name,base_value_addr); + } nasal_ast& argument_format=reference_of_func.get_arguments(); if(!node.get_children().size()) { diff --git a/test/NasNeuron.nas b/test/NasNeuron.nas new file mode 100644 index 0000000..ae2a951 --- /dev/null +++ b/test/NasNeuron.nas @@ -0,0 +1,96 @@ +# NasNeuron lib written by ValKmjolnir + +# Basic Class NasMatrix +# NasMatGen : generate a new matrix +# NasMatAdd : add two matrixes +# NasMatSub : sub two matrixes +# NasMatMul : multiply two matrix +# NasMatTrans: transpose a matrix +# NasMatPrt : print a matrix +var NasMatrix= +{ + NasMatGen:func(row,col) + { + var GenMat={Row:row,Col:col,Elem:[]}; + for(var i=0;i0.7)); +} + +var prt=func() +{ + var s=""; + for(var i=0;i<10;i+=1) + { + for(var j=0;j<10;j+=1) + s~=map[i][j]; + s~='\n'; + } + print(s); +} + +var bfs=func(begin,end) +{ + var move=[[1,0],[0,1],[-1,0],[0,-1]]; + var queue=new_queue(); + queue_push(queue,begin); + map[begin[0]][begin[1]]=3; + while(!queue_empty(queue)) + { + var vertex=queue_front(queue); + queue_pop(queue); + foreach(var i;move) + { + var x=vertex[0]+i[0]; + var y=vertex[1]+i[1]; + if(x==end[0] and y==end[1]) + { + map[x][y]='*'; + return; + } + if(0<=x and x<10 and 0<=y and y<10 and map[x][y]==0) + { + queue_push(queue,[x,y]); + map[x][y]=3; + } + } + prt(); + } + print("cannot reach."); + return; +} + +prt(); +var x=num(input()); +var y=num(input()); +var begin=[x,y]; +x=num(input()); +y=num(input()); +var end=[x,y]; +bfs(begin,end); +prt(); \ No newline at end of file diff --git a/test/choice.nas b/test/choice.nas new file mode 100644 index 0000000..2f9dcec --- /dev/null +++ b/test/choice.nas @@ -0,0 +1,29 @@ + +var condition_true=1; +var condition_false=0; +if(condition_true) +{ + var a=1; +} +else if(!condition_false) +{ + var b=1; +} +elsif(!condition_true and condition_false) +{ + print("impossible"); +} +else +{ + var c=1; + var d=1; +} + +if(condition_true) + var a=1; +else if(!condition_false) + var b=1; +elsif(!condition_true and condition_false) + print("impossible"); +else + var c=1; \ No newline at end of file diff --git a/test/efb.nas b/test/efb.nas new file mode 100644 index 0000000..01c964d --- /dev/null +++ b/test/efb.nas @@ -0,0 +1,2044 @@ +#// Wrappers for property I/O, for conveniently switching between two methods +var setProp = func(prop, value){ + #// setprop(prop, value); + props.getNode("/").setValue(prop, value); +} +var getProp = func(prop){ + #// getprop(prop); + props.getNode("/").getValue(prop); +} + +var ChartsList = +{ + 'KATL': + { + STAR: ["STAR_CANUK1_RNAV", "STAR_ERLIN9_RNAV", "STAR_FLCON7_RNAV", "STAR_HERKO6_RNAV", "STAR_HONIE8_RNAV", "STAR_LA_GRANGE2", "STAR_PECHY7_RNAV", "STAR_ROME4", "STAR_RPTOR1_RNAV", "STAR_SINCA5", "STAR_VIKNN_3RNAV", "STAR_WHINZ1"], + STARs: 12, + IAP: ["ILS_8L_Cat II - III", "ILS_PRM_8L", "ILS_PRM_8L_CAT II - III", "ILS_PRM_8R", "ILS_PRM_9L", "ILS-LOC_8L", "ILS-LOC_8R", "ILS-LOC_9L"], + IAPs: 8, + SID: ["SID_ATL5", "SID_BRAV6_RNAV", "SID_CADIT6_RNAV", "SID_COKEM5_RNAV", "SID_DAWGS5_RNAV", "SID_DOOLY5_RNAV", "SID_GEETK6_RNAV", "SID_JCKTS6_RNAV", "SID_JOGOR4_RNAV", "SID_MUNSN5_RNAV", "SID_NOVSS4_RNAV", "SID_NUGGT5_RNAV"], + SIDs: 12, + APT: "APT_0", + APTs: 1, + LOCATION: "ATLANTA USA", + NAME: "Hartsfield-Jackson" + }, + 'KLAX': + { + STAR: "REDEYE2", + STARs: 1, + IAP: ["06L-ILS", "06R-ILS", "07L-ILS", "07R-ILS"], + IAPs: 4, + SID: "SNGO6", + SIDs: 1, + APT: "APT_0", + APTs: 1, + LOCATION: "LOS ANGELES USA", + NAME: "Intntl" + }, + 'KIAH': + { + STAR: ["RIICE3_1", "RIICE_2"], + STARs: 2, + IAP: ["09-ILS", "15R-ILS"], + IAPs: 2, + SID: "", + SIDs: 0, + APT: "APT_0", + APTs: 1, + LOCATION: "HOUSTON USA", + NAME: "G. Bush Intctl" + }, + 'VABB': + { + STAR: "", + STARs: 0, + IAP: ["09-ILS-DME", "14-ILS-DME"], + IAPs: 2, + SID: "EKPOSxA", + SIDs: 1, + APT: "APT_0", + APTs: 1, + LOCATION: "MUMBAI IN", + NAME: "Chhatrapati Shivaji" + }, + 'KMEM': + { + STAR: "BEERT4", + STARs: 1, + IAP: "09-ILS_LOC", + IAPs: 1, + SID: "", + SIDs: 0, + APT: "APT_0", + APTs: 1, + LOCATION: "MEMPHIS USA", + NAME: "International" + }, + 'LFRB': + { + STAR: "STAR", + STARs: 1, + IAP: ["IAP_25L", "IAP_25L_RNAV", "ILS_Y_25L", "ILS_YZ_07R", "ILS_Z_25L", "NDB_25L", "RADAR", "RNAV_07R", "VFR_APP01", "VFR_LNDG_01"], + IAPs: 11, + SID: ["SID_07R", "SID_25L"], + SIDs: 2, + APT: ["APT_0", "APT_1"], + APTs: 2, + LOCATION: "BREST FR", + NAME: "Guipavas" + }, + 'LFRM': + { + STAR: ["VFR_APP01", "VFR_LND01"], + STARs: 2, + IAP: "", + IAPs: 0, + SID: "", + SIDs: 0, + APT: "APT_0", + APTs: 1, + LOCATION: "LE MANS FR", + NAME: "Arnage" + }, + 'LIME': + { + STAR: ["STAR_ASTIG_ODINA_1S", "STAR_ASTIG_ODINA_1T", "STAR_DIXER_GEN_IDONA_1S", "STAR_DIXER_GEN_IDONA_1T", "STAR_DORIN_LUSIL_OSKOR_1S", "STAR_DORIN_LUSIL_OSKOR_1T", "STAR_East", "STAR_West", "STAR_VOR_DME", "VOR_Y28", "VOR_Y28_2", "VOR_Z28"], + STARs: 12, + IAP: ["ILS-PAPA-28", "ILS-PAPA-28-CAT II", "ILS-SIERRA-28", "ILS-SIERRA-28-CAT II", "ILS-TANGO-28", "ILS-TANGO-28-CAT II", "ILS-X28", "ILS-Y28", "ILS-Z28"], + IAPs: 9, + SID: ["SID_10_BEKAN_DORIN_5S", "SID_10-28_BEKAN5T_DORIN5T_ORI5QT", "SID_10-28_Alternate", "SID_28_SRN5R_TZO5R_TZO5S", "SID_InitialClimb", "SID10_InitialClimb", "SID28_InitialClimb", "SID28_InitialClimb2", "DEP_North_East", "DEP_South", "DEP_West"], + SIDs: 12, + APT: ["APT_0", "APT_0_Small", "GROUND_East_Apron", "GROUND_North_Apron", "GROUND_West_Apron"], + APTs: 6, + LOCATION: "BERGAMO IT", + NAME: "Orio al Serio" + }, + 'LOWI': + { + STAR: ["26-RTT", "STAR", "VFR_East", "VFR_West_KTI", "West-NDB_KYI"], + STARs: 5, + IAP: ["LOC_26_RNAV", "LOC_DME_East", "LOC_DME_West", "NDB_East", "RNAV_08", "RNAV_26", "SPEC_LOC_DME_East"], + IAPs: 8, + SID: ["08-RTT", "General Departure", "SID_08", "SID0_RTT1W", "SID_08_SPECPERF_KPT1Z", "SID_08_SPECPERF_RTT2Z", "SID-26", "SID_26_MOGTI1H_RTT1Y", "SID_26_RNAV"], + SIDs: 9, + APT: ["APT_0", "APT_1"], + APTs: 2, + LOCATION: "INNSBRUCK AT", + NAME: "Kranebitten" + }, + 'WSSS': + { + STAR: ["BOBAG1A", "BOBAG1B", "LAVAX1A", "LAVAX1B"], + STARs: 4, + IAP: ["02C-VOR-DME", "02L-ILS", "02L-ILS-CATII", "20C-VOR-DME", "20R-ILS"], + IAPs: 5, + SID: "BOG1", + SIDs: 1, + APT: ["APT_0", "APT_1"], + APTs: 2, + LOCATION: "SINGAPORE SG", + NAME: "Changi" + }, +}; + +# used in page +var l=[]; +var r=[]; +for(var i=0;i<21;i+=1) +{ + append(l,""); + append(r,""); +} +var KCl0_0 = ""; +var KCl0_1 = ""; +var KCl0 = ""; +var KCl1 = ""; +var KCl2 = ""; +var KCl3 = ""; +var KCl4 = ""; +var KCr1 = ""; +var KCr2 = ""; +var KCr3 = ""; +var KCr4 = ""; +var KCr5 = ""; +var KCr6 = ""; +var ChartName = ["NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL"]; +var ChartDisp = ["NULL", "NULL", "NULL"]; +var Keyboard_Helper = ""; +var Keyboard_Message = ""; +var Index_Max = 0; +var Index_Offset = 0; +var PageList = 0; + +# used in efb +var ZoomFact = 0; +var PanHFact = 0; +var PanVFact = 0; +var OriginApt = "NOT Set"; +var DestinationApt = "NOT Set"; +var ClosingFlightFlag = 0; +var lenght = 0; +var Temp_String = ""; +var Cnv_Fact = 0; +var VK_Key = ""; +var VK_Input_Mem = 0; +var VK_Output_Mem = 0; +var TMZ_Input_Lenght = 0; +var TMZ_Converted_ID = ""; +var TMZ_Converted_Name = ""; +var TMZ_Converted_OffSet = ""; +var TMZ_zulu_HH = ""; +var TMZ_Index = 0; +var TMZ_DB_Size = 0; +var Output_TMZ_Line = ""; +var TMZ_DATE = ""; +var TMZ_TIME = ""; +var Output_HH = 0; +var Output_MM = 0; +var CUT = ["NULL", "NULL", "NULL"]; +var Initial_FL = 0; +var Target_FL = 0; +var Initial_GS = 0; +var Target_GS = 0; +var DRC_String = ""; +var DRC_Input_Lenght = 0; + +# public vars +var helper = ""; +var keypress = ""; +var nochart = ""; +var AptName = "Unknown"; +var Chart_Pages = 1; +var DRC_Distance = 0; +var DRC_l3 = ""; +var DRC_r3 = ""; +var DRC_l5 = ""; +var DRC_r5 = ""; +var DRC_l7 = ""; +var DRC_r8 = ""; +var DRC_r9 = ""; +var DRC_r10 =""; + +# Chart Properties +ident = getProp("/sim/airport/closest-airport-id"); +#AptName = getProp("/instrumentation/efb/chart/icao"); + +if (ident != nil) +{ + setProp("instrumentation/efb/chart/icao", ident); + setProp("instrumentation/efb/chart/DEP_icao", getProp("/instrumentation/efb/chart/icao")); +} else setProp("/instrumentation/efb/chart/icao", ""); +setProp("/instrumentation/efb/chart/type", "APT"); +setProp("/instrumentation/efb/chart/newairport", 0); +setProp("/instrumentation/efb/FlightStatus", 0); # INACTIVE +nochart = 0; + +var page = { + update : func { + for(var i=0; i<21; i+=1) + setProp("/instrumentation/efb/display/line"~i~"-l", l[i]); + # r[0] haven't been used + for(var i=1; i<21; i+=1) + setProp("/instrumentation/efb/display/line"~i~"-r", r[i]); + setProp("/instrumentation/efb/display/input-helper", helper); + setProp("/instrumentation/efb/keypress", keypress); + return; + }, + clearpage : func { + for(var i=0; i<21; i+=1){ + l[i] = ""; + r[i] = ""; + } + helper = ""; + return; + }, + index : func { + for(var i=0; i<21; i+=1){ + l[i] = ""; + r[i] = ""; + } + return; + }, + index_TEST : func { + for(var i=0; i<21; i+=1) + l[i] = "< TEST_L"~i; + # r[0] haven't been used + for(var i=1; i<15; i+=1) + r[i] = "TEST >"; + for(var i=15; i<21; i+=1) + r[i] = "TEST_R"~i~" >"; + return; + }, + KCupdate : func { + setProp("/instrumentation/efb/display/lineAPT_NAME", KCl0); + setProp("/instrumentation/efb/display/lineAPT_LOCATION", KCl0_0); + setProp("/instrumentation/efb/display/lineAPT_PAGESHOW", KCl0_1); + setProp("/instrumentation/efb/display/lineSTAR", KCl1); + setProp("/instrumentation/efb/display/lineIAP", KCl2); + setProp("/instrumentation/efb/display/lineSID", KCl3); + setProp("/instrumentation/efb/display/lineAPT", KCl4); + + setProp("/instrumentation/efb/display/lineCHART1-r", KCr1); + setProp("/instrumentation/efb/display/lineCHART2-r", KCr2); + setProp("/instrumentation/efb/display/lineCHART3-r", KCr3); + + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", Keyboard_Helper); + setProp("/instrumentation/efb/Keyboard/CHART_Output_Line", Keyboard_Message); + }, + KCclearpage : func { + KCl0 = ""; + KCl0_0 = ""; + KCl0_1 = ""; + KCl1 = ""; + KCl2 = ""; + KCl3 = ""; + KCl4 = ""; + + KCr1 = ""; + KCr2 = ""; + KCr3 = ""; + + Keyboard_Helper = ""; + Keyboard_Message = ""; + helper = ""; + }, + DRCupdate : func { + setProp("/instrumentation/efb/display/DRC_l3", DRC_l3); + setProp("/instrumentation/efb/display/DRC_l5", DRC_l5); + setProp("/instrumentation/efb/display/DRC_r3", DRC_r3); + setProp("/instrumentation/efb/display/DRC_r5", DRC_r5); + setProp("/instrumentation/efb/display/DRC_l7", DRC_l7); + setProp("/instrumentation/efb/display/DRC_r8", DRC_r8); + setProp("/instrumentation/efb/display/DRC_r9", DRC_r9); + setProp("/instrumentation/efb/display/DRC_r10", DRC_r10); + }, + DRCclearpage : func { + DRC_l3 = ""; + DRC_l5 = ""; + DRC_r3 = ""; + DRC_r5 = ""; + DRC_l7 = ""; + DRC_r8 = ""; + DRC_r9 = ""; + DRC_r10 = ""; + }, + airportinfo : func { + var ClosestName = ""; + if (getProp("/instrumentation/gps/scratch/name") == nil) + ClosestName = ""; + else + ClosestName = getProp("/instrumentation/gps/scratch/name"); + l[2] = "Airport : " ~ getProp("/instrumentation/gps/scratch/ident") ~ " (" ~ ClosestName ~ ")"; + l[3] = "Latitude : " ~ sprintf("%3.4f", getProp("/instrumentation/gps/scratch/latitude-deg")); + l[4] = "Longitude : " ~ sprintf("%3.4f", getProp("/instrumentation/gps/scratch/longitude-deg")); + l[5] = "Elevation : " ~ sprintf("%3.4f", getProp("/instrumentation/gps/scratch/altitude-ft")) ~ " ft"; + setProp("/environment/metar[6]/station-id", getProp("/instrumentation/gps/scratch/ident")); + l[7] = "Runways : "; + l[8] = " "; + for (var n=0; n<12; n+=1) { + if (getProp("/instrumentation/gps/scratch/runways[" ~ n ~ "]/id") != nil) { + if (n <= 7) l[7] = l[7] ~ getProp("/instrumentation/gps/scratch/runways[" ~ n ~ "]/id") ~ " "; + else l[8] = l[8] ~ getProp("/instrumentation/gps/scratch/runways[" ~ n ~ "]/id") ~ " "; + } + l[10] = "Weather Source: NOAA/METAR"; + r[10] = substr(getProp("/environment/metar[6]/data"),0,16) ~ "z"; + l[11] = substr(getProp("/environment/metar[6]/data"),17,41); + if (size(getProp("/environment/metar[6]/data")) > 41) + l[12] = substr(getProp("/environment/metar[6]/data"), 58, 41); + l[13] = " Current Weather Situation"; + l[14] = "Temperature : " ~ sprintf("%3.2f", getProp("/environment/metar[6]/temperature-degc")) ~ " �C"; + r[14] = "Dewpoint : " ~ sprintf("%3.2f", getProp("/environment/metar[6]/dewpoint-degc")) ~ " �C"; + l[15] = "Wind Direction : " ~ sprintf("%3.0f", getProp("/environment/metar[6]/base-wind-dir-deg")) ~ " degs"; + r[15] = "Wind Speed : " ~ sprintf("%3.0f", getProp("/environment/metar[6]/base-wind-speed-kt")) ~ " Kt"; + l[16] = "Max Visibility : " ~ sprintf("%3.0f", getProp("/environment/metar[6]/max-visibility-m")) ~ " ft"; + r[16] = "Min Visibility : " ~ sprintf("%3.0f", getProp("/environment/metar[6]/min-visibility-m")) ~ " ft"; + l[17] = "Relative Humidity : " ~ sprintf("%3.2f", getProp("/environment/metar[6]/rel-humidity-norm")) ~ " %"; + l[18] = "Pressure : " ~ sprintf("%3.2f", getProp("/environment/metar[6]/pressure-inhg")) ~ " inHg"; + l[20] = "Weather Report subject to Station availability"; + } + }, + FlightMonitor : func { + if (getProp("/instrumentation/efb/FlightStatus") == 1) { + var FStatus = "ACTIVE"; + } else FStatus = "INACTIVE"; + if (getProp("/autopilot/route-manager/active") == 1) { + if (getProp("/autopilot/route-manager/departure/takeoff-time") != nil) { + var TOT = getProp("/autopilot/route-manager/departure/takeoff-time") ~ "z"; + } else TOT = "Unknown"; + if (getProp("/autopilot/route-manager/destination/touchdown-time") != nil) { + var TDT = getProp("/autopilot/route-manager/destination/touchdown-time") ~ "z"; + } else TDT = "Unknown"; + var OAPT = getProp("/autopilot/route-manager/departure/airport") ~ " " ~ getProp("/autopilot/route-manager/departure/runway"); + var DAPT = getProp("/autopilot/route-manager/destination/airport") ~ " " ~ getProp("/autopilot/route-manager/destination/runway"); + } else { + OAPT = "NOT Set"; + DAPT = "NOT Set"; + TOT = "Unknown"; + TDT = "Unknown"; + } + l[2] = "Aircraft: " ~ getProp("/sim/description") ~ " Seattle"; + l[3] = "Operator: " ~ substr(getProp("/sim/aircraft-operator"),0,3); + r[3] = "CallSign: " ~ substr(getProp("/sim/multiplay/callsign"), 0,6); + l[4] = "Flight No: " ~ "NOT Set"; # This will be set through CDU (To be done) + r[4] = "Flight Status: " ~ FStatus; + l[5] = "Origin APT: " ~ OAPT; + r[5] = "TO Time: " ~ TOT; + l[6] = "Destination APT: " ~ DAPT; + r[6] = "TD Time: " ~ TDT; + l[7] = "Date: " ~ substr(getProp("environment/metar/data"),0,10); + r[7] = "Time: " ~ getProp("/instrumentation/clock/indicated-short-string") ~ "z"; + l[9] = "Ind. ALT: " ~ sprintf("%3.2f", getProp("/Instrumentation/altimeter/indicated-altitude-ft")) ~ " ft"; + r[9] = "Press. ALT: " ~ sprintf("%3.2f", getProp("/Instrumentation/altimeter/pressure-alt-ft")) ~ " ft"; + l[10] = "Press. hPa: " ~ sprintf("%3.2f", getProp("/Instrumentation/altimeter/setting-hpa")); + r[10] = "Press. inHg: " ~ sprintf("%3.2f", getProp("/Instrumentation/altimeter/setting-inhg")); + l[11] = "Speed Knots: " ~ sprintf("%3.0f", getProp("/Instrumentation/airspeed/indicated-speed-kt")); + r[11] = "Speed Mach: " ~ sprintf("%3.0f", getProp("/Instrumentation/airspeed/indicated-mach")); + l[12] = "Temperature �C: " ~ sprintf("%3.2f", getProp("/environment/temperature-degc")); + r[12] = "Temperature �F: " ~ sprintf("%3.2f", getProp("/environment/temperature-degf")); + l[13] = "Wind Dir.: " ~ sprintf("%3.0f", getProp("/environment/metar/base-wind-dir-deg")) ~ " degs"; + r[13] = "Wind Speed: " ~ sprintf("%3.0f", getProp("/environment/base-wind-speed-kt")) ~ " kts"; + l[14] = "Total Fuel: " ~ sprintf("%3.2f", getProp("/consumables/fuel/total-fuel-gals")) ~ " gals"; + l[15] = "Gross Weight: " ~ sprintf("%3.2f", getProp("/yasim/gross-weight-lbs")) ~ " lbs"; + # warning: this line l[14] has been changed to l[15],be careful of bugs.But it must be at the right side + }, + gps : func { + l[1] = " GPS POSITION / SETTINGS"; + l[2] = "Latitude : " ~ sprintf("%3.2f", getProp("/instrumentation/gps/indicated-latitude-deg")) ~ " degs"; + r[2] = "Longitude : " ~ sprintf("%3.2f", getProp("/instrumentation/gps/indicated-longitude-deg")) ~ " degs"; + l[13] = "GPS Mode: " ~ getProp("/instrumentation/gps/mode"); + r[13] = "WayPoint ID: " ~ getProp("/instrumentation/gps/wp/wp[1]/ID"); + l[14] = "Leg Distance: " ~ sprintf("%3.2f", getProp("/instrumentation/gps/wp/leg-distance-nm")) ~ " Nm"; + l[15] = "Leg Magnetic Course : " ~ sprintf("%3.2f", getProp("/instrumentation/gps/wp/leg-mag-course-deg")) ~ " degs"; + l[16] = "Leg True Heading: " ~ sprintf("%3.2f", getProp("/instrumentation/gps/wp/leg-true-course-deg")) ~ " degs"; + }, + charts_keyboard : func { + setProp("/instrumentation/efb/chart/Status", "ON"); + setProp("/instrumentation/efb/chart/type", "APT"); + PageList = getProp("/instrumentation/efb/chart/PageList"); + + # Checks existence of Charts in the DB by chart's type ~ "-0"; example: "KSFO/type-0" + var Chart_Search = ""; + Chart_Search = sprintf("%s", getProp("/instrumentation/efb/chart/icao")); + + # HERE we need to launch the SEARCH into the ChartsList hash + #if (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "-0") == nil ) { + # setProp("/instrumentation/efb/chart_Found", "NOT_FOUND"); + # nochart = 1; + #} else { + # setProp("/instrumentation/efb/chart_Found", "FOUND"); + # nochart = 0; + #} + + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", "Charts for " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ ": " ~ getProp("/instrumentation/efb/chart_Found")); + if (nochart == 0) { + # gets the APT's Name & Location + setProp("/instrumentation/efb/chart/type", "NAME"); + KCl0 = getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type")); + setProp("/instrumentation/efb/chart/type", "LOCATION"); + KCl0_0 = getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type")); + + setProp("/instrumentation/efb/chart/type", "APT"); + # Gets the number of charts (by Type) in the Charts DB + STAR_Status = setProp("/instrumentation/efb/chart/NumSTARs", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ "STARs"))); + IAP_Status = setProp("/instrumentation/efb/chart/NumIAPs", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ "IAPs"))); + SID_Status = setProp("/instrumentation/efb/chart/NumSIDs", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ "SIDs"))); + APT_Status = setProp("/instrumentation/efb/chart/NumAPTs", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ "APTs"))); + + # Gets the Type of chart from Pilot's Selection + + if (getProp("/instrumentation/efb/VK_Chart_Type") != "") { + if (getProp("/instrumentation/efb/VK_Chart_Type") == "STAR") { + setProp("/instrumentation/efb/chart/type", "STAR"); + Keyboard_Message = getProp("/instrumentation/efb/chart/NumSTARs") ~ " " ~ getProp("/instrumentation/efb/chart/type") ~ " Charts for " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ " Apt - Select a Chart"; + STAR_Status = 1; + } else STAR_STATUS = 0; + if (getProp("/instrumentation/efb/VK_Chart_Type") == "IAP") { + setProp("/instrumentation/efb/chart/type", "IAP"); + Keyboard_Message = getProp("/instrumentation/efb/chart/NumIAPs") ~ " " ~ getProp("/instrumentation/efb/chart/type") ~ " Charts for " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ " Apt - Select a Chart"; + IAP_Status = 1; + } else IAP_Status = 0; + if (getProp("/instrumentation/efb/VK_Chart_Type") == "SID") { + setProp("/instrumentation/efb/chart/type", "SID"); + Keyboard_Message = getProp("/instrumentation/efb/chart/NumSIDs") ~ " " ~ getProp("/instrumentation/efb/chart/type") ~ " Charts for " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ " Apt - Select a Chart"; + SID_Status = 1; + } else SID_Status = 0; + if (getProp("/instrumentation/efb/VK_Chart_Type") == "APT") { + setProp("/instrumentation/efb/chart/type", "APT"); + Keyboard_Message = getProp("/instrumentation/efb/chart/NumAPTs") ~ " " ~ getProp("/instrumentation/efb/chart/type") ~ " Charts for " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ " Apt - Select a Chart"; + APT_Status = 1; + } else APT_Status = 0; + + setProp("/instrumentation/efb/VK_Chart_Type", getProp("/instrumentation/efb/chart/type")); + setProp("/instrumentation/efb/chartsDB", "ChartsDB/"); + + #setProp("/instrumentation/efb/chart/selected", getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "-1")); + + var lastn = getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "s") - 1; + if (lastn <= 0) lastn = 0; + + if ((STAR_Status == 0) and (IAP_Status == 0) and (SID_Status == 0) and (APT_Status == 0)) { + setProp("/instrumentation/efb/chart/Status", 0); + Keyboard_Message = "No Charts available for: " ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ " Apt"; + setProp("/instrumentation/efb/chart/Status", "OFF"); + } + + # Gets the available ICAO/Type charts in the Charts DB + for (var index = 0; index <= 29; index += 1) + ChartName[index] = ""; + + if (lastn > 0) { + for (var index = 0; index <= lastn; index += 1) { + setProp("/instrumentation/efb/chart/IDX", index); + setProp("/instrumentation/efb/chart/selected", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "-" ~ getProp("/instrumentation/efb/chart/IDX")))); + ChartName[index] = getProp("/instrumentation/efb/chart/selected"); + } + } else { + setProp("/instrumentation/efb/chart/selected", (getProp("/instrumentation/efb/chartsDB/" ~ sprintf("%s", getProp("/instrumentation/efb/chart/icao")) ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "-0"))); + ChartName[0] = getProp("/instrumentation/efb/chart/selected"); + } + Keyboard_Helper = "Enter Airport ICAO"; + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", Keyboard_Helper); + setProp("/instrumentation/efb/Keyboard/CHART_Output_Line", Keyboard_Message); + + # Prints Charts values to Upper Input Display + if (getProp("/instrumentation/efb/chart/Status") == "ON") { + KCl1 = sprintf(getProp("/instrumentation/efb/chart/NumSTARs")); + KCl2 = sprintf(getProp ("/instrumentation/efb/chart/NumIAPs")); + KCl3 = sprintf(getProp ("/instrumentation/efb/chart/NumSIDs")); + KCl4 = sprintf(getProp ("/instrumentation/efb/chart/NumAPTs")); + + # Set Index Offset for proper Page Display (by 3 rows) + if (lastn <=2) Index_Max = 0; + elsif ((lastn > 2) and (lastn <= 5)) Index_Max = 3; + elsif ((lastn > 5) and (lastn <= 8)) Index_Max = 6; + elsif ((lastn > 8) and (lastn <=11)) Index_Max = 9; + elsif ((lastn > 11) and (lastn <=14)) Index_Max = 12; + elsif ((lastn > 14) and (lastn <=17)) Index_Max = 15; + elsif ((lastn > 17) and (lastn <=20)) Index_Max = 18; + elsif ((lastn > 20) and (lastn <=23)) Index_Max = 21; + elsif ((lastn > 23) and (lastn <=26)) Index_Max = 24; + elsif ((lastn > 26) and (lastn <=29)) Index_Max = 27; + + Chart_Pages = (Index_Max/3) + 1; + + # Displays Actual Chart Page/Total Pages + var Page_Show = "Page " ~ getProp("/instrumentation/efb/chart/PageList") ~ "/" ~ Chart_Pages; + setProp("instrumentation/efb/chart/PageShow", Page_Show); + KCl0_1 = getProp("/instrumentation/efb/chart/PageShow"); + + # Build 3 rows of Chart Names + for (var index = 0; index <= 2; index += 1) { + Index_Offset = ((getProp("/instrumentation/efb/chart/PageList") - 1) * 3); + Index_Offset = Index_Offset + index; + ChartDisp[index] = ChartName[Index_Offset]; + } + # Displays 3 Chart Names [MAX Lenght = 27 chars !], ready for Selection by the Pilot + setProp("instrumentation/efb/chart/Selection_0", ChartDisp[0]); + setProp("instrumentation/efb/chart/Selection_1", ChartDisp[1]); + setProp("instrumentation/efb/chart/Selection_2", ChartDisp[2]); + KCr1 = substr(getProp("instrumentation/efb/chart/Selection_0"), 0, 26); + KCr2 = substr(getProp("instrumentation/efb/chart/Selection_1"), 0, 26); + KCr3 = substr(getProp("instrumentation/efb/chart/Selection_2"), 0, 26); + } else { + KCl0 = ""; + KCl0_0 = ""; + KCl0_1 = ""; + KCl1 = ""; + KCl2 = ""; + KCl3 = ""; + KCl4 = ""; + + KCr1 = ""; + KCr2 = ""; + KCr3 = ""; + setProp("instrumentation/efb/chart/Selection_0", ""); + setProp("instrumentation/efb/chart/Selection_1", ""); + setProp("instrumentation/efb/chart/Selection_2", ""); + } + page.KCupdate(); + } + } # END of 'nochart == 0' Brace + } +}; + +var efb = { + init : func { + me.UPDATE_INTERVAL = 0.05; + me.loopid = 0; + # INITIALIZE + + setProp("/instrumentation/efb/page", "MENU"); + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + + # Chart Section Stuff + + setProp("/instrumentation/efb/chart/type", "APT"); + setProp("/instrumentation/efb/chart/selected", "APT_0"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", ""); + setProp("/instrumentation/efb/chart/rotation", 0); + setProp("/instrumentation/efb/diagram/rotation", 0); + + AptName = getProp("/instrumentation/efb/chart/icao"); + + # Various Stuff + + setProp("/instrumentation/efb/manual-page", 0); + + setProp("/instrumentation/efb/vnav_autogen/first", 0); + setProp("/instrumentation/efb/vnav_autogen/gen", 0); + TMZ_DB_Size = getProp("/instrumentation/efb/TimeZonesDB/TMZ_DB_Size") - 1; + setProp("/instrumentation/efb/chart/PageList", 1); + me.reset(); + }, + searchairport : func(query) { + setProp("/instrumentation/gps/scratch/query", query); + setProp("/instrumentation/gps/scratch/type", "airport"); + setProp("/instrumentation/gps/command", "search"); + setProp("/instrumentation/efb/selected-rwy/id", ""); + }, + searchcomms : func(query) { + setProp("/sim/gui/dialogs/scratch/airports/selected-airport/id", query); + #setProp("/sim/gui/dialogs/airports/scratch/type", "airport"); + setProp("/sim/gui/dialogs/scratch/airports/mode", "search"); + #setProp("/instrumentation/efb/selected-rwy/id", ""); + }, + searchcharts : func(chart) {setProp("/sim/model/efb/chart", "Charts/" ~ chart ~ ".jpg");}, + efbTimer : nil, + update : func { + var keypress = getProp("/instrumentation/efb/keypress"); + var currentPage = getProp("/instrumentation/efb/page"); + if (currentPage == "MENU") { + # Make sure we know the APT's ICAO + setProp("/instrumentation/gps/scratch/ident", getProp("/sim/airport/closest-airport-id")); + + if (getProp("/instrumentation/gps/scratch/ident") != nil) setProp("/instrumentation/efb/chart/icao", sprintf("%s", getProp("/instrumentation/gps/scratch/ident"))); + else setProp("/instrumentation/efb/chart/icao", ""); + + AptName = sprintf("%s", getProp("/instrumentation/efb/chart/icao")); + page.clearpage(); + page.index(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + keypress = ""; + } + elsif (keypress == "l1") { + setProp("/instrumentation/efb/page", "CHARTS"); + setProp("/instrumentation/efb/chart/chartmenu", 0); + setProp("/instrumentation/efb/chart/zoom-in", 0); + ZoomFact = 0; + PanHFact = 0; + PanVFact = 0; + keypress = ""; + } + elsif (keypress == "r1") { + setProp("/sim/model/efb/page", "Displays/Video_1.jpg"); + setProp("/instrumentation/efb/page", "VIDEO"); + keypress = ""; + } + elsif (keypress == "l2") { + setProp("/sim/model/efb/page", "Displays/Performance_1.jpg"); + setProp("/instrumentation/efb/page", "PERFORMANCE"); + keypress = ""; + } + elsif (keypress == "r2") { + setProp("/sim/model/efb/page", "Displays/Documents_1.jpg"); + setProp("/instrumentation/efb/page", "DOCUMENTS"); + keypress = ""; + } + elsif (keypress == "l4") { + setProp("/sim/model/efb/page", "Displays/Airport_Info.jpg"); + setProp("/instrumentation/efb/page", "APT INFO"); + keypress = ""; + } + elsif (keypress == "l5") { + setProp("/instrumentation/efb/page", "Airport Charts"); + keypress = ""; + } + elsif (keypress == "l7") { + setProp("/sim/model/efb/page", "Displays/IDENT_1.jpg"); + setProp("/instrumentation/efb/page", "IDENT"); + keypress = ""; + } + elsif (keypress == "l8") { + setProp("/sim/model/efb/page", "Displays/System_1.jpg"); + setProp("/instrumentation/efb/page", "SYSTEMS"); + keypress = ""; + } + elsif (keypress == "r4") { + #//setProp("/instrumentation/efb/page", "Airport Diagram"); + keypress = ""; + } + elsif (keypress == "r5") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + keypress = ""; + } + elsif (keypress == "r6") { + #//setProp("/instrumentation/efb/page", "Flight Fuel Planner"); + keypress = ""; + } + elsif (keypress == "r7") { + setProp("/sim/model/efb/page", "Displays/Monitor.jpg"); + setProp("/instrumentation/efb/page", "MONITOR"); + keypress = ""; + } + elsif (keypress == "r8") { + setProp("/instrumentation/efb/page", "INITIALIZE"); + keypress = ""; + } + #__________________________________________________________________________________________ + # CHART SECTION Parser --------------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "CHARTS") { + page.clearpage(); + #setProp("/sim/model/efb/chart", "Displays/Help_1.jpg"); + setProp("/instrumentation/efb/diagram/rotation", 0); + setProp("/instrumentation/efb/diagram/chartmenu", 0); + setProp("/instrumentation/efb/chartsDB", "Charts/"); + #helper = ""; + # NOTE: this gives the Airport's name to be used on the bottom line of the Chart Display) has still to be checked: if RouteManager is not selected from the upper MENU, the property is not active... + AptName = getProp("/instrumentation/efb/chart/icao"); + + #_____________________________ + # Chart Selection at Airport | + #_____________________________| + + # Checks existence of Charts in the DB + + if(ChartsList[AptName] == nil){ + setProp("/instrumentation/efb/chart_Found", "NOT_FOUND"); + nochart = 1; + }else{ + setProp("/instrumentation/efb/chart_Found", "FOUND"); + nochart = 0; + } + if (nochart == 0){ + page.update(); + if (getProp("/instrumentation/efb/chart/type") == "APT"){ + l[0] = "AIRPORT MAP"; + } + else l[0] = ""; + + l[20] = AptName; + efb.searchcharts(AptName ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "/" ~ getProp("/instrumentation/efb/chart/selected")); + #efb.searchcharts(AptName ~ "/" ~ getProp("/instrumentation/efb/chart/type") ~ "/" ~ getProp("instrumentation/efb/chart/selection2"); + setProp("/sim/model/efb/chart", getProp("/sim/model/efb/chart")); + setProp("/sim/model/efb/chart_BKUP", getProp("/sim/model/efb/chart")); + setProp("/sim/model/efb/Chart_2", getProp("/sim/model/efb/chart_BKUP")); + setProp("/sim/model/efb/Chart_4", getProp("/sim/model/efb/chart_BKUP")); + setProp("/sim/model/efb/Ovlay_1", "Displays/drawing.png"); + + if (getProp("/instrumentation/efb/chart/chartmenu") == 0) setProp("/sim/model/efb/Ovlay_1", "Displays/drawing.png"); + if (getProp("/instrumentation/efb/chart/chartmenu") == 1) setProp("/sim/model/efb/Ovlay_1", "Displays/drawing2.png"); + + } else { + setProp("/sim/model/efb/chart", "Displays/NoCharts.jpg"); + setProp("/sim/model/efb/Ovlay_1", "Displays/drawingNULL.png"); + helper = "Airport: " ~ AptName; + } + # Handles the Zoom-In and Zoom-Out EFB buttons on Charts Display; available ZoomFact is 2x and 4x only. + if ((ZoomFact >= 0) and (ZoomFact <= 4)) { + if ((keypress == "Zin") and (nochart == 0)) { + ZoomFact = ZoomFact + 2; + setProp("/instrumentation/efb/chart/zoom-in", ZoomFact); + keypress = ""; + } + elsif ((keypress == "Zout") and (nochart == 0) and (ZoomFact > 0)) { + ZoomFact = ZoomFact - 2; + setProp("/instrumentation/efb/chart/zoom-in", ZoomFact); + keypress = ""; + } + } + if (ZoomFact == 0) setProp("/instrumentation/efb/chart/zoom-in", 0); + # Handles the Pan-Right, Pan_Left, ScrollUP and ScrollDN EFB buttons on Charts Display; Pan Horizontal Factor is 100; Pan Vertical Factor is 100. + if ((ZoomFact == 2) or (ZoomFact == 4)) { + if ((keypress == "Move_R") and (nochart == 0)) { + PanHFact = PanHFact + 100; + setProp("/instrumentation/efb/chart/panH", PanHFact); + keypress = ""; + } + elsif ((keypress == "Move_L") and (nochart == 0)) { + PanHFact = PanHFact - 100; + setProp("/instrumentation/efb/chart/panH", PanHFact); + keypress = ""; + } + elsif ((keypress == "ScrollUP") and (nochart == 0)) { + PanVFact = PanVFact + 100; + setProp("/instrumentation/efb/chart/panV", PanVFact); + keypress = ""; + } + elsif ((keypress == "ScrollDN") and (nochart == 0)) { + PanVFact = PanVFact - 100; + setProp("/instrumentation/efb/chart/panV", PanVFact); + keypress = ""; + } + } elsif (ZoomFact == 0) { + setProp("/instrumentation/efb/chart/panH", -PanHFact); + setProp("/instrumentation/efb/chart/panV", -PanVFact); + } + # Handles Chart Rotation counter-clockwise + if ((keypress == "l2") and (nochart == 0) and (getProp("/instrumentation/efb/chart/chartmenu")) == 0) toggle("/instrumentation/efb/chart/rotation"); + # Toggles Overlay Menu On/OFF + if ((keypress == "r8") and (nochart == 0)) toggle("/instrumentation/efb/chart/chartmenu"); + # Calls Virtual Keyboard for Chart DB Selection by the Pilot + if (keypress == "l5") { + setProp("/instrumentation/efb/page", "CHARTS_KEYBOARD"); + setProp("/instrumentation/efb/chart/zoom-in", 0); + setProp("/instrumentation/efb/VKDRC_keypress", ""); + setProp("/instrumentation/efb/VK_Keyboard/Input_String", ""); + setProp("/instrumentation/efb/chart/Searchable", 0); + } + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/chart/zoom-in", 0); + ZoomFact = 0; + PanHFact = -PanHFact; + PanVFact = -PanVFact; + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # AIRPORT INFO SECTION Parser -------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "APT INFO") { + + page.clearpage(); + efb.searchairport(getProp("/sim/airport/closest-airport-id")); + efb.searchcomms(getProp("/sim/airport/closest-airport-id")); + page.airportinfo(); + page.update(); + + # if (keypress == "r6") { + # setProp("/instrumentation/efb/page", "Runway Information"); + # keypress = ""; + # } + if (keypress == "r8") { + setProp("/instrumentation/efb/page", "CHARTS"); + keypress = ""; + } + elsif (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # MONITOR SECTION Parser ------------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "MONITOR") { + page.clearpage(); + page.FlightMonitor(); + page.update(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # VIDEO SECTION Parser --------------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "VIDEO") { + page.clearpage(); + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # DOCUMENTS SECTION Parser ----------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "DOCUMENTS") { + page.clearpage(); + + if (keypress == "l3") { + setProp("/instrumentation/efb/page", "NORM PROC MANUAL"); + keypress = ""; + } + elsif (keypress == "r2") { + setProp("/sim/model/efb/page", "Displays/Checklists_1.jpg"); + setProp("/instrumentation/efb/page", "CHECKLISTS"); + keypress = ""; + } + elsif (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # PERFORMANCE SECTION Parser --------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "PERFORMANCE") { + page.clearpage(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # CHECKLISTS SECTION Parser ---------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "CHECKLISTS") { + page.clearpage(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + if (keypress == "l2") { + setProp("/sim/model/efb/page", "Displays/Checklists_1_1.jpg"); + setProp("/instrumentation/efb/page", "CHECKLISTS"); + keypress = ""; + } + if (keypress == "r2") { + setProp("/sim/model/efb/page", "Displays/Checklists_1_2.jpg"); + setProp("/instrumentation/efb/page", "CHECKLISTS"); + keypress = ""; + } + #__________________________________________________________________________________________ + # IDENT SECTION Parser -------------------------------------------------------------------| + #_________________________________________________________________________________________| + } elsif (currentPage == "IDENT") { + page.clearpage(); + + IDENTl3 = getProp("/sim/description"); + IDENTl4 = substr(getProp("/sim/aircraft-operator"),0,3) ~ " / " ~ substr(getProp("/sim/multiplay/callsign"), 0,6); # this is to ensure that too long 'operator' and 'callsign' data can fit into the EFB display + IDENTr4 = "VMEFB001"; # this is the EFb Seattle version's ID + IDENTl5 = substr(getProp("environment/metar/data"),0,10); + IDENTr5 = getProp("/instrumentation/clock/indicated-short-string") ~ "z"; + IDENTl8 = "AIRPORT MAP DATABASE Seattle Data APR1214-JUN3014"; # this is the DB version, which we will periodically update with better and new Charts + + setProp("/instrumentation/efb/display/IDENTline3-l", IDENTl3); + setProp("/instrumentation/efb/display/IDENTline4-l", IDENTl4); + setProp("/instrumentation/efb/display/IDENTline4-r", IDENTr4); + setProp("/instrumentation/efb/display/IDENTline5-l", IDENTl5); + setProp("/instrumentation/efb/display/IDENTline5-r", IDENTr5); + setProp("/instrumentation/efb/display/IDENTline8-l", IDENTl8); + + setProp("/instrumentation/efb/display/input-helper", helper); + setProp("/instrumentation/efb/keypress", keypress); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + + IDENTl3 = ""; + IDENTl4 = ""; + IDENTr4 = ""; + IDENTl5 = ""; + IDENTr5 = ""; + IDENTl8 = ""; + setProp("/instrumentation/efb/display/IDENTline3-l", IDENTl3); + setProp("/instrumentation/efb/display/IDENTline4-l", IDENTl4); + setProp("/instrumentation/efb/display/IDENTline4-r", IDENTr4); + setProp("/instrumentation/efb/display/IDENTline5-l", IDENTl5); + setProp("/instrumentation/efb/display/IDENTline5-r", IDENTr5); + setProp("/instrumentation/efb/display/IDENTline8-l", IDENTl8); + + keypress = ""; + } + #__________________________________________________________________________________________ + # SYSTEM SECTION Parser ------------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "SYSTEMS") { + page.clearpage(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + #__________________________________________________________________________________________ + # CHART SECTION Parser -------------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "CHARTS_KEYBOARD") { + page.clearpage(); + page.update(); + page.charts_keyboard(); + + if (getProp("/instrumentation/efb/chart/Searchable") == 0) { + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", "Enter ICAO"); + } + + # Get the ICAO to be searched for; "Virtual Keyboard" Keys Parser (see EFB_Chart_Keyboard.xml) + + if ((getProp("/instrumentation/efb/VKDRC_keypress") != "") and (getProp("/instrumentation/efb/VKDRC_keypress") != "SYMB") and (getProp("/instrumentation/efb/VKDRC_keypress") != "SHIFT")) { + setProp("/instrumentation/efb/VK_Keyboard/Input_String", getProp("/instrumentation/efb/VK_Keyboard/Input_String") ~ getProp("/instrumentation/efb/VKDRC_keypress")); # Build the Input String + + if (getProp("/instrumentation/efb/VKDRC_keypress") == "CLEAR") { + + setProp("/instrumentation/efb/VK_Keyboard/Input_String", ""); # CLEARs the whole Input Field and other stuff + } + if (getProp("/instrumentation/efb/VKDRC_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/VK_Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/VK_Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VKDRC_keypress", ""); + } + } + + setProp("/instrumentation/efb/VKDRC_keypress", ""); + + TMZ_String = getProp("/instrumentation/efb/VK_Keyboard/Input_String"); + TMZ_Input_Lenght = size(TMZ_String); + + if (TMZ_Input_Lenght <= 3) { + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", getProp("/instrumentation/efb/VK_Keyboard/Input_String")); # Print it to the Keyboard Input Field + + } else { + setProp("/instrumentation/efb/chart/Searchable", 1); + setProp("/instrumentation/efb/Keyboard/CHART_Input_Line", "Press [Search IDENT] to search for: " ~ getProp("/instrumentation/efb/VK_Keyboard/Input_String")); + } + if ((getProp("/instrumentation/efb/chart/Searchable") == 1) and (keypress == "l3")) { # do SEARCH CHART + setProp("/instrumentation/efb/chart/icao", getProp("/instrumentation/efb/VK_Keyboard/Input_String")); + page.charts_keyboard(); + setProp("/instrumentation/efb/VKDRC_keypress", ""); + setProp("/instrumentation/efb/chart/Searchable", 0); + setProp("/instrumentation/efb/VK_Keyboard/Input_String", ""); + } + + if ((keypress == "PGDN") and (getProp("/instrumentation/efb/chart/PageList") < Chart_Pages)) { + setProp("/instrumentation/efb/chart/SetPage", "INCREASE"); + setProp("/instrumentation/efb/chart/PageList", getProp("/instrumentation/efb/chart/PageList") + 1); + } + if ((keypress == "PGUP") and (getProp("/instrumentation/efb/chart/PageList") > 1)) { + setProp("/instrumentation/efb/chart/SetPage", "INCREASE"); + setProp("/instrumentation/efb/chart/PageList", getProp("/instrumentation/efb/chart/PageList") + 1); + } + + # Chart Selection - redirection to CHARTS...___________________________________________________________________________________ + + if (keypress == "r1") { + setProp("/instrumentation/efb/chart/selected", getProp("/instrumentation/efb/chart/Selection_0")); + keypress = "MENU"; + } + if (keypress == "r2") { + setProp("/instrumentation/efb/chart/selected", getProp("/instrumentation/efb/chart/Selection_1")); + keypress = "MENU"; + } + if (keypress == "r3") { + setProp("/instrumentation/efb/chart/selected", getProp("/instrumentation/efb/chart/Selection_2")); + keypress = "MENU"; + } + # _____________________________________________________________________________________________________________________________ + + if (keypress == "MENU") { + # setProp("/sim/model/efb/page", "Displays/Blank_Test.jpg"); + setProp("/instrumentation/efb/chart/Status", "OFF"); + setProp("/instrumentation/efb/VK_Chart_Type", "APT"); # This starts and re-starts the Chart_Keyboard with active ICAO/APT Chart displayed ! (see B777 EFB Manual) + setProp("/instrumentation/efb/VK_Keyboard/Input_String", ""); + setProp("/instrumentation/efb/page", "CHARTS"); + page.KCclearpage(); + page.KCupdate(); + keypress = ""; + } + + #__________________________________________________________________________________________ + # INITIALIZE SECTION Parser --------------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "INITIALIZE") { + page.clearpage(); + if (getProp("/instrumentation/efb/FlightStatus") == 0) { + if (getProp("/autopilot/route-manager/departure/airport") != "") + OriginApt = getProp("/autopilot/route-manager/departure/airport"); + else + OriginApt = "NOT Set"; + if (getProp("/autopilot/route-manager/destination/airport") != "") + DestinationApt = getProp("/autopilot/route-manager/destination/airport"); + else + DestinationApt = "NOT Set"; + if ((OriginApt != "NOT Set") and (DestinationApt != "NOT Set")) { + OriginApt = getProp("/autopilot/route-manager/departure/airport"); + DestinationApt = getProp("/autopilot/route-manager/destination/airport"); + setProp("/sim/model/efb/page", "Displays/Initialize_1.jpg"); + ClosingFlightFlag = 1; # Flight INITIABLE + } else { + setProp("/sim/model/efb/page", "Displays/Initialize_2.jpg"); + setProp("/instrumentation/efb/FlightStatus", 0); + ClosingFlightFlag = 0; # Flight NOT INITIABLE + } + } elsif ((getProp("/instrumentation/efb/FlightStatus") == 1) and (ClosingFlightFlag == 2)) { + setProp("/instrumentation/efb/FlightStatus", 1); # Flight ACTIVE and CLOSABLE + FlightStatus = 1; + setProp("/sim/model/efb/page", "Displays/Initialize_3.jpg"); + } + + INITl4 = OriginApt; + INITl5 = DestinationApt; + setProp("/instrumentation/efb/display/INITline4-l", INITl4); + setProp("/instrumentation/efb/display/INITline5-l", INITl5); + + if ((keypress == "r8") and (ClosingFlightFlag == 1)) { + setProp("/instrumentation/efb/FlightStatus", 1); # Flight INITIATED + ClosingFlightFlag = 2; # Flight CLOSABLE + keypress = ""; + } + if ((keypress == "r8") and (FlightStatus == 1)) { + setProp("/instrumentation/efb/FlightStatus", 0); # Flight NOT ACTIVE + setProp("/sim/model/efb/page", "Displays/Initialize_5.jpg"); + FlightStatus = 0; + ClosingFlightFlag = 0; # Flight CLOSED + keypress = ""; + } + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + INITl4 = ""; + INITl5 = ""; + setProp("/instrumentation/efb/display/INITline4-l", INITl4); + setProp("/instrumentation/efb/display/INITline5-l", INITl5); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES SECTION Parser ----------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES") { + page.clearpage(); + setProp("/instrumentation/efb/Keyboard/Input_String", ""); + setProp("/instrumentation/efb/Keyboard/Input_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_Line2", ""); + setProp("/instrumentation/efb/Keyboard/Input_Line3", ""); + setProp("/instrumentation/efb/VK_keypress", ""); + + if (keypress == "l3") { + setProp("/instrumentation/efb/page", "UTILITIES_DESC_RATE"); + setProp("/sim/model/efb/page", "Displays/PU_DRC.jpg"); + setProp("/instrumentation/efb/Keyboard/Input_String", ""); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/Input_Unit", "NO_INPUT"); + setProp("/instrumentation/efb/DRC_Initial_FL", "300"); + setProp("/instrumentation/efb/DRC_Target_FL", "30"); + setProp("/instrumentation/efb/DRC_Initial_GS", "250"); + setProp("/instrumentation/efb/DRC_Target_GS", "200"); + setProp("/instrumentation/efb/DRC_Distance", "50"); + setProp("/instrumentation/efb/DRC_Initial_FL_MEM", getProp("/instrumentation/efb/DRC_Initial_FL")); + setProp("/instrumentation/efb/DRC_Target_FL_MEM", getProp("/instrumentation/efb/DRC_Target_FL")); + setProp("/instrumentation/efb/DRC_Initial_GS_MEM", getProp("/instrumentation/efb/DRC_Initial_GS")); + setProp("/instrumentation/efb/DRC_Target_GS_MEM", getProp("/instrumentation/efb/DRC_Target_GS")); + setProp("/instrumentation/efb/DRC_Distance_MEM", getProp("/instrumentation/efb/DRC_Distance")); + VK_Key = ""; + #setProp("/instrumentation/efb/VK_DRC_MarkerL", 1); + Initial_FL = 300; + Target_FL = 30; + Initial_GS = 250; + Target_GS = 200; + DRC_Distance = 50; + keypress = ""; + } + if (keypress == "l4") { + setProp("/instrumentation/efb/page", "GPS POSITION"); + } + if (keypress == "r1") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_SPD"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Spd.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + VK_Input_Mem = 0; + VK_Output_Mem = 0; + } + if (keypress == "r2") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_LNG"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Lng.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + VK_Input_Mem = 0; + VK_Output_Mem = 0; + } + if (keypress == "r3") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_WGT"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Wgt.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + VK_Input_Mem = 0; + VK_Output_Mem = 0; + } + if (keypress == "r4") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_TMP"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Tmp.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + VK_Input_Mem = 0; + VK_Output_Mem = 0; + } + if (keypress == "r5") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_VLM"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Vlm.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + VK_Input_Mem = 0; + VK_Output_Mem = 0; + } + if (keypress == "r6") { + setProp("/instrumentation/efb/page", "UTILITIES_CNV_TMZ"); + setProp("/sim/model/efb/page", "Displays/PU_Cnv_Tmz.jpg"); + setProp("/instrumentation/efb/VK_keypress", ""); + setProp("/instrumentation/efb/VK_IN_Marker", 1); + setProp("/instrumentation/efb/VK_OUT_Marker", 1); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/Keyboard/Input_HH", "--"); + setProp("/instrumentation/efb/Keyboard/Input_MM", "--"); + setProp("/instrumentation/efb/Keyboard/Output_HH", ""); + setProp("/instrumentation/efb/Keyboard/Output_MM", ""); + setProp("/instrumentation/efb/page/Cnv_Fact", "0"); + TMZ_String = ""; + TMZ_Index = 0; + + #Parsing for Month's names + + TMZ_DATE = substr(getProp("environment/metar/data"), 5, 5); + + if (substr(TMZ_DATE, 0, 2) == "01") TMZ_DATE = "JAN" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "02") TMZ_DATE = "FEB" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "03") TMZ_DATE = "MAR" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "04") TMZ_DATE = "APR" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "05") TMZ_DATE = "MAY" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "06") TMZ_DATE = "JUN" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "07") TMZ_DATE = "JUL" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "08") TMZ_DATE = "AUG" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "09") TMZ_DATE = "SEP" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "10") TMZ_DATE = "OCT" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "11") TMZ_DATE = "NOV" ~ substr(TMZ_DATE, 2, 3); + if (substr(TMZ_DATE, 0, 2) == "12") TMZ_DATE = "DEC" ~ substr(TMZ_DATE, 2, 3); + } + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Main_Menu.jpg"); + setProp("/instrumentation/efb/page", "MENU"); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - GPS POSITION ----------------------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "GPS POSITION") { + page.clearpage(); + page.gps(); + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - SPEED CONVERSION Parser -----------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_SPD") { + Input_Unit = getProp("/instrumentation/efb/VK_IN_Marker"); + Output_Unit = getProp("/instrumentation/efb/VK_OUT_Marker"); + + # Input keys Check + + if (getProp("/instrumentation/efb/VK_keypress") != "" or (Input_Unit != VK_Input_Mem) or (Output_Unit != VK_Output_Mem)) { + # Input Field Parser + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + if (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + if (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + + # Input Field Display + + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + setProp("/instrumentation/efb/Keyboard/Input_Line", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print it to the Keyboard Input Field + + # ---------------> Conversion Table Selection + # ---------------> Input Unit 1 () FT/M ---> Output Unit: FT/M, KM/H, KT, MTS, MPH + if (Input_Unit == 1) { + if (Output_Unit == 1) Cnv_Fact = 1; + elsif (Output_Unit == 2) Cnv_Fact = 0.018288; + elsif (Output_Unit == 3) Cnv_Fact = 0.0098747; + elsif (Output_Unit == 4) Cnv_Fact = 0.0050800; + elsif (Output_Unit == 5) { + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + Cnv_Fact = 0.011364; + } + } + # ---------------> Input Unit 2 () KM/H ---> Output Unit: FT/M, KM/H, KT, MTS, MPH + elsif (Input_Unit == 2) { + if (Output_Unit == 1) Cnv_Fact = 54.68066; + elsif (Output_Unit == 2) Cnv_Fact = 1; + elsif (Output_Unit == 3) Cnv_Fact = 0.5399568; + elsif (Output_Unit == 4) Cnv_Fact = 0.2777778; + elsif (Output_Unit == 5) Cnv_Fact = 0.6213712; + } + # ---------------> Input Unit 3 () KT ---> Output Unit: FT/M, KM/H, KT, MTS, MPH + elsif (Input_Unit == 3) { + if (Output_Unit == 1) Cnv_Fact = 101.2686; + elsif (Output_Unit == 2) Cnv_Fact = 1.852000; + elsif (Output_Unit == 3) Cnv_Fact = 1; + elsif (Output_Unit == 4) Cnv_Fact = 0.5144444; + elsif (Output_Unit == 5) Cnv_Fact = 1.150779; + } + # ---------------> Input Unit 4 () MTS ---> Output Unit: FT/M, KM/H, KT, MTS, MPH + elsif (Input_Unit == 4) { + if (Output_Unit == 1) Cnv_Fact = 196.85; + elsif (Output_Unit == 2) Cnv_Fact = 3.6000; + elsif (Output_Unit == 3) Cnv_Fact = 1.9438; + elsif (Output_Unit == 4) Cnv_Fact = 1; + elsif (Output_Unit == 5) Cnv_Fact = 2.2369; + } + # ---------------> Input Unit 5 () MPH ---> Output Unit: FT/M, KM/H, KT, MTS, MPH + elsif (Input_Unit == 5) { + if (Output_Unit == 1) Cnv_Fact = 88.0002; + elsif (Output_Unit == 2) Cnv_Fact = 1.609344; + elsif (Output_Unit == 3) Cnv_Fact = 0.8689762; + elsif (Output_Unit == 4) Cnv_Fact = 0.4470400; + elsif (Output_Unit == 5) Cnv_Fact = 1; + } + VK_Input_Mem = Input_Unit; + VK_Output_Mem = Output_Unit; + + # Output Field Display + + if ((getProp("/instrumentation/efb/Keyboard/Input_Line") == "") or (getProp("/instrumentation/efb/Keyboard/Input_Line") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_Line") == "-")) { + setProp("/instrumentation/efb/Keyboard/Output_Line", ""); + } else { + Output_Line = getProp("/instrumentation/efb/Keyboard/Input_Line"); + Output_Line = Output_Line * Cnv_Fact; # Build the Input String + setProp("/instrumentation/efb/Keyboard/Output_Line", Output_Line); # Print it to the Keyboard Output Field + } + setProp("/instrumentation/efb/VK_keypress", ""); + } + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Input_Line", ""); + setProp("/instrumentation/efb/Keyboard/Output_Line", ""); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - LENGHT CONVERSION Parser ----------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_LNG") { + + Input_Unit = getProp("/instrumentation/efb/VK_IN_Marker"); + Output_Unit = getProp("/instrumentation/efb/VK_OUT_Marker"); + + # Input keys Check + + if (getProp("/instrumentation/efb/VK_keypress") != "" or (Input_Unit != VK_Input_Mem) or (Output_Unit != VK_Output_Mem)) { + # Input Field Parser + + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + + # Input Field Display + + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + setProp("/instrumentation/efb/Keyboard/Input_Line", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print it to the Keyboard Input Field + + # ---------------> Conversion Table Selection + + # ---------------> Input Unit 1 () FEET ---> Output Unit: FEET, KILOMETERS, METERS, NAUTICAL MILES, STATUTE MILES + if (Input_Unit == 1) { + if (Output_Unit == 1) Cnv_Fact = 1; + elsif (Output_Unit == 2) Cnv_Fact = 0.0003048; + elsif (Output_Unit == 3) Cnv_Fact = 0.30480; + elsif (Output_Unit == 4) Cnv_Fact = 0.000164579; # International and US Nautical Miles, NOT UK Nautical Miles !! + elsif (Output_Unit == 5) Cnv_Fact = 0.000189394; # International Statute Miles + } + # ---------------> Input Unit 2 () KILOMETERS ---> Output Unit: FEET, KILOMETERS, METERS, NAUTICAL MILES, STATUTE MILES + elsif (Input_Unit == 2) { + if (Output_Unit == 1) Cnv_Fact = 3280.83989501; + elsif (Output_Unit == 2) Cnv_Fact = 1; + elsif (Output_Unit == 3) Cnv_Fact = 1000; + elsif (Output_Unit == 4) Cnv_Fact = 0.539956803456; # International and US Nautical Miles, NOT UK Nautical Miles !! + elsif (Output_Unit == 5) Cnv_Fact = 0.621371192237; # International Statute Miles + } + # ---------------> Input Unit 3 () METERS ---> Output Unit: FEET, KILOMETERS, METERS, NAUTICAL MILES, STATUTE MILES + elsif (Input_Unit == 3) { + if (Output_Unit == 1) Cnv_Fact = 3.28083989501; + elsif (Output_Unit == 2) Cnv_Fact = 0.001; + elsif (Output_Unit == 3) Cnv_Fact = 1; + elsif (Output_Unit == 4) Cnv_Fact = 0.000539956803456; # International and US Nautical Miles, NOT UK Nautical Miles !! + elsif (Output_Unit == 5) Cnv_Fact = 0.000621371192237; # International Statute Miles + } + # ---------------> Input Unit 4 () NAUTICAL MILES (INTERNATIONAL!) ---> Output Unit: FEET, KILOMETERS, METERS, NAUTICAL MILES, STATUTE MILES + elsif (Input_Unit == 4) { + if (Output_Unit == 1) Cnv_Fact = 6076.11548556; + elsif (Output_Unit == 2) Cnv_Fact = 1.852; + elsif (Output_Unit == 3) Cnv_Fact = 1852; + elsif (Output_Unit == 4) Cnv_Fact = 1; + elsif (Output_Unit == 5) Cnv_Fact = 1.15077944802; # International Statute Miles + } + # ---------------> Input Unit 5 () STATUTE MILES ---> Output Unit: FEET, KILOMETERS, METERS, NAUTICAL MILES, STATUTE MILES + elsif (Input_Unit == 5) { + if (Output_Unit == 1) Cnv_Fact = 5280; + elsif (Output_Unit == 2) Cnv_Fact = 1.609344; + elsif (Output_Unit == 3) Cnv_Fact = 1609.344; + elsif (Output_Unit == 4) Cnv_Fact = 0.868976241901; # International and US Nautical Miles, NOT UK Nautical Miles !! + elsif (Output_Unit == 5) Cnv_Fact = 1; + } + VK_Input_Mem = Input_Unit; + VK_Output_Mem = Output_Unit; + + # Output Field Display + if ((getProp("/instrumentation/efb/Keyboard/Input_Line") == "") or (getProp("/instrumentation/efb/Keyboard/Input_Line") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_Line") == "-")) { + setProp("/instrumentation/efb/Keyboard/Output_Line", ""); + } else { + Output_Line = getProp("/instrumentation/efb/Keyboard/Input_Line"); + Output_Line = Output_Line * Cnv_Fact; # Build the Input String + setProp("/instrumentation/efb/Keyboard/Output_Line", Output_Line); # Print it to the Keyboard Output Field + } + setProp("/instrumentation/efb/VK_keypress", ""); + } + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Input_Line", ""); + setProp("/instrumentation/efb/Keyboard/Output_Line", ""); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - WEIGHT CONVERSION Parser ----------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_WGT") { + Input_Unit = getProp("/instrumentation/efb/VK_IN_Marker"); + Output_Unit = getProp("/instrumentation/efb/VK_OUT_Marker"); + + # Input keys Check + if (getProp("/instrumentation/efb/VK_keypress") != "" or (Input_Unit != VK_Input_Mem) or (Output_Unit != VK_Output_Mem)) { + # Input Field Parser + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + + # Input Field Display + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + setProp("/instrumentation/efb/Keyboard/Input_Line2", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print it to the Keyboard Input Field + + # ---------------> Conversion Table Selection + # ---------------> Input Unit 1 () KILOGRAMS ---> Output Unit: KILOGRAMS, POUNDS + if (Input_Unit == 1) { + if (Output_Unit == 1) Cnv_Fact = 1; + elsif (Output_Unit == 2) Cnv_Fact = 2.20462262185; + } + # ---------------> Input Unit 2 () POUNDS ---> Output Unit: KILOGRAMS, POUNDS + elsif (Input_Unit == 2) { + if (Output_Unit == 1) Cnv_Fact = 0.45359237; + elsif (Output_Unit == 2) Cnv_Fact = 1; + } + VK_Input_Mem = Input_Unit; + VK_Output_Mem = Output_Unit; + + # Output Field Display + if ((getProp("/instrumentation/efb/Keyboard/Input_Line2") == "") or (getProp("/instrumentation/efb/Keyboard/Input_Line2") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_Line2") == "-")) { + setProp("/instrumentation/efb/Keyboard/Output_Line2", ""); + } else { + Output_Line2 = getProp("/instrumentation/efb/Keyboard/Input_Line2"); + Output_Line2 = Output_Line2 * Cnv_Fact; # Build the Input String + setProp("/instrumentation/efb/Keyboard/Output_Line2", Output_Line2); # Print it to the Keyboard Output Field + } + setProp("/instrumentation/efb/VK_keypress", ""); + } + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Input_Line2", ""); + setProp("/instrumentation/efb/Keyboard/Output_Line2", ""); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - TEMPERATURE CONVERSION Parser -----------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_TMP") { + + Input_Unit = getProp("/instrumentation/efb/VK_IN_Marker"); + Output_Unit = getProp("/instrumentation/efb/VK_OUT_Marker"); + + # Input keys Check + if (getProp("/instrumentation/efb/VK_keypress") != "" or (Input_Unit != VK_Input_Mem) or (Output_Unit != VK_Output_Mem)) { + # Input Field Parser + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + # Input Field Display + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + setProp("/instrumentation/efb/Keyboard/Input_Line2", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print it to the Keyboard Input Field + + # Output Field Display + if ((getProp("/instrumentation/efb/Keyboard/Input_Line2") == "") or (getProp("/instrumentation/efb/Keyboard/Input_Line2") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_Line2") == "-")) { + setProp("/instrumentation/efb/Keyboard/Output_Line2", ""); + } else { + Output_Line2 = getProp("/instrumentation/efb/Keyboard/Input_Line2"); + # ---------------> Conversion Table Selection + # ---------------> Input Unit 1 () CELSIUS (�C) ---> Output Unit: CELSIUS (�C), FAHRENHEIT (�F) + if (Input_Unit == 1) { + if (Output_Unit == 1) Cnv_Fact = Output_Line2; + elsif (Output_Unit == 2) Cnv_Fact = (Output_Line2*1.8) + 32; + } + # ---------------> Input Unit 2 () FAHRENHEIT (�F) ---> Output Unit: CELSIUS (�C), FAHRENHEIT (�F) + elsif (Input_Unit == 2) { + if (Output_Unit == 1) Cnv_Fact = (Output_Line2 - 32)/1.8; + elsif (Output_Unit == 2) Cnv_Fact = Output_Line2; + } + VK_Input_Mem = Input_Unit; + VK_Output_Mem = Output_Unit; + + Output_Line2 = Cnv_Fact; # Build the Input String + setProp("/instrumentation/efb/Keyboard/Output_Line2", Output_Line2); # Print it to the Keyboard Output Field + } + setProp("/instrumentation/efb/VK_keypress", ""); + } + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Input_Line2", ""); + setProp("/instrumentation/efb/Keyboard/Output_Line2", ""); + keypress = ""; + } + #__________________________________________________________________________________________ + # PILOT UTILITIES - VOLUME CONVERSION Parser ----------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_VLM") { + + Input_Unit = getProp("/instrumentation/efb/VK_IN_Marker"); + Output_Unit = getProp("/instrumentation/efb/VK_OUT_Marker"); + Output_TMZ_Line = ""; + # Input keys Check + if (getProp("/instrumentation/efb/VK_keypress") != "" or (Input_Unit != VK_Input_Mem) or (Output_Unit != VK_Output_Mem)) { + # Input Field Parser + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # CHANGEs SIGN to the Input Field + if (substr(Temp_String, 0, 1) == "-") { + lenght = size(Temp_String) - 1; + Temp_String = substr(Temp_String, 1, lenght); + } else { + Temp_String = "-" ~ Temp_String; + } + setProp("/instrumentation/efb/Keyboard/Input_String", Temp_String); + setProp("/instrumentation/efb/VK_keypress", ""); + } + # Input Field Display + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + setProp("/instrumentation/efb/Keyboard/Input_Line3", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print it to the Keyboard Input Field + + # ---------------> Conversion Table Selection + # ---------------> Input Unit 1 () IMPERIAL GALLONS ---> Output Unit: IMPERIAL GALLONS, US GALLONS, LITERS + if (Input_Unit == 1) { + if (Output_Unit == 1) Cnv_Fact = 1; + elsif (Output_Unit == 2) Cnv_Fact = 1.20095; + elsif (Output_Unit == 3) Cnv_Fact = 4.54609; + } + # ---------------> Input Unit 2 () US GALLONS ---> Output Unit: IMPERIAL GALLONS, US GALLONS, LITERS + elsif (Input_Unit == 2) { + if (Output_Unit == 1) Cnv_Fact = 0.832674; + elsif (Output_Unit == 2) Cnv_Fact = 1; + elsif (Output_Unit == 3) Cnv_Fact = 3.78541; + } + # ---------------> Input Unit 3 () LITERS ---> Output Unit: IMPERIAL GALLONS, US GALLONS, LITERS + elsif (Input_Unit == 3) { + if (Output_Unit == 1) Cnv_Fact = 0.219969; + elsif (Output_Unit == 2) Cnv_Fact = 0.264172; + elsif (Output_Unit == 3) Cnv_Fact = 1; + } + VK_Input_Mem = Input_Unit; + VK_Output_Mem = Output_Unit; + # Output Field Display + if ((getProp("/instrumentation/efb/Keyboard/Input_Line3") == "") or (getProp("/instrumentation/efb/Keyboard/Input_Line3") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_Line3") == "-")) { + setProp("/instrumentation/efb/Keyboard/Output_Line3", ""); + } else { + Output_Line2 = getProp("/instrumentation/efb/Keyboard/Input_Line3"); + Output_Line2 = Output_Line2 * Cnv_Fact; # Build the Input String + setProp("/instrumentation/efb/Keyboard/Output_Line3", Output_Line2); # Print it to the Keyboard Output Field + } + setProp("/instrumentation/efb/VK_keypress", ""); + } + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Input_Line3", ""); + setProp("/instrumentation/efb/Keyboard/Output_Line3", ""); + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - TIME ZONE CONVERSION Parser -------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_CNV_TMZ") { + + TMZ_TIME = getProp("/instrumentation/clock/indicated-short-string") ~ "z"; + setProp("/instrumentation/efb/Keyboard/Current_DT_Line", TMZ_DATE ~ " " ~ TMZ_TIME); # Print Current Date & Time + setProp("/instrumentation/efb/Keyboard/Converted_Name_Line", "Use Keyboard to Input Time (HHMM)"); + # Input keys Check + + if (getProp("/instrumentation/efb/VK_keypress") != "") { + # Input Field Parser + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field and other stuff + setProp("/instrumentation/efb/Keyboard/Input_HH_Line", "--"); + setProp("/instrumentation/efb/Keyboard/Input_MM_Line", "--"); + setProp("/instrumentation/efb/Keyboard/Input_Zulu_Line", "--:--"); + setProp("/instrumentation/efb/Keyboard/Output_HH", ""); + setProp("/instrumentation/efb/Keyboard/Output_MM", ""); + setProp("/instrumentation/efb/Keyboard/Converted_ID_Line", ""); + setProp("/instrumentation/efb/Keyboard/Converted_Name_Line", "Use Keyboard to Input Time (HHMM)"); + setProp("/instrumentation/efb/Keyboard/Output_TMZ_Line", "--:--"); + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", ""); + TMZ_index = 0; + Output_TMz_Line = "--:--"; + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "CHNGS") { + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String")); # Bypasses CHANGEs SIGN + setProp("/instrumentation/efb/VK_keypress", ""); + } + + # Input Field Display + TMZ_String = getProp("/instrumentation/efb/Keyboard/Input_String"); + TMZ_Input_Lenght = size(TMZ_String); + + if (TMZ_Input_Lenght <= 3) { + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String + + if (TMZ_Input_Lenght > 1) { + setProp("/instrumentation/efb/Keyboard/Input_HH_Line", substr(getProp("/instrumentation/efb/Keyboard/Input_String"), 0, 2)); # IF 3rd digit, Print HH to the Keyboard Input Field + setProp("/instrumentation/efb/Keyboard/Output_HH", substr(getProp("/instrumentation/efb/Keyboard/Input_String"), 0, 2)); # Copy HH to Output_HH + setProp("/instrumentation/efb/Keyboard/Input_MM_Line", substr(getProp("/instrumentation/efb/Keyboard/Input_String"), 2, TMZ_Input_Lenght)); # IF 3rd digit, Print MM to the Keyboard Input Field + setProp("/instrumentation/efb/Keyboard/Output_MM", substr(getProp("/instrumentation/efb/Keyboard/Input_String"), 2, TMZ_Input_Lenght)); # Copy MM to Output_MM + setProp("/instrumentation/efb/Keyboard/Input_Zulu_Line", (getProp("/instrumentation/efb/Keyboard/Input_HH_Line") ~ ":" ~ getProp("/instrumentation/efb/Keyboard/Input_MM_Line"))); # IF 3rd digit, Print "zulu Time" to the Keyboard Output "zulu to be converted" Field (see EFB Manual) + } else { + setProp("/instrumentation/efb/Keyboard/Input_HH_Line", getProp("/instrumentation/efb/Keyboard/Input_String")); # Print Blank HH to the Keyboard Input Field + setProp("/instrumentation/efb/Keyboard/Input_MM_Line", "--"); # Print Blank HH to the Keyboard Input Field + setProp("/instrumentation/efb/Keyboard/Input_Zulu_Line", getProp("/instrumentation/efb/Keyboard/Input_HH_Line") ~ ":" ~ getProp("/instrumentation/efb/Keyboard/Input_MM_Line")); # Print Blank "zulu Time" to the Keyboard Output "zulu to be converted" Field (see EFB Manual) # Print "" MM to the Keyboard Input Field + setProp("/instrumentation/efb/Keyboard/Output_HH", ""); + setProp("/instrumentation/efb/Keyboard/Output_MM", ""); + } + + } # an 'else' clause should be set here, giving the Pilot an audible 'WARNING Beep', because we cannot accept more than 4 chars for Time Input! + } + setProp("/instrumentation/efb/VK_keypress", ""); # reset the VK keys to "" + + # ---------------> Output Unit: Input Time Conversion --> TIME ZONES Time + + if (TMZ_Input_Lenght > 1) { + # TMZ_Index = TMZ_Index; + if ((keypress == "r3") and (TMZ_Index > 0)) { + TMZ_Index = TMZ_Index - 1; + keypress = ""; + } # an 'else' clause should be set here, giving the Pilot an audible 'WARNING Beep', because he reached Bottom End of DB File! + if ((keypress == "r4") and (TMZ_Index < TMZ_DB_Size)) { + TMZ_Index = TMZ_Index + 1; + keypress = ""; + } # an 'else' clause should be set here, giving the Pilot an audible 'WARNING Beep', because he reached Top End of DB File! + #setProp("/instrumentation/efb/Keyboard/Output_HH", "12"); + #setProp("/instrumentation/efb/Keyboard/Output_MM", "54"); + if (keypress == "r5") { setProp("/instrumentation/efb/Keyboard/Cnv_Fact", "0"); # RESET ALL + setProp("/instrumentation/efb/Keyboard/Input_String", ""); + TMZ_String = ""; + TMZ_Index = 0; + TMZ_Input_Lenght = 0; + setProp("/instrumentation/efb/Keyboard/Current_DT_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_HH_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_MM_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_Zulu_Line", ""); + setProp("/instrumentation/efb/Keyboard/Output_HH", "0"); + setProp("/instrumentation/efb/Keyboard/Output_MM", "0"); + setProp("/instrumentation/efb/Keyboard/Converted_ID_Line", ""); + setProp("/instrumentation/efb/Keyboard/Converted_Name_Line", "Use Keyboard to Input Time (HHMM)"); + setProp("/instrumentation/efb/Keyboard/Output_TMZ_Line", ""); + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", "0"); + TMZ_index = 0; + Output_TMz_Line = "--:--"; + } + if (getProp("/instrumentation/efb/Keyboard/Output_HH") != "0") { + TMZ_Converted_ID = getProp("/instrumentation/efb/TimeZonesDB/IDX[" ~ TMZ_Index ~ "]/ID"); + TMZ_Converted_Name = getProp("/instrumentation/efb/TimeZonesDB/IDX[" ~ TMZ_Index ~ "]/Name"); + TMZ_zulu_HH = getProp("/instrumentation/efb/Keyboard/Output_HH"); + TMZ_Converted_OffSet = getProp("/instrumentation/efb/TimeZonesDB/IDX[" ~ TMZ_Index ~ "]/OffSet"); + setProp("/instrumentation/efb/Keyboard/Converted_ID_Line", TMZ_Converted_ID); # Print Time Zone ID to the Keyboard Converted Time Field + setProp("/instrumentation/efb/Keyboard/Converted_Name_Line", TMZ_Converted_Name); # Print Time Zone Name to the Keyboard Converted Time Field + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", (TMZ_zulu_HH + TMZ_Converted_OffSet)); + } else { + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", 0); + } + # HH Corrections for Time Zone's Conversion Factors + if (getProp("/instrumentation/efb/Keyboard/Cnv_Fact") > 9) { + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", getProp("/instrumentation/efb/Keyboard/Cnv_Fact")); # Print HH Converted Time to the Keyboard Converted Time Field + } elsif (((getProp("/instrumentation/efb/Keyboard/Cnv_Fact") >= 0) and (getProp("/instrumentation/efb/Keyboard/Cnv_Fact") <= 9))) { + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", "0" ~ getProp("/instrumentation/efb/Keyboard/Cnv_Fact")); # Print H Converted Time to the Keyboard Converted Time Field + } elsif (getProp("/instrumentation/efb/Keyboard/Cnv_Fact") < 0) { + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", (24 + getProp("/instrumentation/efb/Keyboard/Cnv_Fact"))); # Print (24 - HH) Converted Time to the Keyboard Converted Time Field + } + } else { + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", "--"); + } + # Output Converted Time Field Display + if ((getProp("/instrumentation/efb/Keyboard/Input_HH_Line") == "") or (getProp("/instrumentation/efb/Keyboard/Input_HH_Line") == ".") or (getProp("/instrumentation/efb/Keyboard/Input_HH_Line") == "--")) { + setProp("/instrumentation/efb/Keyboard/Output_TMZ_Line", ""); + Output_TMz_Line = "--:--"; + } else { + Output_TMZ_Line = getProp("/instrumentation/efb/Keyboard/Cnv_Fact"); + Output_TMZ_Line = substr(Output_TMZ_Line, 0, 2) ~ ":" ~ getProp("/instrumentation/efb/Keyboard/Output_MM");# Build the Output String + } + setProp("/instrumentation/efb/Keyboard/Output_TMZ_Line", Output_TMZ_Line); # Print it to the Keyboard Output Converted Time Field + + if (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/page", "UTILITIES"); + setProp("/instrumentation/efb/Keyboard/Current_DT_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_HH_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_MM_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_Zulu_Line", ""); + setProp("/instrumentation/efb/Keyboard/Cnv_Fact", ""); + setProp("/instrumentation/efb/Keyboard/Output_HH", ""); + setProp("/instrumentation/efb/Keyboard/Output_MM", ""); + setProp("/instrumentation/efb/Keyboard/Converted_ID_Line", ""); + setProp("/instrumentation/efb/Keyboard/Converted_Name_Line", ""); + setProp("/instrumentation/efb/Keyboard/Output_TMZ_Line", ""); + setProp("/instrumentation/efb/Keyboard/Input_String", ""); + + keypress = ""; + } + + #__________________________________________________________________________________________ + # PILOT UTILITIES - DESCENT RATE Calculator ----------------------------------------------| + #_________________________________________________________________________________________| + } elsif (currentPage == "UTILITIES_DESC_RATE") { + + page.clearpage(); + # Input keys Check + if (keypress == "l2") { + setProp("/instrumentation/efb/Input_Unit", "Initial_FL"); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/DRC_Initial_FL_MEM", getProp("/instrumentation/efb/DRC_Initial_FL")); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 1); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 0); + } + elsif (keypress == "r2") { + setProp("/instrumentation/efb/Input_Unit", "Target_FL"); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/DRC_Target_FL_MEM", getProp("/instrumentation/efb/DRC_Target_FL")); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 1); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 0); + } + elsif (keypress == "l3") { + setProp("/instrumentation/efb/Input_Unit", "Initial_GS"); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/DRC_Initial_GS_MEM", getProp("/instrumentation/efb/DRC_Initial_GS")); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 2); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 0); + } + elsif (keypress == "r3") { + setProp("/instrumentation/efb/Input_Unit", "Target_GS"); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/DRC_Target_GS_MEM", getProp("/instrumentation/efb/DRC_Target_GS")); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 2); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 0); + } + elsif (keypress == "l4") { + setProp("/instrumentation/efb/Input_Unit", "Distance"); + setProp("/instrumentation/efb/Keyboard/Input_String",""); + setProp("/instrumentation/efb/DRC_Distance_MEM", getProp("/instrumentation/efb/DRC_Distance")); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 3); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 0); + } + + # Input keys Parser + if ((getProp("/instrumentation/efb/VK_keypress") != "") and (getProp("/instrumentation/efb/VK_keypress") != ".") and (getProp("/instrumentation/efb/VK_keypress") != "CHNGS") and (getProp("/instrumentation/efb/Input_Unit") != "NO_INPUT")) { + if (getProp("/instrumentation/efb/VK_keypress") == "CLEAR") { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + VK_Key = "VOID"; + setProp("/instrumentation/efb/VK_keypress", ""); + } + elsif (getProp("/instrumentation/efb/VK_keypress") == "BKSP") { + Temp_String = getProp("/instrumentation/efb/Keyboard/Input_String"); # BACKSPACEs the Input Field + lenght = size(Temp_String) - 1; + if (lenght >= 1) { + setProp("/instrumentation/efb/Keyboard/Input_String", substr(Temp_String, 0, lenght)); + setProp("/instrumentation/efb/VK_keypress", ""); + } elsif (lenght <= 0) { + setProp("/instrumentation/efb/Keyboard/Input_String", ""); # CLEARs the whole Input Field + VK_Key = "VOID"; + } + } + DRC_String = getProp("/instrumentation/efb/Keyboard/Input_String"); + DRC_Input_Lenght = size(DRC_String); + + if (DRC_Input_Lenght < 3) { + if (VK_Key != "VOID") { + setProp("/instrumentation/efb/Keyboard/Input_String", getProp("/instrumentation/efb/Keyboard/Input_String") ~ getProp("/instrumentation/efb/VK_keypress")); # Build the Input String... + } + if ((getProp("/instrumentation/efb/Input_Unit") == "Initial_FL") and (VK_Key != "VOID")) { + setProp("/instrumentation/efb/DRC_Initial_FL", getProp("/instrumentation/efb/Keyboard/Input_String")); # ...For Initial FL + } elsif ((getProp("/instrumentation/efb/Input_Unit") == "Initial_FL") and (VK_Key == "VOID")) { + setProp("/instrumentation/efb/display/DRC_l3", "CLEAR"); + setProp("/instrumentation/efb/DRC_Initial_FL", getProp("/instrumentation/efb/DRC_Initial_FL_MEM")); + } + if ((getProp("/instrumentation/efb/Input_Unit") == "Target_FL") and (VK_Key != "VOID")) { + setProp("/instrumentation/efb/DRC_Target_FL", getProp("/instrumentation/efb/Keyboard/Input_String")); # ...For Target FL + } elsif ((getProp("/instrumentation/efb/Input_Unit") == "Target_FL") and (VK_Key == "VOID")) { + setProp("/instrumentation/efb/display/DRC_r3", "CLEAR"); + setProp("/instrumentation/efb/DRC_Target_FL", getProp("/instrumentation/efb/DRC_Target_FL_MEM")); + } + if ((getProp("/instrumentation/efb/Input_Unit") == "Initial_GS") and (VK_Key != "VOID")) { + setProp("/instrumentation/efb/DRC_Initial_GS", getProp("/instrumentation/efb/Keyboard/Input_String")); # ...For Initial GS + } elsif ((getProp("/instrumentation/efb/Input_Unit") == "Initial_GS") and (VK_Key == "VOID")) { + setProp("/instrumentation/efb/display/DRC_l5", "CLEAR"); + setProp("/instrumentation/efb/DRC_Initial_GS", getProp("/instrumentation/efb/DRC_Initial_GS_MEM")); + } + if ((getProp("/instrumentation/efb/Input_Unit") == "Target_GS") and (VK_Key != "VOID")) { + setProp("/instrumentation/efb/DRC_Target_GS", getProp("/instrumentation/efb/Keyboard/Input_String")); # ...For Target GS + } elsif ((getProp("/instrumentation/efb/Input_Unit") == "Target_GS") and (VK_Key == "VOID")) { + setProp("/instrumentation/efb/display/DRC_r5", "CLEAR"); + setProp("/instrumentation/efb/DRC_Target_GS", getProp("/instrumentation/efb/DRC_Target_GS_MEM")); + } + if ((getProp("/instrumentation/efb/Input_Unit") == "Distance") and (VK_Key != "VOID")) { + setProp("/instrumentation/efb/DRC_Distance", getProp("/instrumentation/efb/Keyboard/Input_String")); # ...For Distance + } elsif ((getProp("/instrumentation/efb/Input_Unit") == "Distance") and (VK_Key == "VOID")) { + setProp("/instrumentation/efb/display/DRC_l7", "CLEAR"); + setProp("/instrumentation/efb/DRC_Distance", getProp("/instrumentation/efb/DRC_Distance_MEM")); + } + } + } + setProp("/instrumentation/efb/VK_keypress", ""); # reset the VK keys to "" + VK_Key = ""; + + # Transfers Values to DRC variables as numbers + Initial_FL = num(getProp("/instrumentation/efb/DRC_Initial_FL")); + Target_FL = num(getProp("/instrumentation/efb/DRC_Target_FL")); + Initial_GS = num(getProp("/instrumentation/efb/DRC_Initial_GS")); + Target_GS = num(getProp("/instrumentation/efb/DRC_Target_GS")); + DRC_Distance = num(getProp("/instrumentation/efb/DRC_Distance")); + + # Calculates Formulas + # Formula: [Angle of Descent (ft/NM) = ALT Gradient/Distance] |||| [SPD Factor (ft/min) = SPD Gradient/60] |||| [Target Descent Rate (Fpm) = Angle of Descent * SPD Factor] + + var DRC_Angle = (Target_FL - Initial_FL)/DRC_Distance; + var DRC_AvgSpeed = (Initial_GS + Target_GS)/2; + var DRC_Fact = DRC_AvgSpeed/60; + var DRC_Output = DRC_Angle * DRC_Fact*100; + var DRC_Time = (Target_FL - Initial_FL)/(DRC_Output/100); + + # Prepares Output Strings + DRC_l3 = substr(getProp("/instrumentation/efb/DRC_Initial_FL"), 0, 3); + CUT = split(".", DRC_l3); + DRC_l3 = CUT[0]; + + DRC_r3 = substr(getProp("/instrumentation/efb/DRC_Target_FL"), 0, 3); + CUT = split(".", DRC_r3); + DRC_r3 = CUT[0]; + + DRC_l5 = substr(getProp("/instrumentation/efb/DRC_Initial_GS"), 0, 3); + CUT = split(".", DRC_l5); + DRC_l5 = CUT[0]; + + DRC_r5 = substr(getProp("/instrumentation/efb/DRC_Target_GS"), 0, 3); + CUT = split(".", DRC_r5); + DRC_r5 = CUT[0]; + + DRC_l7 = substr(getProp("/instrumentation/efb/DRC_Distance"), 0, 3); + CUT = split(".", DRC_l7); + DRC_l7 = CUT[0]; + + setProp("/instrumentation/efb/DRC_Output", "100"); + setProp("/instrumentation/efb/DRC_Output", DRC_Output); + DRC_r8 = substr(getProp("/instrumentation/efb/DRC_Output"), 0, 8); + CUT = split(".", DRC_r8); + DRC_r8 = CUT[0]; + + setProp("/instrumentation/efb/DRC_Angle", "100"); + setProp("/instrumentation/efb/DRC_Angle", DRC_Angle); + DRC_r9 = substr(getProp("/instrumentation/efb/DRC_Angle"), 0, 5); + # CUT = split(".", DRC_r9); + # DRC_r9 = CUT[0]; + + setProp("/instrumentation/efb/DRC_Time", "100"); + setProp("/instrumentation/efb/DRC_Time", DRC_Time); + DRC_r10 = substr(getProp("/instrumentation/efb/DRC_Time"), 0, 5); + #CUT = split(".", DRC_r10); + #DRC_r10 = CUT[0]; + + + page.DRCupdate(); # Displays Output + + if (keypress == "MENU") { + page.DRCclearpage(); + page.DRCupdate(); + setProp("/sim/model/efb/page", "Displays/PU_1.jpg"); + setProp("/instrumentation/efb/VK_DRC_MarkerR", 0); + setProp("/instrumentation/efb/VK_DRC_MarkerL", 0); + setProp("/instrumentation/efb/page", "UTILITIES"); + keypress = ""; + } + #__________________________________________________________________________________________ + # PILOT UTILITIES - NORMAL PROCEDURES MANUAL ----------------------------------------------| + #__________________________________________________________________________________________| + } elsif (currentPage == "NORM PROC MANUAL") { + page.clearpage(); + + if (keypress == "PGUP") { + setProp("/instrumentation/efb/manual-page", getProp("/instrumentation/efb/manual-page") - 0.20); + keypress = ""; + } + elsif (keypress == "ScrollUP") { + setProp("/instrumentation/efb/manual-page", getProp("/instrumentation/efb/manual-page") - 0.02); + keypress = ""; + } + elsif (keypress == "ScrollDN") { + setProp("/instrumentation/efb/manual-page", getProp("/instrumentation/efb/manual-page") + 0.02); + keypress = ""; + } + elsif (keypress == "PGDN") { + setProp("/instrumentation/efb/manual-page", getProp("/instrumentation/efb/manual-page") + 0.20); + keypress = ""; + } + elsif (keypress == "MENU") { + setProp("/sim/model/efb/page", "Displays/Documents_1.jpg"); + setProp("/instrumentation/efb/page", "DOCUMENTS"); + keypress = ""; + } + } + #___________________________________________________________________________________________ + #_______________________________END of Parsers & SubParsers_________________________________| + page.update(); + if ((getProp("/instrumentation/efb/page") == "Airport Charts") or (getProp("/instrumentation/efb/page") == "Airport Diagram") or (getProp("/instrumentation/efb/page") == "NORM PROC MANUAL")) setProp("/instrumentation/efb/text-color", 0); + else setProp("/instrumentation/efb/text-color", 1); + }, + reset : func { + if(!me.efbTimer) + me.efbTimer = maketimer(me.UPDATE_INTERVAL, func me.update()); + else + me.efbTimer.stop(); + me.loopid += 1; + #//me._loop_(me.loopid); + me.efbTimer.start(); + }, + #//_loop_ : func() { + #// id == me.loopid or return; + #// me.update(); + #//} +}; + +var toggle = func(property) { + if (getProp(property) == 1) + setProp(property, 0); + else + setProp(property, 1); +} +setlistener("sim/signals/fdm-initialized", func {efb.init();}); diff --git a/test/final.nas b/test/final.nas new file mode 100644 index 0000000..ac5d13c --- /dev/null +++ b/test/final.nas @@ -0,0 +1,210 @@ +var smartScreen = canvas.new({ + "name": "smartScreen", # The name is optional but allow for easier identification + "size": [2048, 2048], # Size of the underlying texture (should be a power of 2, required) [Resolution] + "view": [768, 768], # Virtual resolution (Defines the coordinate system of the canvas [Dimensions] + # which will be stretched the size of the texture, required) + "mipmapping": 1 # Enable mipmapping (optional) +}); + +smartScreen.addPlacement({"node": "screen", "texture": "screen.jpeg"}); +var group = smartScreen.createGroup(); + +# Create a text element and set some values +var text = group.createChild("text", "optional-id-for element") + .setTranslation(10, 20) # The origin is in the top left corner + .setAlignment("left-center") # All values from osgText are supported (see $FG_ROOT/Docs/README.osgtext) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") # Fonts are loaded either from $AIRCRAFT_DIR/Fonts or $FG_ROOT/Fonts + .setFontSize(14, 1.2) # Set fontsize and optionally character aspect ratio + .setColor(1,0,0) # Text color + .setText("This is a text element"); +text.hide(); +text.setText("SELF TEST NORMAL").show(); + + + +var ui_root = smartScreen.createGroup(); +var vbox = canvas.VBoxLayout.new(); +smartScreen.setLayout(vbox); + + +var button_onl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Online OSM").listen("clicked", func showOnlineMap()); +var button_offl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Offline OSM").listen("clicked", func showOfflineMap()); +button_onl.setSizeHint([32, 128]); +button_offl.setSizeHint([32, 128]); + +var label = canvas.gui.widgets.Label.new(ui_root, canvas.style, {}); + +var button_box = canvas.HBoxLayout.new(); +button_box.addItem(button_onl); +button_box.addItem(button_offl); +button_box.addItem(label); +button_box.addStretch(1); + +vbox.addItem(button_box); +vbox.addStretch(1); + + +var showOnlineMap = func(){ + TestMap.show(); + g.hide(); + label.setText("Online Mode"); +} + + +var showOfflineMap = func(){ + TestMap.hide(); + g.show(); + label.setText("Offline Mode"); +} + + +# Online Map using MapStructure +var TestMap = smartScreen.createGroup().createChild("map"); +TestMap.setTranslation(smartScreen.get("view[0]")/2,smartScreen.get("view[1]")/2); + + +var ctrl_ns = canvas.Map.Controller.get("Aircraft position"); +var source = ctrl_ns.SOURCES["map-dialog"]; +if (source == nil) { + # TODO: amend + var source = ctrl_ns.SOURCES["map-dialog"] = { + getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),# ? ? ? + getAltitude: func getprop('/position/altitude-ft'), + getHeading: func { + if (me.aircraft_heading) + getprop('/orientation/heading-deg'); + else + 0; + }, + aircraft_heading: 1, + }; +} +setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n){source.aircraft_heading = n.getBoolValue();}, 1); +TestMap.setController("Aircraft position", "map-dialog"); +TestMap.setRange(1); + +var r = func(name,vis=1,zindex=nil){return caller(0)[0];}; +# TODO: we'll need some z-indexing here, right now it's just random + +foreach(var type; [r('APS')] ){ + TestMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: 2); +} + +foreach(var type; [ r('OSM')]) { + TestMap.addLayer(factory: canvas.OverlayLayer, + type_arg: type.name, + visible: type.vis, + priority: 1); +} + + +TestMap.hide(); + +# Offline map + +var g = smartScreen.createGroup(); +var zoom = 15; +var type = "intl"; +var tile_size = 256; + + +var changeZoom = func(d) +{ + zoom = math.max(2, math.min(19, zoom + d)); + updateTiles(); +} + +# http://polymaps.org/docs/ +# https://github.com/simplegeo/polymaps +# https://github.com/Leaflet/Leaflet + +var maps_base = getprop("/sim/fg-home") ~ '/cache/maps'; + +var makePath = +string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.jpg'); +var num_tiles = [4, 4]; + +var center_tile_offset = [(num_tiles[0]-1)/2, (num_tiles[1]-1)/ 2]; + +# simple aircraft icon at current position/center of the map +g.createChild("path") + .moveTo( tile_size*center_tile_offset[0]-10, tile_size*center_tile_offset[1]) + .horiz(20) + .move(-10,-10) + .vert(20) + .set("stroke", "red") + .set("stroke-width", 2) + .set("z-index", 1); + +# initialize the map by setting up +# a grid of raster images + +var tiles = setsize([], num_tiles[0]); +for(var x=0; x me.old) { + me.pos_flank(1); + } elsif (val < me.old) { + me.neg_flank(1); + } + } elsif (me.old == -1) { + if (val > me.old) { + me.neg_flank(0); + } + } + me.old = val; +} + +############################################################ +# StableTrigger: Triggers an action when a MPP property +# becomes stable (i.e. doesn't change for +# MIN_STABLE seconds). +# src - MP prop : property node +# action - action to take when the value becomes stable : [func(v)] +# An action is triggered when value has stabilized. +var StableTrigger = {}; +StableTrigger.new = func (src, action) { + var obj = { parents : [StableTrigger], + src : src, + action : action, + old : 0, + stable_since : 0, + wait : 0, + MIN_STABLE : 0.01 }; + # Error checking. + var bad = (obj.src == nil) or (action = nil); + + if (bad) { + print("StableTrigger["); + print(" ", debug.string(obj.src)); + print(" ", debug.string(obj.action)); + print("]"); + fail(); + } + + return obj; +} +StableTrigger.update = func () { + var v = me.src.getValue(); + if (!is_num(v)) return; + var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time. + + if ((me.old == v) and + ((t - me.stable_since) > me.MIN_STABLE) and (me.wait == 1)) { + # Trigger action. + me.action(v); + + me.wait = 0; + } elsif (me.old == v) { + # Wait. This is either before the signal is stable or after the action. + } else { + me.stable_since = t; + me.wait = 1; + me.old = me.src.getValue(); + } +} + +############################################################ +# Selects the most recent value of two properties. +# src1 - : property node +# src2 - : property node +# dest - : property node +# threshold - : double +var MostRecentSelector = {}; +MostRecentSelector.new = func (src1, src2, dest, threshold) { + var obj = { parents : [MostRecentSelector], + old1 : 0, + old2 : 0, + src1 : src1, + src2 : src2, + dest : dest, + thres : threshold }; + if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) { + print("MostRecentSelector["); + print(" ", debug.string(obj.src1)); + print(" ", debug.string(obj.src2)); + print(" ", debug.string(obj.dest)); + print("]"); + } + + return obj; +} +MostRecentSelector.update = func { + var v1 = me.src1.getValue(); + var v2 = me.src2.getValue(); + if (!is_num(v1) and !is_num(v2)) return; + elsif (!is_num(v1)) me.dest.setValue(v2); + elsif (!is_num(v2)) me.dest.setValue(v1); + else { + if (abs (v2 - me.old2) > me.thres) { + me.old2 = v2; + me.dest.setValue(me.old2); + } + if (abs (v1 - me.old1) > me.thres) { + me.old1 = v1; + me.dest.setValue(me.old1); + } + } +} + +############################################################ +# Adds two input properties. +# src1 - : property node +# src2 - : property node +# dest - : property node +var Adder = {}; +Adder.new = func (src1, src2, dest) { + var obj = { parents : [DeltaAccumulator], + src1 : src1, + src2 : src2, + dest : dest }; + if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) { + print("Adder["); + print(" ", debug.string(obj.src1)); + print(" ", debug.string(obj.src2)); + print(" ", debug.string(obj.dest)); + print("]"); + fail(); + } + + return obj; +} +Adder.update = func () { + var v1 = me.src1.getValue(); + var v2 = me.src2.getValue(); + if (!is_num(v1) or !is_num(v2)) return; + me.dest.setValue(v1 + v2); +} + +############################################################ +# Adds the delta of src to dest. +# src - : property node +# dest - : property node +var DeltaAdder = {}; +DeltaAdder.new = func (src, dest) { + var obj = { parents : [DeltaAdder], + old : 0, + src : src, + dest : dest }; + if (obj.src == nil or obj.dest == nil) { + print("DeltaAdder[", debug.string(obj.src), ", ", + debug.string(obj.dest), "]"); + fail(); + } + + return obj; +} +DeltaAdder.update = func () { + var v = me.src.getValue(); + if (!is_num(v)) return; + me.dest.setValue((v - me.old) + me.dest.getValue()); + me.old = v; +} + +############################################################ +# Switch encoder: Encodes upto 32 boolean properties in one +# int property. +# inputs - list of property nodes +# dest - where the bitmask is stored : property node +var SwitchEncoder = {}; +SwitchEncoder.new = func (inputs, dest) { + var obj = { parents : [SwitchEncoder], + inputs : inputs, + dest : dest }; + # Error checking. + var bad = (obj.dest == nil); + foreach (var i; inputs) { + if (i == nil) { bad = 1; } + } + + if (bad) { + print("SwitchEncoder["); + foreach (var i; inputs) { + print(" ", debug.string(i)); + } + print(" ", debug.string(obj.dest)); + print("]"); + fail(); + } + + return obj; +} +SwitchEncoder.update = func () { + var v = 0; + var b = 1; + forindex (var i; me.inputs) { + if (me.inputs[i].getBoolValue()) { + v = v + b; + } + b *= 2; + } + me.dest.setIntValue(v); +} + +############################################################ +# Switch decoder: Decodes a bitmask in an int property. +# src - : property node +# actions - list of actions : [func(b)] +# Actions are triggered when their input bit change. +# Due to interpolation the decoder needs to wait for a +# stable input value. +var SwitchDecoder = {}; +SwitchDecoder.new = func (src, actions) { + var obj = { parents : [SwitchDecoder], + wait : 0, + old : 0, + old_stable : 0, + stable_since : 0, + reset : 1, + src : src, + actions : actions, + MIN_STABLE : 0.1 }; + # Error checking. + var bad = (obj.src == nil); + foreach (var a; obj.actions) { + if (a == nil) { bad = 1; } + } + + if (bad) { + print("SwitchDecoder["); + print(" ", debug.string(obj.src)); + foreach (var a; obj.actions) { + print(" ", debug.string(a)); + } + print("]"); + fail(); + } + + return obj; +} +SwitchDecoder.update = func () { + var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time. + var v = me.src.getValue(); + if (!is_num(v)) return; + + if ((me.old == v) and ((t - me.stable_since) > me.MIN_STABLE) and + (me.wait == 1)) { + var ov = me.old_stable; +# Use this to improve. +# here's the boring version: var bittest = func(u, b) { while (b) { u = int(u / 2); b -= 1; } u != int(u / 2) * 2; } + forindex (var i; me.actions) { + var m = math.mod(v, 2); + var om = math.mod(ov, 2); + if ((m != om or me.reset)) { me.actions[i](m?1:0); } + v = (v - m)/2; + ov = (ov - om)/2; + } + me.old_stable = me.src.getValue(); + me.wait = 0; + me.reset = 0; + } elsif (me.old == v) { + # Wait. This is either before the bitmask is stable or after + # it has been processed. + } else { + me.stable_since = t; + me.wait = 1; + me.old = me.src.getValue(); + } +} + +############################################################ +# Time division multiplexing encoder: Transmits a list of +# properties over a MP enabled string property. +# inputs - input properties : [property node] +# dest - MP string prop : property node +# Note: TDM can have high latency so it is best used for +# non-time critical properties. +var TDMEncoder = {}; +TDMEncoder.new = func (inputs, dest) { + var obj = { parents : [TDMEncoder], + inputs : inputs, + channel : MessageChannel.new(dest, + func (msg) { + print("This should not happen!"); + }), + MIN_INT : 0.25, + last_time : 0, + next_item : 0, + old : [] }; + # Error checking. + var bad = (dest == nil) or (obj.channel == nil); + foreach (var i; inputs) { + if (i == nil) { bad = 1; } + } + + if (bad) { + print("TDMEncoder["); + foreach (var i; inputs) { + print(" ", debug.string(i)); + } + print(" ", debug.string(dest)); + print("]"); + } + + setsize(obj.old, size(obj.inputs)); + + return obj; +} +TDMEncoder.update = func () { + var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time. + if (t > me.last_time + me.MIN_INT) { + var n = size(me.inputs); + while (1) { + var v = me.inputs[me.next_item].getValue(); + + if ((n <= 0) or (me.old[me.next_item] != v)) { + # Set the MP properties to send the next item. + me.channel.send(Binary.encodeByte(me.next_item) ~ + Binary.encodeDouble(v)); + + me.old[me.next_item] = v; + + me.last_time = t; + me.next_item += 1; + if (me.next_item >= size(me.inputs)) { me.next_item = 0; } + return; + } else { + # Search for changed property. + n -= 1; + me.next_item += 1; + if (me.next_item >= size(me.inputs)) { me.next_item = 0; } + } + } + } +} + +############################################################ +# Time division multiplexing decoder: Receives a list of +# properties over a MP enabled string property. +# src - MP string prop : property node +# actions - list of actions : [func(v)] +# An action is triggered when its value is received. +# Note: TDM can have high latency so it is best used for +# non-time critical properties. +var TDMDecoder = {}; +TDMDecoder.new = func (src, actions) { + var obj = { parents : [TDMDecoder], + actions : actions }; + obj.channel = MessageChannel.new(src, + func (msg) { + obj.process(msg); + }); + + # Error checking. + var bad = (src == nil) or (obj.channel == nil); + foreach (var a; actions) { + if (a == nil) { bad = 1; } + } + + if (bad) { + print("TDMDecoder["); + print(" ", debug.string(src)); + foreach (var a; actions) { + print(" ", debug.string(a)); + } + print("]"); + fail(); + } + + return obj; +} +TDMDecoder.process = func (msg) { + var v1 = Binary.decodeByte(msg); + var v2 = Binary.decodeDouble(substr(msg, 1)); + # Trigger action. + me.actions[v1](v2); +} +TDMDecoder.update = func { + me.channel.update(); +} + +############################################################################### +# Internal utility functions + +var is_num = func (v) { + return num(v) != nil; +} + +# fail causes a Nasal runtime error so we get a backtrace. +var fail = func { + error_detected_in_calling_context(); +} + +############################################################################### + +############################################################################### +# Copilot selection dialog. +# +# Usage: dual_control_tools.copilot_dialog.show(); +# +var COPILOT_DLG = 0; +var copilot_dialog = {}; +############################################################ +copilot_dialog.init = func (copilot_type, x = nil, y = nil) { + me.x = x; + me.y = y; + me.bg = [0, 0, 0, 0.3]; # background color + me.fg = [[1.0, 1.0, 1.0, 1.0]]; + # + # "private" + if (contains(aircraft_dual_control, "copilot_view")) { + me.title = "Pilot selection"; + } else { + me.title = "Copilot selection"; + } + me.basenode = props.globals.getNode("sim/remote", 1); + me.dialog = nil; + me.namenode = props.Node.new({"dialog-name" : me.title }); + me.listeners = []; + me.copilot_type = copilot_type; +} +############################################################ +copilot_dialog.create = func { + if (me.dialog != nil) + me.close(); + + me.dialog = gui.Widget.new(); + me.dialog.set("name", me.title); + if (me.x != nil) + me.dialog.set("x", me.x); + if (me.y != nil) + me.dialog.set("y", me.y); + + me.dialog.set("layout", "vbox"); + me.dialog.set("default-padding", 0); + var titlebar = me.dialog.addChild("group"); + titlebar.set("layout", "hbox"); + titlebar.addChild("empty").set("stretch", 1); + if (contains(aircraft_dual_control, "copilot_view")) { + titlebar.addChild("text").set("label", "Book your flight"); + } else { + titlebar.addChild("text").set("label", "Passengers online"); + } + var w = titlebar.addChild("button"); + w.set("pref-width", 16); + w.set("pref-height", 16); + w.set("legend", ""); + w.set("default", 0); + w.set("key", "esc"); + w.setBinding("nasal", "dual_control_tools.copilot_dialog.destroy(); "); + w.setBinding("dialog-close"); + me.dialog.addChild("hrule"); + + var content = me.dialog.addChild("group"); + content.set("layout", "vbox"); + content.set("halign", "center"); + content.set("default-padding", 5); + + # Generate the dialog contents. + me.players = me.find_copilot_players(); + var i = 0; + var tmpbase = me.basenode.getNode("dialog", 1); + var selected = me.basenode.getNode("pilot-callsign").getValue(); + foreach (var p; me.players) { + var tmp = tmpbase.getNode("b[" ~ i ~ "]", 1); + tmp.setBoolValue(streq(selected, p)); + var w = content.addChild("checkbox"); + w.node.setValues({"label" : p, + "halign" : "left", + "property" : tmp.getPath()}); + w.setBinding + ("nasal", + "dual_control_tools.copilot_dialog.select_action(" ~ i ~ ");"); + i = i + 1; + } + me.dialog.addChild("hrule"); + + # Display the dialog. + fgcommand("dialog-new", me.dialog.prop()); + fgcommand("dialog-show", me.namenode); +} +############################################################ +copilot_dialog.close = func { + fgcommand("dialog-close", me.namenode); +} +############################################################ +copilot_dialog.destroy = func { + COPILOT_DLG = 0; + me.close(); + foreach(var l; me.listeners) + removelistener(l); + delete(gui.dialog, "\"" ~ me.title ~ "\""); +} +############################################################ +copilot_dialog.show = func (copilot_type) { +# print("Showing MPCopilots dialog!"); + if (!COPILOT_DLG) { + COPILOT_DLG = int(getprop("/sim/time/elapsed-sec")); + me.init(copilot_type); + me.create(); + me._update_(COPILOT_DLG); + } +} +############################################################ +copilot_dialog._redraw_ = func { + if (me.dialog != nil) { + me.close(); + me.create(); + } +} +############################################################ +copilot_dialog._update_ = func (id) { + if (COPILOT_DLG != id) return; + me._redraw_(); + settimer(func { me._update_(id); }, 4.1); +} +############################################################ +copilot_dialog.select_action = func (n) { + var selected = me.basenode.getNode("pilot-callsign").getValue(); + var bs = me.basenode.getNode("dialog").getChildren(); + # Assumption: There are two true b:s or none. The one not matching selected + # is the new selection. + var i = 0; + me.basenode.getNode("pilot-callsign").setValue(""); + foreach (var b; bs) { + if (!b.getValue() and (i == n)) { + b.setValue(1); + me.basenode.getNode("pilot-callsign").setValue(me.players[i]); + } else { + b.setValue(0); + } + i = i + 1; + } + dual_control.main.reset(); + me._redraw_(); +} +############################################################ +# Return a list containing all nearby copilot players of the right type. +copilot_dialog.find_copilot_players = func { + var mpplayers = + props.globals.getNode("ai/models").getChildren("multiplayer"); + + var res = []; + foreach (var pilot; mpplayers) { + if ((pilot.getNode("valid") != nil) and + (pilot.getNode("valid").getValue()) and + (pilot.getNode("sim/model/path") != nil)) { + var type = pilot.getNode("sim/model/path").getValue(); + + if (type == me.copilot_type) { + append(res, pilot.getNode("callsign").getValue()); + } + } + } +# debug.dump(res); + return res; +} +############################################################################### diff --git a/test/json.nas b/test/json.nas new file mode 100644 index 0000000..8ed0a33 --- /dev/null +++ b/test/json.nas @@ -0,0 +1,195 @@ +#lib json.nas +var json={ + text:'', + line:1, + size:0, + ptr:0, + get:nil, + check:nil, + next:nil, + match:nil, + hash_gen:nil, + vec_gen:nil, + member:nil, + parse:nil, + token:{content:'',type:''}, + content:[], +}; + +json.get=func(filename) +{ + me.line=1; + me.ptr=0; + me.content=[]; + me.token={content:'',type:''}; + me.text=io.fin(filename); + if(!size(me.text)) + die("cannot open "~filename); + me.text=split('',me.text); + me.size=size(me.text); + return; +} + +json.check=func(ptr) +{ + var str=me.text[ptr]; + return (str=='{' or str=='}' or str=='[' or str==']' or str==',' or str==':' or str=='\"' or ('0'<=str and str<='9')); +} + +json.next=func() +{ + while(me.ptr=me.size) + { + me.token.content=""; + me.token.type="eof"; + return; + } + + if(me.text[me.ptr]=='{') + { + me.token.content='{'; + me.token.type="left brace"; + } + elsif(me.text[me.ptr]=='}') + { + me.token.content='}'; + me.token.type="right brace"; + } + elsif(me.text[me.ptr]=='[') + { + me.token.content='['; + me.token.type="left bracket"; + } + elsif(me.text[me.ptr]==']') + { + me.token.content=']'; + me.token.type="right bracket"; + } + elsif(me.text[me.ptr]==',') + { + me.token.content=','; + me.token.type="comma"; + } + elsif(me.text[me.ptr]==':') + { + me.token.content=':'; + me.token.type="colon"; + } + elsif(me.text[me.ptr]=='\"') + { + var s=""; + me.ptr+=1; + while(me.ptr=i;i+=1) -{ - print(i); -} -foreach(var i;[1+(1+1),2,3,4]) -{ - print(i); -} -forindex(var i=list;[1,2,3,4]) -{ - print(i[0]); -} -while(!id) -{ - print("yes"); -} \ No newline at end of file diff --git a/test/main.nas b/test/main.nas new file mode 100644 index 0000000..cab6aed --- /dev/null +++ b/test/main.nas @@ -0,0 +1,382 @@ +# game left in corner by ValKmjolnir +# 2020 + +# lib function defined here +var print=func(elements...) +{ + nasal_call_builtin_std_cout(elements); + return nil; +}; +var append=func(vector,elements...) +{ + nasal_call_builtin_push_back(vector,elements); + return nil; +} +var setsize=func(vector,size) +{ + nasal_call_builtin_set_size(vector,size); + return nil; +} +var system=func(str) +{ + nasal_call_builtin_system(str); + return; +} +var sleep=func(duration) +{ + nasal_call_builtin_sleep(duration); + return; +} +var input=func() +{ + return nasal_call_builtin_input(); +} +var io= +{ + fin:func(filename) + { + return nasal_call_builtin_finput(filename); + }, + fout:func(filename,str) + { + nasal_call_builtin_foutput(filename,str); + return; + } +}; +var int=func(str) +{ + return str+0; +} +var str=func(num) +{ + return num~''; +} +# string split + +# game elements defined here +var role_property= +{ + health:100, + mood:100, + satiety:100, + thirst:100, + health_change:func(x) + { + me.health+=x; + if(me.health<0) + me.health=0; + elsif(me.health>100) + me.health=100; + return nil; + }, + mood_change:func(x) + { + me.mood+=x; + if(me.mood<0) + me.mood=0; + elsif(me.mood>100) + me.mood=100; + return nil; + }, + satiety_change:func(x) + { + me.satiety+=x; + if(me.satiety<0) + me.satiety=0; + elsif(me.satiety>100) + me.satiety=100; + return nil; + }, + thirst_change:func(x) + { + me.thirst+=x; + if(me.thirst<0) + me.thirst=0; + elsif(me.thirst>100) + me.thirst=100; + return nil; + } +}; +var screen= +{ + picture:[], + info_below_left:[], + info_below_right:[], + clear:func() + { + me.picture=[]; + me.info_below_left=[]; + me.info_below_right=[]; + return; + }, + pic_addline:func(_str) + { + append(me.picture,_str); + return; + }, + left_add:func(_str) + { + append(me.info_below_left,_str); + return; + }, + right_add:func(_str) + { + append(me.info_below_right,_str); + return; + }, + prt_screen:func() + { + foreach(var i;me.picture) + print(i); + forindex(var i;me.info_below_left) + print(me.info_below_left[i]~me.info_below_right[i]); + return; + } +}; +var first_shown_info=func() +{ + system("cls"); + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| Let me tell you a story... |", + "| A story that really happened many years ago...|", + "| Nearly no one knows and cares about it... |", + "| But some children may still suffer from... |", + "| This kind of stories... |", + "| And this kind of stories never stop hurting...|", + "| People that are still alive... |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + print(i); + return; +} +var generate_role_property=func() +{ + screen.left_add("+-----------------------+"); + var str=""; + for(var i=10;i<=100;i+=10) + { + if(i<=role_property.health) + str~="="; + else + str~=" "; + } + screen.left_add("|[health ]:"~str~" |"); + str=""; + for(var i=10;i<=100;i+=10) + { + if(i<=role_property.mood) + str~="="; + else + str~=" "; + } + screen.left_add("|[mood ]:"~str~" |"); + str=""; + for(var i=10;i<=100;i+=10) + { + if(i<=role_property.satiety) + str~="="; + else + str~=" "; + } + screen.left_add("|[satiety]:"~str~" |"); + str=""; + for(var i=10;i<=100;i+=10) + { + if(i<=role_property.thirst) + str~="="; + else + str~=" "; + } + screen.left_add("|[thirst ]:"~str~" |"); + screen.left_add("+-----------------------+"); + return; +} +var generate_choose_list=func() +{ + var str_list=[ + "-----------------------+", + "[1]| next step |", + "[2]| restart |", + "[3]| store game |", + "[4]| exit |", + "-----------------------+" + ]; + foreach(var i;str_list) + screen.right_add(i); + return; +} +var next_step=func() +{ + role_property.health_change(-1); + role_property.mood_change(-1); + role_property.satiety_change(-1); + role_property.thirst_change(-10); + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + screen.pic_addline(i); + return; +} +var restart=func() +{ + role_property.health=100; + role_property.mood=100; + role_property.satiety=100; + role_property.thirst=100; + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + screen.pic_addline(i); + return; +} +var generate_incorrect_choice_screen=func() +{ + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| |", + "| |", + "| |", + "| make a correct choice. |", + "| |", + "| |", + "| |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + screen.pic_addline(i); +} +var generate_goodbye_screen=func() +{ + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| |", + "| |", + "| |", + "| see you next life. |", + "| |", + "| |", + "| |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + screen.pic_addline(i); +} +var store_file=func() +{ + var str=role_property.health~'\n'~role_property.mood~'\n'~role_property.satiety~'\n'~role_property.thirst~'\n'; + io.fout("game-left-in-corner.glic",str); + var str_list=[ + "+-----------------------------------------------+", + "| |", + "| |", + "| |", + "| |", + "| |", + "| data stored. |", + "| |", + "| |", + "| |", + "| |", + "| |", + "+-----------------------------------------------+" + ]; + foreach(var i;str_list) + screen.pic_addline(i); + return; +} +var get_file=func() +{ + var str=io.fin("game-left-in-corner.glic"); + print(str); + return; +} +var game_main=func() +{ + first_shown_info(); + screen.clear(); + generate_role_property(); + generate_choose_list(); + screen.prt_screen(); + while(1) + { + screen.clear(); + print("|your choice[1|2|3|4]: |"); + var choice=input(); + if((choice!='1') and (choice!='2') and (choice!='3') and (choice!='4')) + generate_incorrect_choice_screen(); + elsif(choice=='1') + next_step(); + elsif(choice=='2') + restart(); + elsif(choice=='3') + store_file(); + elsif(choice=='4') + { + system("cls"); + screen.clear(); + generate_goodbye_screen(); + generate_role_property(); + generate_choose_list(); + screen.prt_screen(); + break; + } + system("cls"); + generate_role_property(); + generate_choose_list(); + screen.prt_screen(); + if(role_property.health==0 or role_property.mood==0 or role_property.satiety==0 or role_property.thirst==0) + { + print("|you died. |"); + print("+-----------------------------------------------+"); + system("pause"); + screen.clear(); + restart(); + system("cls"); + generate_role_property(); + generate_choose_list(); + screen.prt_screen(); + } + } + return; +} +game_main(); \ No newline at end of file diff --git a/test/neo4j.nas b/test/neo4j.nas new file mode 100644 index 0000000..e961253 --- /dev/null +++ b/test/neo4j.nas @@ -0,0 +1,156 @@ +import("lib.nas"); + +rand(time(0)); +var chartable=split('','abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); +var node=func(type) +{ + var s=""; + for(var i=0;i<10;i+=1) + s~=chartable[rand()*62]; + return {name:s,type:type,next:[]}; +} +var film_node=[]; +for(var i=0;i<1000;i+=1) + append(film_node,node("film")); +var director_node=[]; +for(var i=0;i<400;i+=1) + append(director_node,node("direct")); +var actor_node=[]; +for(var i=0;i<2000;i+=1) + append(actor_node,node("actor")); +var writer_node=[]; +for(var i=0;i<300;i+=1) + append(writer_node,node("writer")); +var type_node=[]; +for(var i=0;i<20;i+=1) + append(type_node,node("type")); +var lang_node=[]; +for(var i=0;i<120;i+=1) + append(lang_node,node("lang")); +var country_node=[]; +for(var i=0;i<120;i+=1) + append(country_node,node("country")); + +func() +{ + var director_size=size(director_node); + var actor_size=size(actor_node); + var writer_size=size(writer_node); + var type_size=size(type_node); + var lang_size=size(lang_node); + var country_size=size(country_node); + + var director_link=int(1+rand()*2); + var actor_link=int(1+rand()*10); + var writer_link=int(1+rand()); + var type_link=int(1+rand()*3); + var lang_link=int(1+rand()*4); + var country_link=int(1+rand()*2); + foreach(var film;film_node) + { + for(var i=0;i10?10:list_size; + for(var i=0;i=list_size) + die("choose a correct index"); + var label_list=film_node[num(choose)].next; + film_list=[]; + count_list=[]; + foreach(var label;label_list) + foreach(var film;label.next) + { + var has=0; + for(var i=0;i 1 and !contains(val, name)) val[name] = []; + } + if(nc > 1) append(val[name], c.getValues()); + else val[name] = c.getValues(); + } + return val; +} + +## +# Initializes property if it's still undefined. First argument +# is a property name/path. It can also be nil or an empty string, +# in which case the node itself gets initialized, rather than one +# of its children. Second argument is the default value. The third, +# optional argument is a property type (one of "STRING", "DOUBLE", +# "INT", or "BOOL"). If it is omitted, then "DOUBLE" is used for +# numbers, and STRING for everything else. Returns the property +# as props.Node. The fourth optional argument enforces a type if +# non-zero. +# +Node.initNode = func(path = nil, value = 0, type = nil, force = 0) { + var prop = me.getNode(path or "", 1); + if(prop.getType() != "NONE") value = prop.getValue(); + if(force) prop.clearValue(); + if(type == nil) prop.setValue(value); + elsif(type == "DOUBLE") prop.setDoubleValue(value); + elsif(type == "INT") prop.setIntValue(value); + elsif(type == "BOOL") prop.setBoolValue(value); + elsif(type == "STRING") prop.setValue("" ~ value); + else die("initNode(): unsupported type '" ~ type ~ "'"); + return prop; +} + +## +# Useful debugging utility. Recursively dumps the full state of a +# Node object to the console. Try binding "props.dump(props.globals)" +# to a key for a fun hack. +# +var dump = func { + if(size(arg) == 1) { prefix = ""; node = arg[0]; } + else { prefix = arg[0]; node = arg[1]; } + + index = node.getIndex(); + type = node.getType(); + name = node.getName(); + val = node.getValue(); + + if(val == nil) { val = "nil"; } + name = prefix ~ name; + if(index > 0) { name = name ~ "[" ~ index ~ "]"; } + print(name, " {", type, "} = ", val); + + # Don't recurse into aliases, lest we get stuck in a loop + if(type != "ALIAS") { + children = node.getChildren(); + foreach(c; children) { dump(name ~ "/", c); } + } +} + +## +# Recursively copy property branch from source Node to +# destination Node. Doesn't copy aliases. Copies attributes +# if optional third argument is set and non-zero. +# +var copy = func(src, dest, attr = 0) { + foreach(var c; src.getChildren()) { + var name = c.getName() ~ "[" ~ c.getIndex() ~ "]"; + copy(src.getNode(name), dest.getNode(name, 1), attr); + } + var type = src.getType(); + var val = src.getValue(); + if(type == "ALIAS" or type == "NONE") return; + elsif(type == "BOOL") dest.setBoolValue(val); + elsif(type == "INT" or type == "LONG") dest.setIntValue(val); + elsif(type == "FLOAT" or type == "DOUBLE") dest.setDoubleValue(val); + else dest.setValue(val); + if(attr) dest.setAttribute(src.getAttribute()); +} + +## +# Utility. Turns any ghosts it finds (either solo, or in an +# array) into Node objects. +# +var wrap = func(node) { + var argtype = typeof(node); + if(argtype == "ghost") { + return wrapNode(node); + } elsif(argtype == "vector") { + var v = node; + var n = size(v); + for(var i=0; i property branch according to the rules +# set out in $FG_ROOT/Docs/README.conditions into a Condition object. +# The 'test' method of the returend object can be used to evaluate +# the condition. +# The function returns nil on error. +# +var compileCondition = func(p) { + if(p == nil) return nil; + if(!isa(p, Node)) p = props.globals.getNode(p); + return _createCondition(p._g); +} + +## +# Evaluates a property branch according to the rules +# set out in $FG_ROOT/Docs/README.conditions. Undefined conditions +# and a nil argument are "true". The function dumps the condition +# branch and returns nil on error. +# +var condition = func(p) { + if(p == nil) return 1; + if(!isa(p, Node)) p = props.globals.getNode(p); + return _cond_and(p) +} + +var _cond_and = func(p) { + foreach(var c; p.getChildren()) + if(!_cond(c)) return 0; + return 1; +} + +var _cond_or = func(p) { + foreach(var c; p.getChildren()) + if(_cond(c)) return 1; + return 0; +} + +var _cond = func(p) { + var n = p.getName(); + if(n == "or") return _cond_or(p); + if(n == "and") return _cond_and(p); + if(n == "not") return !_cond_and(p); + if(n == "equals") return _cond_cmp(p, 0); + if(n == "not-equals") return !_cond_cmp(p, 0); + if(n == "less-than") return _cond_cmp(p, -1); + if(n == "greater-than") return _cond_cmp(p, 1); + if(n == "less-than-equals") return !_cond_cmp(p, 1); + if(n == "greater-than-equals") return !_cond_cmp(p, -1); + if(n == "property") return !!getprop(p.getValue()); + printlog("alert", "condition: invalid operator ", n); + dump(p); + return nil; +} + +var _cond_cmp = func(p, op) { + var left = p.getChild("property", 0, 0); + if(left != nil) { left = getprop(left.getValue()); } + else { + printlog("alert", "condition: no left value"); + dump(p); + return nil; + } + var right = p.getChild("property", 1, 0); + if(right != nil) { right = getprop(right.getValue()); } + else { + right = p.getChild("value", 0, 0); + if(right != nil) { right = right.getValue(); } + else { + printlog("alert", "condition: no right value"); + dump(p); + return nil; + } + } + if(left == nil or right == nil) { + printlog("alert", "condition: comparing with nil"); + dump(p); + return nil; + } + if(op < 0) return left < right; + if(op > 0) return left > right; + return left == right; +} + +## +# Runs as described in $FG_ROOT/Docs/README.commands using +# a given module by default, and returns 1 if fgcommand() succeeded, +# or 0 otherwise. The module name won't override a defined +# in the binding. +# +var runBinding = func(node, module = nil) { + if(module != nil and node.getNode("module") == nil) + node.getNode("module", 1).setValue(module); + var cmd = node.getNode("command", 1).getValue() or "null"; + condition(node.getNode("condition")) ? fgcommand(cmd, node) : 0; +} + + #--------------------------------------------------------------------------- + # Property / object update manager + # + # - Manage updates when a value has changed more than a predetermined amount. + # This class is designed to make updating displays (e.g. canvas), or + # performing actions based on a property (or value in a hash) changing + # by more than the preset amount. + # This can make a significant improvement to performance compared to simply + # redrawing a canvas in an update loop. + # - Author : Richard Harrison (rjh@zaretto.com) + #---------------------------------------------------------------------------*/ + +#example usage: +# this is using the hashlist (which works well with an Emesary notification) +# basically when the method is called it will call each section (in the lambda) +# when the value changes by more than the amount specified as the second parameter. +# It is possible to reference multiple elements from the hashlist in each FromHashList; if either +# one changes then it will result in the lambda being called. +# +# obj.update_items = [ +# UpdateManager.FromHashList(["VV_x","VV_y"], 0.01, func(val) +# { +# obj.VV.setTranslation (val.VV_x, val.VV_y + pitch_offset); +# }), +# UpdateManager.FromHashList(["pitch","roll"], 0.025, func(hdp) +# { +# obj.ladder.setTranslation (0.0, hdp.pitch * pitch_factor+pitch_offset); +# obj.ladder.setCenter (118,830 - hdp.pitch * pitch_factor-pitch_offset); +# obj.ladder.setRotation (-hdp.roll_rad); +# obj.roll_pointer.setRotation (hdp.roll_rad); +# }), +# props.UpdateManager.FromProperty("velocities/airspeed-kt", 0.01, func(val) +# { +# obj.ias_range.setTranslation(0, val * ias_range_factor); +# }), +# props.UpdateManager.FromPropertyHashList(["orientation/alpha-indicated-deg", "orientation/side-slip-deg"], 0.1, func(val) +# { +# obj.VV_x = val.property["orientation/side-slip-deg"].getValue()*10; # adjust for view +# obj.VV_y = val.property["orientation/alpha-indicated-deg"].getValue()*10; # adjust for view +# obj.VV.setTranslation (obj.VV_x, obj.VV_y); +# }), +# ] +# +#==== the update loop then becomes ====== +# +# foreach(var update_item; me.update_items) +# { +# # hdp is a data provider that can be used as the hashlist for the property +# # update from hash methods. +# update_item.update(hdp); +# } +# +var UpdateManager = +{ + _updateProperty : func(_property) + { + }, + FromProperty : func(_propname, _delta, _changed_method) + { + var obj = {parents : [UpdateManager] }; + obj.propname = _propname; + obj.property = props.globals.getNode(_propname); + obj.delta = _delta; + obj.curval = obj.property.getValue(); + obj.lastval = obj.curval; + obj.changed = _changed_method; + obj.update = func(obj) + { + me.curval = me.property.getValue(); + if (me.curval != nil) + { + me.localType = me.property.getType(); + if (me.localType == "INT" or me.localType == "LONG" or me.localType == "FLOAT" or me.localType == "DOUBLE") + { + if(me.lastval == nil or math.abs(me.lastval - me.curval) >= me.delta) + { + me.lastval = me.curval; + me.changed(me.curval); + } + } + else if(me.lastval == nil or me.lastval != me.curval) + { + me.lastval = me.curval; + me.changed(me.curval); + } + } + }; + obj.update(obj); + return obj; + }, + + IsNumeric : func(hashkey) + { + me.localType = me.property[hashkey].getType(); + if (me.localType == "UNSPECIFIED") { + print("UpdateManager: warning ",hashkey," is ",ty, " excluding from update"); + me.property[hashkey] = nil; + } + if (me.localType == "INT" or me.localType == "LONG" or me.localType == "FLOAT" or me.localType == "DOUBLE") + return 1; + else + return 0; + }, + + FromPropertyHashList : func(_keylist, _delta, _changed_method) + { + var obj = {parents : [UpdateManager] }; + obj.hashkeylist = _keylist; + obj.delta = _delta; + obj.lastval = {}; + obj.hashkey = nil; + obj.changed = _changed_method; + obj.needs_update = 0; + obj.property = {}; + obj.is_numeric = {}; + foreach (hashkey; obj.hashkeylist) { + obj.property[hashkey] = props.globals.getNode(hashkey); + obj.lastval[hashkey] = nil; +# var ty = obj.property[hashkey].getType(); +# if (ty == "INT" or ty == "LONG" or ty == "FLOAT" or ty == "DOUBLE") { +# obj.is_numeric[hashkey] = 1; +# } else +# obj.is_numeric[hashkey] = 0; +#print("create: ", hashkey," ", ty, " isnum=",obj.is_numeric[hashkey]); +# if (ty == "UNSPECIFIED") +# print("UpdateManager: warning ",hashkey," is ",ty); + } + obj.update = func(obj) + { + if (me.lastval == nil) + me.needs_update = 1; + else { + me.needs_update = 0; + + foreach (hashkey; me.hashkeylist) { + if (me.property[hashkey] != nil) { + me.valIsNumeric = me.IsNumeric(hashkey); + + if (me.lastval[hashkey] == nil + or (me.valIsNumeric and (math.abs(me.lastval[hashkey] - me.property[hashkey].getValue()) >= me.delta)) + or (!me.valIsNumeric and (me.lastval[hashkey] != me.property[hashkey].getValue()))) { + me.needs_update = 1; + break; + } + } + } + } + if (me.needs_update) { + me.changed(me); + foreach (hashkey; me.hashkeylist) { + me.lastval[hashkey] = me.property[hashkey].getValue(); + } + } + } + ; + return obj; + }, + FromHashValue : func(_key, _delta, _changed_method) + { + var obj = {parents : [UpdateManager] }; + obj.hashkey = _key; + obj.delta = _delta; + obj.isnum = _delta != nil; + obj.curval = nil; + obj.lastval = nil; + obj.changed = _changed_method; + obj.update = func(obj) + { + me.curval = obj[me.hashkey]; + if (me.curval != nil) { + if (me.isnum) { + me.curval = num(me.curval); + if (me.lastval == nil or math.abs(me.lastval - me.curval) >= me.delta) { + me.lastval = me.curval; + me.changed(me.curval); + } + } else { + if (me.lastval == nil or me.lastval != me.curval) { + me.lastval = me.curval; + me.changed(me.curval); + } + } + } + } + ; + return obj; + }, + FromHashList : func(_keylist, _delta, _changed_method) + { + var obj = {parents : [UpdateManager] }; + obj.hashkeylist = _keylist; + obj.delta = _delta; + obj.lastval = {}; + obj.hashkey = nil; + obj.changed = _changed_method; + obj.needs_update = 0; + obj.isnum = _delta != nil; + obj.update = func(obj) + { + if (me.lastval == nil) + me.needs_update = 1; + else + me.needs_update = 0; + + if (obj != nil or me.lastval == nil) { + foreach (hashkey; me.hashkeylist) { + if (me.isnum) { + if (me.lastval[hashkey] == nil or math.abs(me.lastval[hashkey] - obj[hashkey]) >= me.delta) { + me.needs_update = 1; + break; + } + } elsif (me.lastval[hashkey] == nil or me.lastval[hashkey] != obj[hashkey]) { + me.needs_update = 1; + break; + } + } + } + if (me.needs_update) { + me.changed(obj); + foreach (hashkey; me.hashkeylist) { + me.lastval[hashkey] = obj[hashkey]; + } + } + }; + return obj; + }, +}; diff --git a/test/queue.nas b/test/queue.nas new file mode 100644 index 0000000..4a2a0af --- /dev/null +++ b/test/queue.nas @@ -0,0 +1,35 @@ +# lib queue.nas +var block_alloc=func() +{ + return {elem:nil,next:nil}; +} +var new_queue=func() +{ + return {next:nil}; +} +var queue_push=func(queue,elem) +{ + var tmp=queue; + while(tmp.next!=nil) + tmp=tmp.next; + tmp.next=block_alloc(); + tmp.next.elem=elem; +} +var queue_pop=func(queue) +{ + var tmp=queue.next; + if(tmp!=nil) + queue.next=tmp.next; + return; +} +var queue_front=func(queue) +{ + var tmp=queue.next; + if(tmp!=nil) + return tmp.elem; + return nil; +} +var queue_empty=func(queue) +{ + return queue.next==nil; +} \ No newline at end of file diff --git a/test/scalar.nas b/test/scalar.nas new file mode 100644 index 0000000..09afd65 --- /dev/null +++ b/test/scalar.nas @@ -0,0 +1,126 @@ +# basic type +nil; +2147483647; +0x7fffffff; +0xdeadbeef; +0o70120327; +"hello world!"; +'hello world!'; +-12; +!0; +-((30)); +[]; +{}; +[0,1,2,3,4,5][2]; # 2 +[0,1,2,3,4,5,6,7,8,9,10][0,2,4:7,9]; +[0,1,2,3,4,5,6,7,8,9,10,][0,2,4:7,9]; +([0,1,2,3,4])[2]; # 2 +(([0,1,2,3]))[2]; # 2 +[0,1,2,3,4,5][5,4,3,2+1][0:2][0]; # 5 +{str:"hello"}.str; # "hello" +{str:"hello"}["str"]; # "hello" +{"str":"hello\"\"\n"}["str"]; # "hello" +20? 1:0; + +# normal scalar +var number_1=1; +var number_2=0xdeadbeef; +var number_3=0x13702; +var number_4=0.12341490239423; +var string_1="hello"; +var string_2='hello'; +var string_3=number_1? 'yes':'no'; # yes + +# vector +var vector_1=[]; +var vector_2=[0,1,2,"str",number_1,vector_1]; +var vector_3=vector_2[-3,-1]; +var vector_4=vector_2[0:3]; +var vector_5=vector_2[3:]; + +# hash +var hash_1={}; +var hash_2={str1:'str1', str2:'str2', num1:0x7fffffff}; +var hash_3={ + "member_1":1, + "member_2":2, + "member_3":3, +}; +var hash_4={ + mem_1:hash_1, + mem_2:hash_2.num1, # also this can be written as hash_2["num1"] + mem_3:hash_3["member_1"] +}; + +# function +var func_1=func(){return 1;} +var prt=func(x){print(x);return nil;} +var func_with_dynamic_id=func(a,b,c,d...){return [a,b,c,d];} +var func_with_lack_para=func(a,b,c=1,d=2){return a+b+c+d;} +var func_with_func_para=func(a,f){return f(a);} + +func_with_lack_para(a:1, b:2, c:3, d:4); +func_with_lack_para(b:1, c:3, a:4, d:1); +func_with_func_para(f:func prt,a:1); +func_with_func_para(func func_1(),func(x){return x;}); +func_with_func_para(func_1(),func_1); +prt(func func_1()); +var test_func_ret_number_1=func func_1(); # 1 +var test_func_ret_number_2=func_1(); # 1 + +var source={ + member_1: func func_1(), # this will get a number + member_2: func {return 2.71828;} # this will get a function +}; +print(source['member_2']()); +print(source.member_2()); + +var test_func=func{return 1;} +print(func test_func()); # 1 +print(test_func()); # 1 +print(func test_func); # nothing +print(test_func); # nothing +print(([0,1,2,3])[1]); # 1 +print(({str:"what?"})["str"]); # what? +print(({str:"what?"}).str); # what? + +# lambda +(func(x){return x>0? x:0;})(12); +(func{print("hello world");})(); +(((func(x){return 1.0/math.exp(x);})))(0); + +# flexible definition & assignment +var (r,g,b)=[0x00,0x10,0xff]; +(var r,g,b)=[0x00,0x10,0xff]; +var color=[0x00,0x10,0xff]; +var (r,g,b)=color; +(var r,g,b)=color; +(r,g,b)=(b,g,r); +(number_1,number_2)=(number_2,number_1); +var (swap_a,swap_b)=(0x1,0x80); +(swap_a,swap_b)=(swap_b,swap_a); +# ((swap_a),(swap_b))=(swap_b,swap_a) is wrong +# anything that use multi_assignment must not have curve around them +var multi_assign_1=[0,1,2,3,4]; +var multi_assign_2=[10,9,8,7]; +(multi_assign_1[1],multi_assign_2[0])=(multi_assign_1[2],multi_assign_2[1]); + +# calculation +1+1; +1+1-2+3-4+5-6; +1+1*8-9/3; +1*-1; +1*(1+2*(3+4*(5+6*(7+8*(9+10/(1+1)))))); +((-1*2+9))/7-1; +((({num:2})))["num"]*2*2*2; +((((([0,1,2])[0:2]))[0:2]))[1]-1; +(((((((((((((((((((1+1+2+3+5)+8))+13)))+21))))+34)))))+55))))*89; +number_1*(number_2+number_3)/90-number_4; +(func test_func)()-1; +hash_3.member_3+(func {return {what:"i don't tell you.",case_small:80,case_large:100}})()["case_large"]/10; +-1*10+5 or 10-10; +nil and 1+7*8; +(number_1 or number_2) and (number_3 or number_4-number_4*1); +[0,1,4,3,2][4]*2-4+1*2*2*2*2*2/8; +{num:0}.num or {what_is_the_secret_of_universe:42}["what_is_the_secret_of_universe"]; +"123"~"456"-123456*2/2; \ No newline at end of file diff --git a/test/scope.nas b/test/scope.nas new file mode 100644 index 0000000..e38f016 --- /dev/null +++ b/test/scope.nas @@ -0,0 +1,62 @@ +var global_value=0; +var global_hash= +{ + var1:1, + var2:2, + var3:func(){return me.var2;} +}; +print(global_value); +print(global_hash.var3()); + +var func1=func() +{ + global_value=1; + print(global_value); + var closure_value=1; + var temp_value=1; + print(temp_value); + return func{return closure_value;}; +} + +var func2=func() +{ + for(var temp_value=0;temp_value<100;temp_value+=1) + { + if(temp_value<10) + print(temp_value,"< 10"); + elsif(10<=temp_value and temp_value<50) + print(temp_value,"< 50"); + temp_value=10; + } + return; +} + +var func3=func() +{ + var fake_closure_value=1; + return func() + { + var fake_closure_value=2; + return fake_closure_value; + }; +} + +func1()(); +func2(); +func3()(); + +if(!global_value) +{ + var temp_value=1; + if(temp_value) + { + var temp_value=2; + if(temp_value>=1) + { + var temp_value=3; + print(temp_value); + } + print(temp_value); + } + print(temp_value); +} \ No newline at end of file diff --git a/test/special.nas b/test/special.nas new file mode 100644 index 0000000..f581ac2 --- /dev/null +++ b/test/special.nas @@ -0,0 +1,24 @@ +var hash={str:'hello',f:func{return me.str;}}; +var tmp_f=hash.f; +hash=1; +print(tmp_f()); +# undefined symbol 'me' +# this means that +# when generating local_scope for function f, +# nasal_gc will not count 'me' as one reference of this hash + +var h1={str:'hello',f:func{return me.str;}}; +var h2={str:'world',f:func{return nil;}}; +h2.f=h1.f; +print(h2.f()); +# print 'world' +# this means that 'me' in hash's functions +# only points to the hash this function belongs to + +var f1=func(){print(1);return 1;} +var f2=func(){print(2);return 0;} +f1() or f2(); +# print '1' +# this means that when using 'or' or 'and', +# if the result is clear when calculating, +# objects behind will not be calculated \ No newline at end of file diff --git a/test/stack.nas b/test/stack.nas new file mode 100644 index 0000000..610bdc3 --- /dev/null +++ b/test/stack.nas @@ -0,0 +1,34 @@ +# lib stack.nas +var block_alloc=func() +{ + return {elem:nil,next:nil}; +} +var new_stack=func() +{ + return {next:nil}; +} +var stack_push=func(stack,elem) +{ + var tmp=stack.next; + stack.next=block_alloc(); + stack.next.elem=elem; + stack.next.next=tmp; +} +var stack_pop=func(stack) +{ + var tmp=stack.next; + if(tmp!=nil) + stack.next=tmp.next; + return; +} +var stack_top=func(stack) +{ + var tmp=stack.next; + if(tmp!=nil) + return tmp.elem; + return nil; +} +var stack_empty=func(stack) +{ + return stack.next==nil; +} \ No newline at end of file diff --git a/test/string.nas b/test/string.nas new file mode 100644 index 0000000..32de8b9 --- /dev/null +++ b/test/string.nas @@ -0,0 +1,5 @@ +import("lib.nas"); +var filename=""; + +filename=input(); +print(filename[0]); \ No newline at end of file