3D Model support for GDU-1045, general refactor
- Add GDU-1045 3d model courtesy of Jean-Paul ANCEAUX (www2). - Refactor to simplify deployment in aircraft - Add README file
1154
Aircraft/Instruments-3d/FG1000/GDU104X/GDU-1045.1.xml
Normal file
1149
Aircraft/Instruments-3d/FG1000/GDU104X/GDU-1045.2.xml
Normal file
1149
Aircraft/Instruments-3d/FG1000/GDU104X/GDU-1045.3.xml
Normal file
1149
Aircraft/Instruments-3d/FG1000/GDU104X/GDU-1045.4.xml
Normal file
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Model/FG1000.png
Normal file
After Width: | Height: | Size: 109 B |
84552
Aircraft/Instruments-3d/FG1000/GDU104X/Model/GDU-104X.1.ac
Normal file
84552
Aircraft/Instruments-3d/FG1000/GDU104X/Model/GDU-104X.2.ac
Normal file
84552
Aircraft/Instruments-3d/FG1000/GDU104X/Model/GDU-104X.3.ac
Normal file
84552
Aircraft/Instruments-3d/FG1000/GDU104X/Model/GDU-104X.4.ac
Normal file
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Model/screen.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/FG1000.png
Normal file
After Width: | Height: | Size: 109 B |
After Width: | Height: | Size: 13 KiB |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/GDU-1040A-20.png
Normal file
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 28 KiB |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/GDU-1040A-30.png
Normal file
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 34 KiB |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/GDU-1040A.png
Normal file
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 40 KiB |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/GDU-1044B.png
Normal file
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 39 KiB |
BIN
Aircraft/Instruments-3d/FG1000/GDU104X/Textures/GDU-104X.png
Normal file
After Width: | Height: | Size: 47 KiB |
|
@ -1,11 +1,19 @@
|
||||||
# FG Commands to support simple bindings
|
# FG Commands to support simple bindings
|
||||||
|
io.include("Constants.nas");
|
||||||
|
|
||||||
removecommand("FG1000HardKeyPushed");
|
removecommand("FG1000HardKeyPushed");
|
||||||
addcommand("FG1000HardKeyPushed",
|
addcommand("FG1000HardKeyPushed",
|
||||||
func(node) {
|
func(node) {
|
||||||
var device = int(node.getNode("device").getValue());
|
var device = int(node.getNode("device", 1).getValue());
|
||||||
var name = node.getNode("notification").getValue();
|
var name = node.getNode("notification",1).getValue();
|
||||||
var value = node.getNode("value").getValue();
|
|
||||||
|
# The knob animation stores the value as an offset property
|
||||||
|
var value = node.getNode("offset", 1).getValue();
|
||||||
|
|
||||||
|
if (value == nil) {
|
||||||
|
print("FG1000HardKeyPushed: No <offset> argument passed to fgcommand");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (device == nil) {
|
if (device == nil) {
|
||||||
print("FG1000HardKeyPushed: Unknown device" ~ node.getNode("device").getValue());
|
print("FG1000HardKeyPushed: Unknown device" ~ node.getNode("device").getValue());
|
||||||
|
@ -15,8 +23,8 @@ addcommand("FG1000HardKeyPushed",
|
||||||
# Notification may be provided as a number, or a string.
|
# Notification may be provided as a number, or a string.
|
||||||
if (int(name) == nil) {
|
if (int(name) == nil) {
|
||||||
# Name is a string, to map it to the correct INT id.
|
# Name is a string, to map it to the correct INT id.
|
||||||
if (defined(fg1000.FASCIA[name])) {
|
if (FASCIA[name] != nil) {
|
||||||
name = fg1000.FASCIA[name];
|
name = FASCIA[name];
|
||||||
} else {
|
} else {
|
||||||
print("Unable to find FASCIA entry for Hard Key " ~ name);
|
print("Unable to find FASCIA entry for Hard Key " ~ name);
|
||||||
return;
|
return;
|
||||||
|
@ -36,8 +44,8 @@ addcommand("FG1000HardKeyPushed",
|
||||||
removecommand("FG1000SoftKeyPushed");
|
removecommand("FG1000SoftKeyPushed");
|
||||||
addcommand("FG1000SoftKeyPushed",
|
addcommand("FG1000SoftKeyPushed",
|
||||||
func(node) {
|
func(node) {
|
||||||
var device = int(node.getNode("device").getValue());
|
var device = int(node.getNode("device", 1).getValue());
|
||||||
var value = int(node.getNode("value").getValue());
|
var value = node.getNode("offset", 1).getValue();
|
||||||
|
|
||||||
if (device == nil) {
|
if (device == nil) {
|
||||||
print("FG1000SoftKeyPushed: Unknown device" ~ node.getNode("device").getValue());
|
print("FG1000SoftKeyPushed: Unknown device" ~ node.getNode("device").getValue());
|
||||||
|
@ -45,10 +53,17 @@ addcommand("FG1000SoftKeyPushed",
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == nil) {
|
if (value == nil) {
|
||||||
|
print("FG1000SoftKeyPushed: No <offset> value for softkey number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int(value) == nil) {
|
||||||
print("Unable to convert softkey number to integer " ~ node.getNode("value").getValue());
|
print("Unable to convert softkey number to integer " ~ node.getNode("value").getValue());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = int(value);
|
||||||
|
|
||||||
var notification = notifications.PFDEventNotification.new(
|
var notification = notifications.PFDEventNotification.new(
|
||||||
"MFD",
|
"MFD",
|
||||||
device,
|
device,
|
||||||
|
|
|
@ -130,7 +130,11 @@ var FASCIA = {
|
||||||
NOSE_UP : 43,
|
NOSE_UP : 43,
|
||||||
NOSE_DOWN : 44,
|
NOSE_DOWN : 44,
|
||||||
|
|
||||||
JOYSTICK_PRESS : 45
|
JOYSTICK_PRESS : 45,
|
||||||
|
|
||||||
|
# GDU 1045 Autopilot keys
|
||||||
|
YD : 46,
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ var EIS =
|
||||||
|
|
||||||
obj.setController(fg1000.EISController.new(obj, svg));
|
obj.setController(fg1000.EISController.new(obj, svg));
|
||||||
|
|
||||||
|
|
||||||
obj.addTextElements(["RPMDisplay", "MBusVolts", "EBusVolts", "EngineHours"]);
|
obj.addTextElements(["RPMDisplay", "MBusVolts", "EBusVolts", "EngineHours"]);
|
||||||
|
|
||||||
obj._fuelFlowPointer = PFD.PointerElement.new(obj.pageName, svg, "FuelFlowPointer", 0.0, 20.0, 135);
|
obj._fuelFlowPointer = PFD.PointerElement.new(obj.pageName, svg, "FuelFlowPointer", 0.0, 20.0, 135);
|
||||||
|
|
100
Aircraft/Instruments-3d/FG1000/Nasal/FG1000.nas
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# FG1000 Base clearStyles
|
||||||
|
|
||||||
|
print("\n############");
|
||||||
|
print("# FG1000 #");
|
||||||
|
print("############\n");
|
||||||
|
|
||||||
|
io.include("Constants.nas");
|
||||||
|
io.include("Commands.nas");
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
|
||||||
|
io.load_nasal(nasal_dir ~ '/ConfigStore.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/MFDPage.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/MFDPageController.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/MFD.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/GUI.nas', "fg1000");
|
||||||
|
|
||||||
|
var FG1000 = {
|
||||||
|
|
||||||
|
new : func(EIS_Class = nil, EIS_SVG = nil) {
|
||||||
|
var obj = {
|
||||||
|
parents : [FG1000],
|
||||||
|
displays : {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (EIS_Class == nil) {
|
||||||
|
# Load the default EIS class.
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
io.load_nasal(nasal_dir ~ '/EIS/EIS.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/EIS/EISController.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/EIS/EISStyles.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ '/EIS/EISOptions.nas', "fg1000");
|
||||||
|
obj.EIS_Class = fg1000.EIS;
|
||||||
|
} else {
|
||||||
|
obj.EIS_Class = EIS_Class;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EIS_SVG == nil) {
|
||||||
|
obj.EIS_SVG = "/Aircraft/Instruments-3d/FG1000/MFDPages/EIS.svg";
|
||||||
|
} else {
|
||||||
|
obj.EIS_SVG = EIS_SVG;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.ConfigStore = fg1000.ConfigStore.new();
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
setEIS : func(EIS_Class, EIS_SVG) {
|
||||||
|
me.EIS_Class = EIS_Class;
|
||||||
|
me.EIS_SVG = EIS.SVG;
|
||||||
|
},
|
||||||
|
|
||||||
|
addMFD : func(index, targetcanvas=nil, screenObject=nil) {
|
||||||
|
if (me.displays[index] != nil) {
|
||||||
|
print("FG1000 Index " ~ index ~ " already exists!");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetcanvas == nil) {
|
||||||
|
targetcanvas = canvas.new({
|
||||||
|
"name" : "MFD Canvas",
|
||||||
|
"size" : [1024, 768],
|
||||||
|
"view" : [1024, 768],
|
||||||
|
"mipmapping": 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var mfd = fg1000.MFD.new(me, me.EIS_Class, me.EIS_SVG, targetcanvas, index);
|
||||||
|
me.displays[index] = mfd;
|
||||||
|
},
|
||||||
|
|
||||||
|
display : func(index, target_object=nil) {
|
||||||
|
if (me.displays[index] == nil) {
|
||||||
|
print("displayMFD: unknown display index " ~ index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_object == nil) target_object = "Screen" ~ index;
|
||||||
|
|
||||||
|
var targetcanvas = me.displays[index].getCanvas();
|
||||||
|
targetcanvas.addPlacement({"node": target_object});
|
||||||
|
},
|
||||||
|
|
||||||
|
displayGUI : func(index, scale=1.0) {
|
||||||
|
if (me.displays[index] == nil) {
|
||||||
|
print("displayMFD: unknown display index " ~ index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mfd_canvas = me.displays[index].getCanvas();
|
||||||
|
var gui = fg1000.GUI.new(mfd_canvas, index, scale);
|
||||||
|
},
|
||||||
|
|
||||||
|
getConfigStore : func() {
|
||||||
|
return me.ConfigStore;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
io.include("Constants.nas");
|
var GUI =
|
||||||
|
|
||||||
var MFDGUI =
|
|
||||||
{
|
{
|
||||||
# List of UI hotspots and their mapping to Emesary bridge notifications
|
# List of UI hotspots and their mapping to Emesary bridge notifications
|
||||||
WHEEL_HOT_SPOTS : [
|
WHEEL_HOT_SPOTS : [
|
||||||
|
@ -74,10 +72,10 @@ var MFDGUI =
|
||||||
{ Id: 12, top_left: [1145, 830], bottom_right: [1200, 875] },
|
{ Id: 12, top_left: [1145, 830], bottom_right: [1200, 875] },
|
||||||
],
|
],
|
||||||
|
|
||||||
new : func()
|
new : func(mfd_canvas, device_id, scale = 1.0)
|
||||||
{
|
{
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [ MFDGUI ],
|
parents : [ GUI ],
|
||||||
mfd : nil,
|
mfd : nil,
|
||||||
eisPublisher : nil,
|
eisPublisher : nil,
|
||||||
navcomPublisher : nil,
|
navcomPublisher : nil,
|
||||||
|
@ -85,19 +83,11 @@ var MFDGUI =
|
||||||
navdataInterface : nil,
|
navdataInterface : nil,
|
||||||
width : 1407,
|
width : 1407,
|
||||||
height : 918,
|
height : 918,
|
||||||
scale : 1.0,
|
scale : scale,
|
||||||
|
device_id : device_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
# Increment the device count, so we get an uniqueish device id.
|
obj.window = canvas.Window.new([obj.scale*obj.width,obj.scale*obj.height],"dialog").set('title',"FG1000 MFD" ~ device_id);
|
||||||
obj.device_id = getprop("/instrument/fg1000/device-count");
|
|
||||||
if (obj.device_id == nil) obj.device_id = 0;
|
|
||||||
setprop("/instrument/fg1000/device-count", obj.device_id + 1);
|
|
||||||
print("Device count: " ~ getprop("/instrument/fg1000/device-count"));
|
|
||||||
print("Device ID: " ~ obj.device_id);
|
|
||||||
|
|
||||||
obj.scale = getprop("/sim/gui/mfd-scale") or 1.0;
|
|
||||||
|
|
||||||
obj.window = canvas.Window.new([obj.scale*obj.width,obj.scale*obj.height],"dialog").set('title',"FG1000 MFD");
|
|
||||||
|
|
||||||
obj.window.del = func() {
|
obj.window.del = func() {
|
||||||
# Over-ride the window.del function so we clean up when the user closes the window
|
# Over-ride the window.del function so we clean up when the user closes the window
|
||||||
|
@ -110,42 +100,13 @@ var MFDGUI =
|
||||||
obj.myCanvas.set("name", "MFD");
|
obj.myCanvas.set("name", "MFD");
|
||||||
obj.root = obj.myCanvas.createGroup();
|
obj.root = obj.myCanvas.createGroup();
|
||||||
|
|
||||||
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
# Project the canvas onto the dialog
|
||||||
io.load_nasal(nasal_dir ~ 'MFD.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyPublisher.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyUpdater.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericEISPublisher.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComPublisher.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComUpdater.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/NavDataInterface.nas', "fg1000");
|
|
||||||
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericFMSPublisher.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ 'Interfaces/GenericADCPublisher.nas', "fg1000");
|
|
||||||
|
|
||||||
# Now create the MFD itself
|
|
||||||
if (obj.scale > 0.999) {
|
|
||||||
# If we're at full scale, then create it directly in this Canvas as that
|
|
||||||
# produces sharper results and perhaps better performance
|
|
||||||
obj.mfd = fg1000.MFD.new(obj.myCanvas, obj.device_id);
|
|
||||||
obj.mfd._svg.setTranslation(186,45);
|
|
||||||
#obj.mfd._svg.set("z-index", 150);
|
|
||||||
} else {
|
|
||||||
# If we're using some scaling factor, then we create it as an image raster
|
|
||||||
# which scales everything for us nicely.
|
|
||||||
obj.mfd_canvas = canvas.new({
|
|
||||||
"name" : "MFD Canvas",
|
|
||||||
"size" : [1024, 768],
|
|
||||||
"view" : [1024, 768],
|
|
||||||
"mipmapping": 0,
|
|
||||||
});
|
|
||||||
obj.mfd = fg1000.MFD.new(obj.mfd_canvas, obj.device_id);
|
|
||||||
|
|
||||||
var mfd_child = obj.root.createChild("image")
|
var mfd_child = obj.root.createChild("image")
|
||||||
.setFile(obj.mfd_canvas.getPath())
|
.setFile(mfd_canvas.getPath())
|
||||||
.set("z-index", 150)
|
.set("z-index", 150)
|
||||||
.setTranslation(obj.scale*186,obj.scale*45)
|
.setTranslation(obj.scale*186,obj.scale*45)
|
||||||
.setSize(obj.scale*1024, obj.scale*768);
|
.setSize(obj.scale*1024, obj.scale*768);
|
||||||
}
|
|
||||||
|
|
||||||
# Create the surround fascia, which is just a PNG image;
|
# Create the surround fascia, which is just a PNG image;
|
||||||
var child = obj.root.createChild("image")
|
var child = obj.root.createChild("image")
|
||||||
|
@ -154,29 +115,11 @@ var MFDGUI =
|
||||||
.setTranslation(0, 0)
|
.setTranslation(0, 0)
|
||||||
.setSize(obj.scale*obj.width,obj.scale*obj.height);
|
.setSize(obj.scale*obj.width,obj.scale*obj.height);
|
||||||
|
|
||||||
obj.eisPublisher = fg1000.GenericEISPublisher.new();
|
|
||||||
obj.eisPublisher.start();
|
|
||||||
|
|
||||||
obj.navcomPublisher = fg1000.GenericNavComPublisher.new();
|
|
||||||
obj.navcomPublisher.start();
|
|
||||||
|
|
||||||
obj.navcomUpdater = fg1000.GenericNavComUpdater.new(obj.mfd.getDevice());
|
|
||||||
obj.navcomUpdater.start();
|
|
||||||
|
|
||||||
obj.navdataInterface = fg1000.NavDataInterface.new(obj.mfd.getDevice());
|
|
||||||
obj.navdataInterface.start();
|
|
||||||
|
|
||||||
obj.gpsPublisher = fg1000.GenericFMSPublisher.new();
|
|
||||||
obj.gpsPublisher.start();
|
|
||||||
|
|
||||||
obj.adcPublisher = fg1000.GenericADCPublisher.new();
|
|
||||||
obj.adcPublisher.start();
|
|
||||||
|
|
||||||
# Add a event listener for the mouse wheel, which is used for turning the
|
# Add a event listener for the mouse wheel, which is used for turning the
|
||||||
# knobs.
|
# knobs.
|
||||||
obj.myCanvas.addEventListener("wheel", func(e)
|
obj.myCanvas.addEventListener("wheel", func(e)
|
||||||
{
|
{
|
||||||
foreach(var hotspot; MFDGUI.WHEEL_HOT_SPOTS) {
|
foreach(var hotspot; GUI.WHEEL_HOT_SPOTS) {
|
||||||
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
||||||
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
||||||
(e.shiftKey == hotspot.shift))
|
(e.shiftKey == hotspot.shift))
|
||||||
|
@ -184,7 +127,7 @@ var MFDGUI =
|
||||||
# We've found the hotspot, so send a notification to deal with it
|
# We've found the hotspot, so send a notification to deal with it
|
||||||
var args = {'device': obj.device_id,
|
var args = {'device': obj.device_id,
|
||||||
'notification': hotspot.notification,
|
'notification': hotspot.notification,
|
||||||
'value' : e.deltaY};
|
'offset' : e.deltaY};
|
||||||
|
|
||||||
fgcommand("FG1000HardKeyPushed", props.Node.new(args));
|
fgcommand("FG1000HardKeyPushed", props.Node.new(args));
|
||||||
break;
|
break;
|
||||||
|
@ -195,7 +138,7 @@ var MFDGUI =
|
||||||
# Add a event listener for the mouse click, which is used for buttons
|
# Add a event listener for the mouse click, which is used for buttons
|
||||||
obj.myCanvas.addEventListener("click", func(e)
|
obj.myCanvas.addEventListener("click", func(e)
|
||||||
{
|
{
|
||||||
foreach(var hotspot; MFDGUI.CLICK_HOT_SPOTS) {
|
foreach(var hotspot; GUI.CLICK_HOT_SPOTS) {
|
||||||
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
||||||
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
||||||
(e.shiftKey == hotspot.shift))
|
(e.shiftKey == hotspot.shift))
|
||||||
|
@ -203,20 +146,20 @@ var MFDGUI =
|
||||||
# We've found the hotspot, so send a notification to deal with it
|
# We've found the hotspot, so send a notification to deal with it
|
||||||
var args = {'device': obj.device_id,
|
var args = {'device': obj.device_id,
|
||||||
'notification': hotspot.notification,
|
'notification': hotspot.notification,
|
||||||
'value' : hotspot.value};
|
'offset' : hotspot.value};
|
||||||
|
|
||||||
fgcommand("FG1000HardKeyPushed", props.Node.new(args));
|
fgcommand("FG1000HardKeyPushed", props.Node.new(args));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(var hotspot; MFDGUI.SOFTKEY_HOTSPOTS) {
|
foreach(var hotspot; GUI.SOFTKEY_HOTSPOTS) {
|
||||||
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
||||||
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]))
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]))
|
||||||
{
|
{
|
||||||
# We've found the hotspot, so send a notification to deal with it
|
# We've found the hotspot, so send a notification to deal with it
|
||||||
var args = {'device': obj.device_id,
|
var args = {'device': obj.device_id,
|
||||||
'value' : hotspot.Id};
|
'offset' : hotspot.Id};
|
||||||
fgcommand("FG1000SoftKeyPushed", props.Node.new(args));
|
fgcommand("FG1000SoftKeyPushed", props.Node.new(args));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -228,25 +171,6 @@ var MFDGUI =
|
||||||
|
|
||||||
cleanup : func()
|
cleanup : func()
|
||||||
{
|
{
|
||||||
me.mfd.del();
|
|
||||||
me.eisPublisher.stop();
|
|
||||||
me.eisPublisher = nil;
|
|
||||||
|
|
||||||
me.navcomPublisher.stop();
|
|
||||||
me.navcomPublisher = nil;
|
|
||||||
|
|
||||||
me.navcomUpdater.stop();
|
|
||||||
me.navcomUpdater = nil;
|
|
||||||
|
|
||||||
me.navdataInterface.stop();
|
|
||||||
me.navdataInterface =nil;
|
|
||||||
|
|
||||||
me.gpsPublisher.stop();
|
|
||||||
me.gpsPublisher = nil;
|
|
||||||
|
|
||||||
me.adcPublisher.stop();
|
|
||||||
me.adcPublisher = nil;
|
|
||||||
|
|
||||||
# Clean up the window itself
|
# Clean up the window itself
|
||||||
call(canvas.Window.del, [], me.window);
|
call(canvas.Window.del, [], me.window);
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Generic Interface controller.
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyPublisher.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyUpdater.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericEISPublisher.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComPublisher.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComUpdater.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/NavDataInterface.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericFMSPublisher.nas', "fg1000");
|
||||||
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericADCPublisher.nas', "fg1000");
|
||||||
|
|
||||||
|
|
||||||
|
var GenericInterfaceController = {
|
||||||
|
|
||||||
|
new : func() {
|
||||||
|
var obj = {
|
||||||
|
parents : [GenericInterfaceController],
|
||||||
|
running : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.eisPublisher = fg1000.GenericEISPublisher.new();
|
||||||
|
obj.navcomPublisher = fg1000.GenericNavComPublisher.new();
|
||||||
|
obj.navcomUpdater = fg1000.GenericNavComUpdater.new();
|
||||||
|
obj.navdataInterface = fg1000.NavDataInterface.new();
|
||||||
|
obj.gpsPublisher = fg1000.GenericFMSPublisher.new();
|
||||||
|
obj.adcPublisher = fg1000.GenericADCPublisher.new();
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
start : func() {
|
||||||
|
if (me.running) return;
|
||||||
|
me.eisPublisher.start();
|
||||||
|
me.navcomPublisher.start();
|
||||||
|
me.navcomUpdater.start();
|
||||||
|
me.navdataInterface.start();
|
||||||
|
me.gpsPublisher.start();
|
||||||
|
me.adcPublisher.start();
|
||||||
|
},
|
||||||
|
|
||||||
|
stop : func() {
|
||||||
|
if (me.running == 0) return;
|
||||||
|
me.eisPublisher.stop();
|
||||||
|
me.navcomPublisher.stop();
|
||||||
|
me.navcomUpdater.stop();
|
||||||
|
me.navdataInterface.stop();
|
||||||
|
me.gpsPublisher.stop();
|
||||||
|
me.adcPublisher.stop();
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
# NavCom Interface using Emesary for a simple dual Nav/Com system using standard properties
|
# NavCom Interface using Emesary for a simple dual Nav/Com system using standard properties
|
||||||
#
|
#
|
||||||
# This maps properties to Emesary Messages that will be publishes using the
|
# This maps properties to Emesary Messages that will be published using the
|
||||||
#
|
#
|
||||||
# notifications.PFDEventNotification.NavComData
|
# notifications.PFDEventNotification.NavComData
|
||||||
#
|
#
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
|
|
||||||
var GenericNavComUpdater =
|
var GenericNavComUpdater =
|
||||||
{
|
{
|
||||||
new : func (device) {
|
new : func () {
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [
|
parents : [
|
||||||
GenericNavComUpdater,
|
GenericNavComUpdater,
|
||||||
PropertyUpdater.new(
|
PropertyUpdater.new(
|
||||||
device,
|
|
||||||
notifications.PFDEventNotification.DefaultType,
|
notifications.PFDEventNotification.DefaultType,
|
||||||
notifications.PFDEventNotification.NavComData
|
notifications.PFDEventNotification.NavComData
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
var NavDataInterface = {
|
var NavDataInterface = {
|
||||||
|
|
||||||
new : func (device)
|
new : func ()
|
||||||
{
|
{
|
||||||
var obj = { parents : [ NavDataInterface ] };
|
var obj = { parents : [ NavDataInterface ] };
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ new : func (device)
|
||||||
obj._recipient = nil;
|
obj._recipient = nil;
|
||||||
obj._transmitter = emesary.GlobalTransmitter;
|
obj._transmitter = emesary.GlobalTransmitter;
|
||||||
obj._registered = 0;
|
obj._registered = 0;
|
||||||
obj._device = device;
|
|
||||||
obj._defaultDTO = "";
|
obj._defaultDTO = "";
|
||||||
|
|
||||||
# List of recently use waypoints
|
# List of recently use waypoints
|
||||||
|
@ -221,7 +220,6 @@ RegisterWithEmesary : func()
|
||||||
{
|
{
|
||||||
if (me._recipient == nil){
|
if (me._recipient == nil){
|
||||||
me._recipient = emesary.Recipient.new("DataInterface");
|
me._recipient = emesary.Recipient.new("DataInterface");
|
||||||
var pfd_obj = me._device;
|
|
||||||
var controller = me;
|
var controller = me;
|
||||||
|
|
||||||
# Note that unlike the various keys, this data isn't specific to a particular
|
# Note that unlike the various keys, this data isn't specific to a particular
|
||||||
|
|
|
@ -22,10 +22,9 @@ var PropertyUpdater =
|
||||||
setValue : func(val) { me._prop.setValue(val); },
|
setValue : func(val) { me._prop.setValue(val); },
|
||||||
},
|
},
|
||||||
|
|
||||||
new : func (device, notificationType, eventID) {
|
new : func (notificationType, eventID) {
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [ PropertyUpdater ],
|
parents : [ PropertyUpdater ],
|
||||||
_device : device,
|
|
||||||
_notificationType : notificationType,
|
_notificationType : notificationType,
|
||||||
_eventID : eventID,
|
_eventID : eventID,
|
||||||
_recipient : nil,
|
_recipient : nil,
|
||||||
|
@ -66,7 +65,6 @@ var PropertyUpdater =
|
||||||
|
|
||||||
if (me._recipient == nil){
|
if (me._recipient == nil){
|
||||||
me._recipient = emesary.Recipient.new("PropertyUpdater");
|
me._recipient = emesary.Recipient.new("PropertyUpdater");
|
||||||
var pfd_obj = me._device;
|
|
||||||
var notificationtype = me._notificationType;
|
var notificationtype = me._notificationType;
|
||||||
var eventID = me._eventID;
|
var eventID = me._eventID;
|
||||||
var controller = me;
|
var controller = me;
|
||||||
|
|
|
@ -1,24 +1,5 @@
|
||||||
# FG1000 MFD
|
# FG1000 MFD
|
||||||
|
|
||||||
print("##############");
|
|
||||||
print("# FG1000 MFD #");
|
|
||||||
print("##############\n");
|
|
||||||
|
|
||||||
io.include("Constants.nas");
|
|
||||||
io.include("Commands.nas");
|
|
||||||
|
|
||||||
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
|
||||||
|
|
||||||
io.load_nasal(nasal_dir ~ '/ConfigStore.nas', "fg1000");
|
|
||||||
|
|
||||||
io.load_nasal(nasal_dir ~ '/MFDPage.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ '/MFDPageController.nas', "fg1000");
|
|
||||||
|
|
||||||
io.load_nasal(nasal_dir ~ '/EIS/EIS.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ '/EIS/EISStyles.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ '/EIS/EISOptions.nas', "fg1000");
|
|
||||||
io.load_nasal(nasal_dir ~ '/EIS/EISController.nas', "fg1000");
|
|
||||||
|
|
||||||
var MFDPages = [
|
var MFDPages = [
|
||||||
"NavigationMap",
|
"NavigationMap",
|
||||||
"TrafficMap",
|
"TrafficMap",
|
||||||
|
@ -61,6 +42,8 @@ var MFDPages = [
|
||||||
"Surround",
|
"Surround",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
|
||||||
foreach (var page; MFDPages) {
|
foreach (var page; MFDPages) {
|
||||||
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ '.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ '.nas', "fg1000");
|
||||||
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ 'Styles.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ "MFDPages/" ~ page ~ '/' ~ page ~ 'Styles.nas', "fg1000");
|
||||||
|
@ -70,7 +53,7 @@ foreach (var page; MFDPages) {
|
||||||
|
|
||||||
var MFD =
|
var MFD =
|
||||||
{
|
{
|
||||||
new : func (myCanvas, device_id=1)
|
new : func (fg1000instance, EIS_Class, EIS_SVG, myCanvas, device_id=1)
|
||||||
{
|
{
|
||||||
var obj = {
|
var obj = {
|
||||||
parents : [ MFD ],
|
parents : [ MFD ],
|
||||||
|
@ -78,9 +61,11 @@ var MFD =
|
||||||
NavigationMap: nil,
|
NavigationMap: nil,
|
||||||
Surround : nil,
|
Surround : nil,
|
||||||
_pageList : {},
|
_pageList : {},
|
||||||
|
_fg1000 : fg1000instance,
|
||||||
|
_canvas : myCanvas,
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.ConfigStore = fg1000.ConfigStore.new();
|
obj.ConfigStore = obj._fg1000.getConfigStore();
|
||||||
|
|
||||||
obj._svg = myCanvas.createGroup("softkeys");
|
obj._svg = myCanvas.createGroup("softkeys");
|
||||||
obj._svg.set("clip-frame", canvas.Element.LOCAL);
|
obj._svg.set("clip-frame", canvas.Element.LOCAL);
|
||||||
|
@ -94,7 +79,7 @@ var MFD =
|
||||||
};
|
};
|
||||||
|
|
||||||
canvas.parsesvg(obj._svg,
|
canvas.parsesvg(obj._svg,
|
||||||
'/Aircraft/Instruments-3d/FG1000/MFDPages/EIS.svg',
|
EIS_SVG,
|
||||||
{'font-mapper': fontmapper});
|
{'font-mapper': fontmapper});
|
||||||
|
|
||||||
foreach (var page; MFDPages) {
|
foreach (var page; MFDPages) {
|
||||||
|
@ -120,7 +105,8 @@ var MFD =
|
||||||
obj.SurroundController = obj.Surround.getController();
|
obj.SurroundController = obj.Surround.getController();
|
||||||
|
|
||||||
# Engine Information System. A special case as it's always displayed on the MFD.
|
# Engine Information System. A special case as it's always displayed on the MFD.
|
||||||
obj.EIS = fg1000.EIS.new(obj, myCanvas, obj._MFDDevice, obj._svg);
|
# Note that it is passed in on the constructor
|
||||||
|
obj.EIS = EIS_Class.new(obj, myCanvas, obj._MFDDevice, obj._svg);
|
||||||
obj.addPage("EIS", obj.EIS);
|
obj.addPage("EIS", obj.EIS);
|
||||||
|
|
||||||
# The NavigationMap page is a special case, as it is displayed with the Nearest... pages as an overlay
|
# The NavigationMap page is a special case, as it is displayed with the Nearest... pages as an overlay
|
||||||
|
@ -173,4 +159,8 @@ var MFD =
|
||||||
getDeviceID : func() {
|
getDeviceID : func() {
|
||||||
return me._MFDDevice.device_id;
|
return me._MFDDevice.device_id;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getCanvas : func() {
|
||||||
|
return me._canvas;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
62
Aircraft/Instruments-3d/FG1000/README
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
README for the FG1000 glass panel display
|
||||||
|
|
||||||
|
The FG1000 aims to emulate the successful Garmin G1000 glass panel.
|
||||||
|
|
||||||
|
Development status can be found on the wiki: http://wiki.flightgear.org/FG1000
|
||||||
|
|
||||||
|
=How To Install On An Aircraft=
|
||||||
|
|
||||||
|
1) Place one or more of the display (GDU) units in your model. The XML files
|
||||||
|
are named <model>.<device-number>.xml, e.g.
|
||||||
|
|
||||||
|
GDU-1045.1.xml GDU-1045.2.xml GDU-1045.3.xml GDU-1045.4.xml
|
||||||
|
|
||||||
|
The <device-number> is referenced later to identify which displays to used
|
||||||
|
for each PFD, MFD etc. You must only used one of each <device-number> value,
|
||||||
|
though you can mix and match the GDU models.
|
||||||
|
|
||||||
|
2) Create Interfaces for Navigation, engine, NAV/COM, FMS data. There is a
|
||||||
|
generic interface (GenericInterfaceController) that uses the standard FG route
|
||||||
|
manager, GPS, navigation data and NAV/COM settings, and engine data for a single
|
||||||
|
piston engine.
|
||||||
|
|
||||||
|
You need to load it as follows:
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
var interfaceController = fg1000.GenericInterfaceController.new();
|
||||||
|
interfaceController.start();
|
||||||
|
|
||||||
|
You may want to create your own version depending on what properties you are
|
||||||
|
using for the NAV/COM, and your engine configuration.
|
||||||
|
|
||||||
|
Note that you should only start the interface after you've loaded the FG1000
|
||||||
|
as they will publish information at start of day that the displays need.
|
||||||
|
|
||||||
|
3) Set up the Engine Information System. There is a generic EIS provided
|
||||||
|
(see FG1000/Nasal/EIS, and FG1000/MFDPages/EIS.svg) that is intended to match
|
||||||
|
a Cessna 172. If you need something different, you should create your own
|
||||||
|
EIS class and SVG file.
|
||||||
|
|
||||||
|
Note that you need to pass data to/from the engine using Emesary. See
|
||||||
|
Interfaces/GenericEISPublisher.nas for a reference implementation.
|
||||||
|
|
||||||
|
4) Load the FG1000 itself. See FG1000/Nasal/FG1000.nas for full details,
|
||||||
|
including how to pass in the EIS. A simple FG1000 using the generic EIS, and
|
||||||
|
displaying PFD on device-number 1 and an MFD on device-number 2 is as follows:
|
||||||
|
|
||||||
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
|
io.load_nasal(nasal_dir ~ 'FG1000.nas', "fg1000");
|
||||||
|
|
||||||
|
# Create the FG1000
|
||||||
|
var fg1000system = fg1000.FG1000.new();
|
||||||
|
|
||||||
|
# Create a PFD as device 1, MFD as device 2
|
||||||
|
fg1000system.addPFD(1);
|
||||||
|
fg1000system.addMFD(2);
|
||||||
|
|
||||||
|
# Display the devices
|
||||||
|
fg1000system.display(1);
|
||||||
|
fg1000system.display(2);
|
||||||
|
|
||||||
|
# Display a GUI version of device 1 at 50% scale.
|
||||||
|
#fg1000system.displayGUI(1, 0.5);
|
|
@ -827,8 +827,18 @@
|
||||||
<command>nasal</command>
|
<command>nasal</command>
|
||||||
<script>
|
<script>
|
||||||
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
||||||
io.load_nasal(nasal_dir ~ 'GUI.nas', "fg1000");
|
io.load_nasal(nasal_dir ~ 'FG1000.nas', "fg1000");
|
||||||
var MFD_GUI = fg1000.MFDGUI.new();
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericInterfaceController.nas', "fg1000");
|
||||||
|
|
||||||
|
var fg1000system = fg1000.FG1000.new();
|
||||||
|
fg1000system.addMFD(0);
|
||||||
|
fg1000system.displayGUI(0);
|
||||||
|
|
||||||
|
# Start the interface controller after the FG1000, as it will publish
|
||||||
|
# immediately and update the NAV/COM data.
|
||||||
|
var interfaceController = fg1000.GenericInterfaceController.new();
|
||||||
|
interfaceController.start();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</binding>
|
</binding>
|
||||||
</item>
|
</item>
|
||||||
|
|