diff --git a/Joysticks/fsbgns530.joystick.json b/Joysticks/fsbgns530.joystick.json
new file mode 100644
index 000000000..31d70b34b
--- /dev/null
+++ b/Joysticks/fsbgns530.joystick.json
@@ -0,0 +1,155 @@
+{
+ "$schema": "./mfjoystick.schema.json",
+ "InstanceName": "FlightSimBuilder 530",
+ "VendorId": 1240,
+ "ProductId": 59094,
+ "Inputs": [
+ {
+ "Id": 1,
+ "Type": "Button",
+ "Label": "Left - Knob Outer - Left"
+ },
+ {
+ "Id": 2,
+ "Type": "Button",
+ "Label": "Left - Knob Outer - Right"
+ },
+ {
+ "Id": 3,
+ "Type": "Button",
+ "Label": "Left - Knob Inner - Left"
+ },
+ {
+ "Id": 4,
+ "Type": "Button",
+ "Label": "Left - Knob Inner - Right"
+ },
+ {
+ "Id": 5,
+ "Type": "Button",
+ "Label": "Left - Knob Inner - Push"
+ },
+ {
+ "Id": 7,
+ "Type": "Button",
+ "Label": "Right - Knob Outer - Left"
+ },
+ {
+ "Id": 8,
+ "Type": "Button",
+ "Label": "Right - Knob Outer - Right"
+ },
+ {
+ "Id": 9,
+ "Type": "Button",
+ "Label": "Right - Knob Inner - Left"
+ },
+ {
+ "Id": 10,
+ "Type": "Button",
+ "Label": "Right - Knob Inner - Right"
+ },
+ {
+ "Id": 11,
+ "Type": "Button",
+ "Label": "Right - Knob Inner - Push"
+ },
+ {
+ "Id": 12,
+ "Type": "Button",
+ "Label": "UNUSED"
+ },
+ {
+ "Id": 13,
+ "Type": "Button",
+ "Label": "C <->"
+ },
+ {
+ "Id": 14,
+ "Type": "Button",
+ "Label": ".C"
+ },
+ {
+ "Id": 15,
+ "Type": "Button",
+ "Label": "V <->"
+ },
+ {
+ "Id": 16,
+ "Type": "Button",
+ "Label": ".V"
+ },
+ {
+ "Id": 17,
+ "Type": "Button",
+ "Label": "UNUSED"
+ },
+ {
+ "Id": 18,
+ "Type": "Button",
+ "Label": "UNUSED"
+ },
+ {
+ "Id": 19,
+ "Type": "Button",
+ "Label": "CDI"
+ },
+ {
+ "Id": 20,
+ "Type": "Button",
+ "Label": "OBS"
+ },
+ {
+ "Id": 21,
+ "Type": "Button",
+ "Label": "MSG"
+ },
+ {
+ "Id": 22,
+ "Type": "Button",
+ "Label": "FPL"
+ },
+ {
+ "Id": 23,
+ "Type": "Button",
+ "Label": "VNAV"
+ },
+ {
+ "Id": 24,
+ "Type": "Button",
+ "Label": "PROC"
+ },
+ {
+ "Id": 25,
+ "Type": "Button",
+ "Label": "RNG UP"
+ },
+ {
+ "Id": 26,
+ "Type": "Button",
+ "Label": "RNG DOWN"
+ },
+ {
+ "Id": 27,
+ "Type": "Button",
+ "Label": "Direct To"
+ },
+ {
+ "Id": 28,
+ "Type": "Button",
+ "Label": "MENU"
+ },
+ {
+ "Id": 29,
+ "Type": "Button",
+ "Label": "CLR"
+ },
+ {
+ "Id": 30,
+ "Type": "Button",
+ "Label": "ENT"
+ }
+ ],
+ "Outputs": [
+ ]
+}
diff --git a/Joysticks/saitek.multipanel.joystick.json b/Joysticks/saitek.multipanel.joystick.json
new file mode 100644
index 000000000..5a1aef66a
--- /dev/null
+++ b/Joysticks/saitek.multipanel.joystick.json
@@ -0,0 +1,178 @@
+{
+ "$schema": "./mfjoystick.schema.json",
+ "InstanceName": "Pro Flight Multi Panel",
+ "VendorId": 1699,
+ "ProductId": 3334,
+ "Inputs": [
+ {
+ "Id": 0,
+ "Type": "Button",
+ "Label": "Position Switch - ALT"
+ },
+ {
+ "Id": 1,
+ "Type": "Button",
+ "Label": "Position Switch - VS"
+ },
+ {
+ "Id": 2,
+ "Type": "Button",
+ "Label": "Position Switch - IAS"
+ },
+ {
+ "Id": 3,
+ "Type": "Button",
+ "Label": "Position Switch - HDG"
+ },
+ {
+ "Id": 4,
+ "Type": "Button",
+ "Label": "Position Switch - CRS"
+ },
+ {
+ "Id": 5,
+ "Type": "Button",
+ "Label": "Encoder Right"
+ },
+ {
+ "Id": 6,
+ "Type": "Button",
+ "Label": "Encoder Left"
+ },
+ {
+ "Id": 7,
+ "Type": "Button",
+ "Label": "AP Button"
+ },
+ {
+ "Id": 8,
+ "Type": "Button",
+ "Label": "HDG Button"
+ },
+ {
+ "Id": 9,
+ "Type": "Button",
+ "Label": "NAV Button"
+ },
+ {
+ "Id": 10,
+ "Type": "Button",
+ "Label": "IAS Button"
+ },
+ {
+ "Id": 11,
+ "Type": "Button",
+ "Label": "ALT Button"
+ },
+ {
+ "Id": 12,
+ "Type": "Button",
+ "Label": "VS Button"
+ },
+ {
+ "Id": 13,
+ "Type": "Button",
+ "Label": "APR Button"
+ },
+ {
+ "Id": 14,
+ "Type": "Button",
+ "Label": "REV Button"
+ },
+ {
+ "Id": 15,
+ "Type": "Button",
+ "Label": "Auto Throttle ARM"
+ },
+ {
+ "Id": 16,
+ "Type": "Button",
+ "Label": "Flaps UP"
+ },
+ {
+ "Id": 17,
+ "Type": "Button",
+ "Label": "Flaps DN"
+ },
+ {
+ "Id": 18,
+ "Type": "Button",
+ "Label": "Pitch Trim DN"
+ },
+ {
+ "Id": 19,
+ "Type": "Button",
+ "Label": "Pitch Trim UP"
+ }
+ ],
+ "Outputs": [
+ {
+ "Label": "AP Mode - On/Off",
+ "Type": "Output",
+ "Id": "AP.autopilot",
+ "Byte": 11,
+ "Bit": 0
+ },
+ {
+ "Label": "AP Mode - HDG",
+ "Type": "Output",
+ "Id": "AP.hdg",
+ "Byte": 11,
+ "Bit": 1
+ },
+ {
+ "Label": "AP Mode - NAV",
+ "Id": "AP.nav",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 2
+ },
+ {
+ "Label": "AP Mode - IAS",
+ "Id": "AP.ias",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 3
+ },
+ {
+ "Label": "AP Mode - ALT",
+ "Id": "AP.alt",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 4
+ },
+ {
+ "Label": "AP Mode - VS",
+ "Id": "AP.vs",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 5
+ },
+ {
+ "Label": "AP Mode - APR",
+ "Id": "AP.apr",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 6
+ },
+ {
+ "Label": "AP Mode - REV",
+ "Id": "AP.rev",
+ "Type": "Output",
+ "Byte": 11,
+ "Bit": 7
+ },
+ {
+ "Label": "Line 1",
+ "Id": "CUSTOM.line1",
+ "Byte": 1,
+ "Type": "Custom"
+ },
+ {
+ "Label": "Line 2",
+ "Id": "CUSTOM.line2",
+ "Byte": 6,
+ "Type": "Custom"
+ }
+ ]
+}
diff --git a/MobiFlight/CustomDevices/CustomDevice.cs b/MobiFlight/CustomDevices/CustomDevice.cs
index 6f36f09f3..749923c98 100644
--- a/MobiFlight/CustomDevices/CustomDevice.cs
+++ b/MobiFlight/CustomDevices/CustomDevice.cs
@@ -125,7 +125,7 @@ public class CustomDevice : IMigrateable
///
/// List of MessageTypes supported by the device.
///
- public List MessageTypes = new List();
+ public List MessageTypes { get; set; } = new List();
///
/// Base path for custom firmware
diff --git a/MobiFlight/CustomDevices/IMessageTypeProvider.cs b/MobiFlight/CustomDevices/IMessageTypeProvider.cs
new file mode 100644
index 000000000..0c426cb28
--- /dev/null
+++ b/MobiFlight/CustomDevices/IMessageTypeProvider.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace MobiFlight.CustomDevices
+{
+ public interface IMessageTypeProvider
+ {
+ List MessageTypes { get; }
+ }
+}
\ No newline at end of file
diff --git a/MobiFlight/ExecutionManager.cs b/MobiFlight/ExecutionManager.cs
index 6e83e485a..e306dfd08 100644
--- a/MobiFlight/ExecutionManager.cs
+++ b/MobiFlight/ExecutionManager.cs
@@ -142,7 +142,7 @@ public ExecutionManager(DataGridView dataGridViewConfig, DataGridView inputsData
#endif
joystickManager.SetHandle(handle);
joystickManager.OnButtonPressed += new ButtonEventHandler(mobiFlightCache_OnButtonPressed);
- joystickManager.Connected += (o, e) => { joystickManager.Startup(); };
+ joystickManager.Connected += (o, e) => { joystickManager.Startup(); };
if (Properties.Settings.Default.EnableJoystickSupport)
{
joystickManager.Connect();
@@ -186,7 +186,7 @@ internal Dictionary GetAvailableVariables()
// cfg was not set yet, e.g. we created row and are still in edit mode and now we hit "Edit"
if (cfg == null) continue;
-
+
if (cfg.SourceType != SourceType.VARIABLE) continue;
if (cfg.MobiFlightVariable == null) continue;
@@ -208,7 +208,7 @@ internal Dictionary GetAvailableVariables()
List actions = cfg.GetInputActionsByType(typeof(VariableInputAction));
- if(actions == null) continue;
+ if (actions == null) continue;
actions.ForEach(action =>
{
@@ -280,7 +280,7 @@ public bool ModulesAvailable()
#if ARCAZE
arcazeCache.Available() ||
#endif
- mobiFlightCache.Available();
+ mobiFlightCache.Available() || joystickManager.GetJoysticks().Count > 0;
#endif
}
@@ -732,13 +732,23 @@ private string ExecuteDisplay(string value, OutputConfigItem cfg)
if (serial.IndexOf(Joystick.SerialPrefix)==0)
{
- Joystick joystick = joystickManager.GetJoystickBySerial(serial);
+ IHidDevice joystick = joystickManager.GetJoystickBySerial(serial);
if(joystick != null)
{
- byte state = 0;
- if (value != "0") state = 1;
+ if (cfg.DisplayType==DeviceType.CustomDevice.ToString())
+ {
+ var device = joystick.GetAvailableOutputDevicesAsListItems().Find(d => {
+ return (d.Value as ICustomDevice)?.Name == cfg.CustomDevice.CustomName;
+ });
+ if (device == null) return value;
+ (device.Value as ICustomDevice).Display(cfg.CustomDevice.MessageType, value);
+ } else
+ {
+ byte state = 0;
+ if (value != "0") state = 1;
- joystick.SetOutputDeviceState(cfg.Pin.DisplayPin, state);
+ joystick.SetOutputDeviceState(cfg.Pin.DisplayPin, state);
+ }
joystick.UpdateOutputDeviceStates();
joystick.Update();
} else
diff --git a/MobiFlight/ICustomDevice.cs b/MobiFlight/ICustomDevice.cs
new file mode 100644
index 000000000..8759086a8
--- /dev/null
+++ b/MobiFlight/ICustomDevice.cs
@@ -0,0 +1,11 @@
+using MobiFlight.CustomDevices;
+using System.Collections.Generic;
+
+namespace MobiFlight
+{
+ public interface ICustomDevice : IConnectedDevice
+ {
+ void Display(int MessageType, string value);
+ List MessageTypes { get; }
+ }
+}
\ No newline at end of file
diff --git a/MobiFlight/Joysticks/FlightSimBuilder/GNS530.cs b/MobiFlight/Joysticks/FlightSimBuilder/GNS530.cs
new file mode 100644
index 000000000..900517a04
--- /dev/null
+++ b/MobiFlight/Joysticks/FlightSimBuilder/GNS530.cs
@@ -0,0 +1,73 @@
+using HidSharp;
+using HidSharp.Reports;
+using HidSharp.Reports.Input;
+
+namespace MobiFlight.Joysticks.FlightSimBuilder
+{
+ internal class GNS530 : Joystick
+ {
+ int VendorId = 0x04D8;
+ int ProductId = 0xE89D;
+ HidStream Stream { get; set; }
+ HidSharp.HidDevice Device { get; set; }
+
+ protected HidDeviceInputReceiver inputReceiver;
+
+ public GNS530(SharpDX.DirectInput.Joystick joystick, JoystickDefinition definition) : base(joystick, definition) {
+ }
+
+ public void Connect()
+ {
+ if (Device == null)
+ {
+ Device = DeviceList.Local.GetHidDeviceOrNull(vendorID: VendorId, productID: ProductId);
+ if (Device == null) return;
+ }
+
+ Stream = Device.Open();
+ var reportDescriptor = Device.GetReportDescriptor();
+ inputReceiver = reportDescriptor.CreateHidDeviceInputReceiver();
+ inputReceiver.Received += InputReceiver_Received;
+ inputReceiver.Start(Stream);
+ }
+
+ private void InputReceiver_Received(object sender, System.EventArgs e)
+ {
+ var inputRec = sender as HidDeviceInputReceiver;
+ var inputReportBuffer = new byte[5];
+
+ while (inputRec.TryRead(inputReportBuffer, 0, out Report report))
+ {
+ var newState = Gns530Report.ParseReport(inputReportBuffer).ToJoystickState();
+ UpdateButtons(newState);
+ // at the very end update our state
+ State = newState;
+ }
+ }
+
+ protected override void SendData(byte[] data)
+ {
+ /* do nothing */
+ }
+
+ public override void Update()
+ {
+ if (Stream == null || inputReceiver == null)
+ {
+ Connect();
+ };
+ // We don't do anything else
+ // because we have a callback for
+ // handling the incoming reports
+ // InputReceiver_Received(inputReceiver, new System.EventArgs());
+ }
+
+ public override void Shutdown()
+ {
+ Stream.Close();
+ inputReceiver.Received -= InputReceiver_Received;
+ Stream = null;
+ inputReceiver = null;
+ }
+ }
+}
diff --git a/MobiFlight/Joysticks/FlightSimBuilder/Gns530Report.cs b/MobiFlight/Joysticks/FlightSimBuilder/Gns530Report.cs
new file mode 100644
index 000000000..8518c9ddc
--- /dev/null
+++ b/MobiFlight/Joysticks/FlightSimBuilder/Gns530Report.cs
@@ -0,0 +1,33 @@
+using SharpDX.DirectInput;
+
+namespace MobiFlight.Joysticks.FlightSimBuilder
+{
+ internal class Gns530Report
+ {
+ public uint reportID;
+ public int rxAxis;
+ public uint buttonState;
+ static public Gns530Report ParseReport(byte[] inputBuffer)
+ {
+ var result = new Gns530Report();
+ // get Report ID
+ result.reportID = inputBuffer[0];
+ // Extract the 10-bit value (bitmask 0x03FF isolates the first 10 bits)
+ // rxAxis = (inputBuffer[2] << 8 | inputBuffer[1]) & 0x03FF;
+ // get 32 bit Button report field:
+ result.buttonState = (uint)inputBuffer[1] + ((uint)inputBuffer[2] << 8) + ((uint)inputBuffer[3] << 16) + ((uint)inputBuffer[4] << 24);
+ return result;
+ }
+ public JoystickState ToJoystickState()
+ {
+ var result = new JoystickState();
+
+ for (int i = 0; i != 30; i++)
+ {
+ result.Buttons[i] = (buttonState & (1 << i)) != 0;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/MobiFlight/Joysticks/HidDevice.cs b/MobiFlight/Joysticks/HidDevice.cs
new file mode 100644
index 000000000..c1b5d9f29
--- /dev/null
+++ b/MobiFlight/Joysticks/HidDevice.cs
@@ -0,0 +1,343 @@
+using HidSharp;
+using HidSharp.Reports;
+using HidSharp.Reports.Input;
+using MobiFlight.Config;
+using MobiFlight.Joysticks.Logitech;
+using SharpDX.DirectInput;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MobiFlight.Joysticks
+{
+ internal class HidDevice : IHidDevice
+ {
+ public static readonly string ButtonPrefix = "Button";
+ public static readonly string AxisPrefix = "Axis";
+ public static readonly string PovPrefix = "POV";
+ public static readonly string SerialPrefix = "JS-";
+
+ public string Name { get { return Definition.InstanceName; }}
+ public string Serial { get { return $"{SerialPrefix}{Definition.InstanceName}"; } }
+
+ protected JoystickState State = null;
+ protected List Buttons = new List();
+ private readonly List Axes = new List();
+ private readonly List POV = new List();
+ private readonly List Outputs = new List();
+
+ public event ButtonEventHandler OnButtonPressed;
+
+ protected readonly JoystickDefinition Definition;
+ protected bool RequiresOutputUpdate = false;
+ private HidStream Stream;
+ private HidSharp.HidDevice Device;
+
+ protected HidDeviceInputReceiver inputReceiver;
+
+ public HidDevice(JoystickDefinition definition)
+ {
+ Definition = definition;
+ }
+
+ public void Connect()
+ {
+ if (Device == null)
+ {
+ Device = DeviceList.Local.GetHidDeviceOrNull(vendorID: Definition.VendorId, productID: Definition.ProductId);
+ if (Device == null) return;
+ }
+
+ Stream = Device.Open();
+ var reportDescriptor = Device.GetReportDescriptor();
+ InitializeDevicesWithDescriptor(reportDescriptor);
+ inputReceiver = reportDescriptor.CreateHidDeviceInputReceiver();
+ inputReceiver.Received += InputReceiver_Received;
+ inputReceiver.Start(Stream);
+ }
+
+ private void InitializeDevicesWithDescriptor(ReportDescriptor reportDescriptor)
+ {
+ reportDescriptor.Reports.ToList().ForEach(report =>
+ {
+ if (report.ReportType == ReportType.Input)
+ {
+ report.DataItems.ToList().ForEach(data =>
+ {
+ if (data.ExpectedUsageType == ExpectedUsageType.PushButton)
+ {
+ for (var i = 0; i < data.ElementCount; i++)
+ {
+ var buttonName = $"{ButtonPrefix} {i}";
+ var buttonLabel = MapDeviceNameToLabel(buttonName);
+ Buttons.Add(new JoystickDevice() { Name = buttonName, Label = buttonLabel, Type = DeviceType.Button, JoystickDeviceType = JoystickDeviceType.Button });
+ }
+ }
+ });
+ }
+
+ if (report.ReportType == ReportType.Feature)
+ {
+ // Do something with the feature information from the json file
+ }
+
+ if (report.ReportType == ReportType.Output)
+ {
+ // Do something with the output information from the json file
+ }
+ });
+ reportDescriptor.DeviceItems.ToList().ForEach(item => {
+ var parser = item.CreateDeviceItemInputParser();
+ });
+
+ EnumerateOutputDevices();
+ }
+
+ virtual protected void EnumerateOutputDevices()
+ {
+ Outputs.Clear();
+
+ Definition?.Outputs?.ForEach(output => {
+ JoystickOutputDevice device = new JoystickOutputDevice() { Label = output.Label, Name = output.Id, Byte = output.Byte, Bit = output.Bit };
+ if (output.Type=="Custom")
+ {
+ device = new JoystickStringOutputDevice(device);
+ }
+ Outputs.Add(device);
+ });
+ return;
+ }
+
+ public string MapDeviceNameToLabel(string deviceName)
+ {
+ // First try and look for a custom label.
+ var input = Definition?.FindInputByName(deviceName);
+ if (input != null)
+ {
+ return input.Label;
+ }
+
+ string result = string.Empty;
+
+ if (deviceName.StartsWith(ButtonPrefix))
+ {
+ result = Buttons.Find(b => b.Name == deviceName)?.Label ?? string.Empty;
+ }
+ else if (deviceName.StartsWith(AxisPrefix))
+ {
+ result = Axes.Find(a => a.Name == deviceName)?.Label ?? string.Empty;
+ }
+ else if (deviceName.StartsWith(PovPrefix))
+ {
+ result = POV.Find(p => p.Name == deviceName)?.Label ?? string.Empty;
+ }
+
+ if (result == string.Empty)
+ result = deviceName;
+
+ return result;
+ }
+
+ protected void UpdateButtons(JoystickState newState)
+ {
+ if (Buttons.Count == 0) return;
+
+ for (int i = 0; i < newState.Buttons.Length; i++)
+ {
+ if (!StateExists() || State.Buttons.Length < i || State.Buttons[i] != newState.Buttons[i])
+ {
+ if (newState.Buttons[i] || (State != null))
+ OnButtonPressed?.Invoke(this, new InputEventArgs()
+ {
+ Name = Name,
+ DeviceId = Buttons[i].Name,
+ DeviceLabel = Buttons[i].Label,
+ Serial = Serial,
+ Type = DeviceType.Button,
+ Value = newState.Buttons[i] ? 0 : 1
+ });
+ }
+ }
+ }
+
+ private void InputReceiver_Received(object sender, System.EventArgs e)
+ {
+ var inputRec = sender as HidDeviceInputReceiver;
+ var inputReportBuffer = new byte[32];
+
+ while (inputRec.TryRead(inputReportBuffer, 0, out Report report))
+ {
+ var newState = MultipanelReport.ParseReport(inputReportBuffer).ToJoystickState();
+ UpdateButtons(newState);
+ // at the very end update our state
+ State = newState;
+ }
+ }
+
+ private bool StateExists()
+ {
+ return State != null;
+ }
+
+ public void SetOutputDeviceState(string name, byte state)
+ {
+ foreach (var light in Outputs.FindAll(l => l.JoystickDeviceType == JoystickDeviceType.Light))
+ {
+ if (light.Label != name) continue;
+ if (light.State == state) continue;
+
+ light.State = state;
+ RequiresOutputUpdate = true;
+ break;
+ }
+ }
+ public void SetCustomDeviceState(string name, string value)
+ {
+ foreach (var light in Outputs.FindAll(l => l.JoystickDeviceType == JoystickDeviceType.String))
+ {
+ //
+ }
+ }
+
+ protected virtual void SendData(byte[] data)
+ {
+ // Don't try and send data if no outputs are defined.
+ if (Definition?.Outputs == null || Definition?.Outputs.Count == 0)
+ {
+ return;
+ }
+
+ if (!RequiresOutputUpdate) return;
+ if (Stream == null)
+ {
+ Connect();
+ };
+ Stream.SetFeature(data);
+
+ RequiresOutputUpdate = false;
+ }
+
+ public void UpdateOutputDeviceStates()
+ {
+ var data = new byte[] { 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0, 0xff };
+ var mappingTable = new Dictionary()
+ {
+ { " ", 0b00001111 },
+ { "0", 0x00 },
+ { "1", 0x01 },
+ { "2", 0x02 },
+ { "3", 0x03 },
+ { "4", 0x04 },
+ { "5", 0x05 },
+ { "6", 0x06 },
+ { "7", 0x07 },
+ { "8", 0x08 },
+ { "9", 0x09 },
+ };
+
+ foreach (var light in Outputs.FindAll(l=>l.JoystickDeviceType==JoystickDeviceType.Light))
+ {
+ data[light.Byte] |= (byte)(light.State << light.Bit);
+ }
+
+ foreach (var stringOutput in Outputs.FindAll(l=>l.JoystickDeviceType==JoystickDeviceType.String))
+ {
+ var strOutputDevice = stringOutput as JoystickStringOutputDevice;
+ if (strOutputDevice == null) continue;
+ if (strOutputDevice.StringState == null) continue;
+ for (var i = 0; i!= strOutputDevice.StringState.Length; i++)
+ {
+ var value = mappingTable.ContainsKey(strOutputDevice.StringState[i].ToString()) ? mappingTable[strOutputDevice.StringState[i].ToString()] : (byte)0b00001111;
+ data[i + strOutputDevice.Byte] = value;
+ }
+ }
+ RequiresOutputUpdate = true;
+
+ SendData(data);
+ }
+
+ public virtual void Update()
+ {
+ if (Stream == null || inputReceiver == null)
+ {
+ Connect();
+ };
+ }
+
+ public virtual void Shutdown()
+ {
+ Stream.Close();
+ inputReceiver.Received -= InputReceiver_Received;
+ Stream = null;
+ inputReceiver = null;
+ }
+
+ public List> GetAvailableDevicesAsListItems()
+ {
+ List> result = new List>();
+
+ GetButtonsSorted().ForEach((item) =>
+ {
+ result.Add(item.ToListItem());
+ });
+ GetAxisSorted().ForEach((item) =>
+ {
+ result.Add(item.ToListItem());
+ });
+ POV.ForEach((item) =>
+ {
+ result.Add(item.ToListItem());
+ });
+ return result;
+ }
+
+ public List> GetAvailableOutputDevicesAsListItems()
+ {
+ List> result = new List>();
+ Outputs.ForEach((item) =>
+ {
+ result.Add(item.ToListItem());
+ });
+ return result;
+ }
+
+ private List GetButtonsSorted()
+ {
+ var buttons = Buttons.ToArray().ToList();
+ buttons.Sort(SortByPositionInDefintion);
+ return Buttons;
+ }
+
+ private List GetAxisSorted()
+ {
+ var axes = Axes.ToArray().ToList();
+ Axes.Sort(SortByPositionInDefintion);
+
+ return Axes;
+ }
+
+ public int GetIndexForKey(string key)
+ {
+ return Definition?.Inputs?.FindIndex(input => input.Name == key) ?? 0;
+ }
+
+ int SortByPositionInDefintion(JoystickDevice b1, JoystickDevice b2)
+ {
+ if (GetIndexForKey(b1.Name) == GetIndexForKey(b2.Name)) return 0;
+ if (GetIndexForKey(b1.Name) > GetIndexForKey(b2.Name)) return 1;
+ return -1;
+ }
+
+ public void Stop()
+ {
+ foreach (var light in Outputs)
+ {
+ light.State = 0;
+ }
+ RequiresOutputUpdate = true;
+ UpdateOutputDeviceStates();
+ }
+
+
+ }
+}
diff --git a/MobiFlight/Joysticks/IHidDevice.cs b/MobiFlight/Joysticks/IHidDevice.cs
new file mode 100644
index 000000000..3fccd890b
--- /dev/null
+++ b/MobiFlight/Joysticks/IHidDevice.cs
@@ -0,0 +1,22 @@
+using MobiFlight.Config;
+using System.Collections.Generic;
+using System;
+
+namespace MobiFlight
+{
+ public interface IHidDevice
+ {
+ string Name { get; }
+
+ string Serial { get; }
+
+ List> GetAvailableDevicesAsListItems();
+ List> GetAvailableOutputDevicesAsListItems();
+ string MapDeviceNameToLabel(string deviceName);
+ void SetOutputDeviceState(string displayPin, byte state);
+ void Shutdown();
+ void Stop();
+ void Update();
+ void UpdateOutputDeviceStates();
+ }
+}
\ No newline at end of file
diff --git a/MobiFlight/Joysticks/Joystick.cs b/MobiFlight/Joysticks/Joystick.cs
index 705e967f2..0d3eb3d17 100644
--- a/MobiFlight/Joysticks/Joystick.cs
+++ b/MobiFlight/Joysticks/Joystick.cs
@@ -12,7 +12,7 @@ public class JoystickNotConnectedException : Exception
public JoystickNotConnectedException(string Message) : base(Message) { }
}
- public class Joystick
+ public class Joystick : IHidDevice
{
public static readonly string ButtonPrefix = "Button";
public static readonly string AxisPrefix = "Axis";
@@ -32,7 +32,7 @@ public class Joystick
private HidDevice Device;
protected bool RequiresOutputUpdate = false;
- private JoystickState State = null;
+ protected JoystickState State = null;
private HidStream Stream;
private static readonly Dictionary UsageMap = new Dictionary
@@ -366,7 +366,7 @@ private void UpdateAxis(JoystickState newState)
}
}
- private void UpdateButtons(JoystickState newState)
+ protected void UpdateButtons(JoystickState newState)
{
if (Buttons.Count==0) return;
diff --git a/MobiFlight/Joysticks/JoystickDefinition.cs b/MobiFlight/Joysticks/JoystickDefinition.cs
index afdea18f4..052a589f5 100644
--- a/MobiFlight/Joysticks/JoystickDefinition.cs
+++ b/MobiFlight/Joysticks/JoystickDefinition.cs
@@ -33,6 +33,7 @@ public class JoystickDefinition : IMigrateable
///
public int VendorId;
+
///
/// Finds a JoystickInput given an input name. This will eventually get replaced with a method that
/// looks up by Id instead.
diff --git a/MobiFlight/Joysticks/JoystickDevice.cs b/MobiFlight/Joysticks/JoystickDevice.cs
index 002645d54..1857b3c30 100644
--- a/MobiFlight/Joysticks/JoystickDevice.cs
+++ b/MobiFlight/Joysticks/JoystickDevice.cs
@@ -1,5 +1,7 @@
using MobiFlight.Config;
+using MobiFlight.CustomDevices;
using System;
+using System.Collections.Generic;
namespace MobiFlight
{
@@ -24,7 +26,48 @@ public class JoystickOutputDevice : JoystickDevice
public byte State = 0;
public JoystickOutputDevice()
{
- Type = DeviceType.LedModule;
+ JoystickDeviceType = JoystickDeviceType.Light;
+ Type = DeviceType.Output;
+ }
+ }
+
+ public class JoystickStringOutputDevice : JoystickOutputDevice, ICustomDevice
+ {
+ public string StringState = null;
+
+ public JoystickStringOutputDevice()
+ {
+ Type = DeviceType.CustomDevice;
+ JoystickDeviceType = JoystickDeviceType.String;
+ }
+
+ public JoystickStringOutputDevice(JoystickOutputDevice device)
+ {
+ Type = DeviceType.CustomDevice;
+ Name = device.Name;
+ Label = device.Label;
+ Byte = device.Byte;
+ JoystickDeviceType = JoystickDeviceType.String;
+ }
+
+ public void Display(int MessageType, string value)
+ {
+ StringState = value;
+ }
+
+ public List MessageTypes
+ {
+ get
+ {
+ var list = new List();
+ list.Add(new MessageType() { Id=1, Description = "You can display up to 5 characters.", Label="Set LCD" });
+ return list;
+ }
+ }
+
+ public void Stop()
+ {
+ // Do nothing
}
}
}
diff --git a/MobiFlight/Joysticks/JoystickDeviceType.cs b/MobiFlight/Joysticks/JoystickDeviceType.cs
index ffc1ce6b4..08b2482ed 100644
--- a/MobiFlight/Joysticks/JoystickDeviceType.cs
+++ b/MobiFlight/Joysticks/JoystickDeviceType.cs
@@ -5,6 +5,7 @@ public enum JoystickDeviceType
Button,
Axis,
POV,
- Light
+ Light,
+ String
}
}
diff --git a/MobiFlight/Joysticks/JoystickManager.cs b/MobiFlight/Joysticks/JoystickManager.cs
index 09d50c6c1..dc5fd9bc2 100644
--- a/MobiFlight/Joysticks/JoystickManager.cs
+++ b/MobiFlight/Joysticks/JoystickManager.cs
@@ -1,10 +1,14 @@
-using MobiFlight.Joysticks.Octavi;
+using HidSharp;
+using MobiFlight.Joysticks.FlightSimBuilder;
+using MobiFlight.Joysticks.Logitech;
+using MobiFlight.Joysticks.Octavi;
using Newtonsoft.Json;
using SharpDX.DirectInput;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Timers;
namespace MobiFlight
@@ -31,7 +35,8 @@ public class JoystickManager
public event ButtonEventHandler OnButtonPressed;
private readonly Timer PollTimer = new Timer();
private readonly List Joysticks = new List();
- private readonly List ExcludedJoysticks = new List();
+ private readonly List HidDevices = new List();
+ private readonly List ExcludedJoysticks = new List();
private IntPtr Handle;
public JoystickManager()
@@ -114,12 +119,15 @@ public void Stop()
}
}
- public List GetJoysticks()
+ public List GetJoysticks()
{
- return Joysticks;
+ var result = new List();
+ result.AddRange(Joysticks);
+ result.AddRange(HidDevices);
+ return result;
}
- public List GetExcludedJoysticks()
+ public List GetExcludedJoysticks()
{
return ExcludedJoysticks;
}
@@ -129,14 +137,14 @@ public void SetHandle(IntPtr handle)
Handle = handle;
}
- public void Connect()
+ public async void Connect()
{
var di = new SharpDX.DirectInput.DirectInput();
Joysticks?.Clear();
ExcludedJoysticks?.Clear();
List settingsExcludedJoysticks = JsonConvert.DeserializeObject>(Properties.Settings.Default.ExcludedJoysticks);
-
- var devices = di.GetDevices(DeviceClass.GameControl, DeviceEnumerationFlags.AttachedOnly).ToList();
+
+ var devices = await Task.Run(() => { return di.GetDevices(DeviceClass.GameControl, DeviceEnumerationFlags.AttachedOnly).ToList(); }).ConfigureAwait(false);
foreach (var d in devices)
{
@@ -148,7 +156,7 @@ public void Connect()
continue;
}
- MobiFlight.Joystick js;
+ Joystick js;
if (d.InstanceName == "Octavi" || d.InstanceName == "IFR1")
{
js = new Octavi(
@@ -158,6 +166,15 @@ public void Connect()
GetDefinitionByInstanceName("Octavi")
);
}
+ else if (d.InstanceName == "FlightSimBuilder 530" || d.InstanceName == "FlightSimBuilder 530")
+ {
+ js = new GNS530(
+ new SharpDX.DirectInput.Joystick(di, d.InstanceGuid),
+ // statically set this to Octavi
+ // until we might support (Octavi|IFR1) or similar
+ GetDefinitionByInstanceName("FlightSimBuilder 530")
+ );
+ }
else
{
js = new Joystick(new SharpDX.DirectInput.Joystick(di, d.InstanceGuid), GetDefinitionByInstanceName(d.InstanceName));
@@ -185,6 +202,8 @@ public void Connect()
}
}
+ ConnectToDirectHid();
+
if (JoysticksConnected())
{
Joysticks.Sort((j1, j2) => j1.Name.CompareTo(j2.Name));
@@ -192,12 +211,37 @@ public void Connect()
}
}
+ private void ConnectToDirectHid()
+ {
+ HidDevices.Clear();
+ var directHidDevice = DeviceList.Local.GetHidDevices();
+ directHidDevice.ToList().ForEach(d =>
+ {
+ try
+ {
+ var FriendlyName = d.GetFriendlyName();
+
+ var definition = GetDefinitionByInstanceName(FriendlyName);
+ if (definition == null) return;
+
+ var js = new Multipanel(definition);
+ js.OnButtonPressed += Js_OnButtonPressed;
+ js.Connect();
+ HidDevices.Add(js);
+ }catch (Exception ex) {
+ return;
+ }
+ });
+ }
+
private void Js_OnDisconnected(object sender, EventArgs e)
{
- var js = sender as Joystick;
+ var js = sender as IHidDevice;
Log.Instance.log($"Joystick disconnected: {js.Name}.", LogSeverity.Info);
- lock (Joysticks)
- Joysticks.Remove(js);
+
+ if(js is Joystick)
+ lock (Joysticks)
+ Joysticks.Remove(js as Joystick);
}
private bool HasAxisOrButtons(Joystick js)
@@ -212,9 +256,12 @@ private void Js_OnButtonPressed(object sender, InputEventArgs e)
OnButtonPressed?.Invoke(sender, e);
}
- internal Joystick GetJoystickBySerial(string serial)
+ internal IHidDevice GetJoystickBySerial(string serial)
{
- return Joysticks.Find(js => js.Serial == serial);
+ var result = Joysticks.Find(js => js.Serial == serial);
+ if (result != null) return result;
+
+ return HidDevices.Find(js => js.Serial == serial);
}
public Dictionary GetStatistics()
diff --git a/MobiFlight/Joysticks/JoystickOutput.cs b/MobiFlight/Joysticks/JoystickOutput.cs
index cf3d1ae5f..bffa91eab 100644
--- a/MobiFlight/Joysticks/JoystickOutput.cs
+++ b/MobiFlight/Joysticks/JoystickOutput.cs
@@ -8,6 +8,10 @@ namespace MobiFlight
{
public class JoystickOutput
{
+ ///
+ /// Unique Id for the output.
+ ///
+ public string Type;
///
/// Unique Id for the output.
///
diff --git a/MobiFlight/Joysticks/Logitech/Multipanel.cs b/MobiFlight/Joysticks/Logitech/Multipanel.cs
new file mode 100644
index 000000000..596640b40
--- /dev/null
+++ b/MobiFlight/Joysticks/Logitech/Multipanel.cs
@@ -0,0 +1,12 @@
+using HidSharp;
+using HidSharp.Reports;
+using HidSharp.Reports.Input;
+
+namespace MobiFlight.Joysticks.Logitech
+{
+ internal class Multipanel : MobiFlight.Joysticks.HidDevice
+ {
+ public Multipanel(JoystickDefinition definition) : base(definition){
+ }
+ }
+}
diff --git a/MobiFlight/Joysticks/Logitech/MultipanelReport.cs b/MobiFlight/Joysticks/Logitech/MultipanelReport.cs
new file mode 100644
index 000000000..0ceda0b29
--- /dev/null
+++ b/MobiFlight/Joysticks/Logitech/MultipanelReport.cs
@@ -0,0 +1,33 @@
+using SharpDX.DirectInput;
+
+namespace MobiFlight.Joysticks.Logitech
+{
+ internal class MultipanelReport
+ {
+ public uint reportID;
+ public int rxAxis;
+ public uint buttonState;
+ static public MultipanelReport ParseReport(byte[] inputBuffer)
+ {
+ var result = new MultipanelReport();
+ // get Report ID
+ result.reportID = inputBuffer[0];
+ // Extract the 10-bit value (bitmask 0x03FF isolates the first 10 bits)
+ // rxAxis = (inputBuffer[2] << 8 | inputBuffer[1]) & 0x03FF;
+ // get 32 bit Button report field:
+ result.buttonState = (uint)inputBuffer[1] + ((uint)inputBuffer[2] << 8) + ((uint)inputBuffer[3] << 16) + ((uint)inputBuffer[4] << 24);
+ return result;
+ }
+ public JoystickState ToJoystickState()
+ {
+ var result = new JoystickState();
+
+ for (int i = 0; i != 30; i++)
+ {
+ result.Buttons[i] = (buttonState & (1 << i)) != 0;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/MobiFlight/Joysticks/Octavi/Octavi.cs b/MobiFlight/Joysticks/Octavi/Octavi.cs
index c275d9080..afdd9615f 100644
--- a/MobiFlight/Joysticks/Octavi/Octavi.cs
+++ b/MobiFlight/Joysticks/Octavi/Octavi.cs
@@ -1,9 +1,7 @@
using HidSharp;
using HidSharp.Reports;
using HidSharp.Reports.Input;
-using SharpDX.DirectInput;
using System.Collections.Generic;
-using System.Threading;
namespace MobiFlight.Joysticks.Octavi
{
@@ -12,9 +10,9 @@ internal class Octavi : Joystick
int VendorId = 0x04D8;
int ProductId = 0xE6D6;
HidStream Stream { get; set; }
- HidDevice Device { get; set; }
+ HidSharp.HidDevice Device { get; set; }
- protected HidSharp.Reports.Input.HidDeviceInputReceiver inputReceiver;
+ protected HidDeviceInputReceiver inputReceiver;
protected ReportDescriptor reportDescriptor;
protected Dictionary OctaviButtons = new Dictionary();
diff --git a/MobiFlight/MobiFlightCustomDevice.cs b/MobiFlight/MobiFlightCustomDevice.cs
index 62c547d21..ec1b61f80 100644
--- a/MobiFlight/MobiFlightCustomDevice.cs
+++ b/MobiFlight/MobiFlightCustomDevice.cs
@@ -1,8 +1,10 @@
using CommandMessenger;
+using MobiFlight.CustomDevices;
+using System.Collections.Generic;
namespace MobiFlight
{
- public class MobiFlightCustomDevice : IConnectedDevice
+ public class MobiFlightCustomDevice : ICustomDevice
{
public const string TYPE = "CustomDevice";
public const int MESSAGE_STOP = -1;
@@ -12,6 +14,7 @@ public class MobiFlightCustomDevice : IConnectedDevice
public DeviceType Type { get; set; } = DeviceType.CustomDevice;
public int DeviceNumber { get; set; }
public CustomDevices.CustomDevice CustomDevice { get; set; }
+ public List MessageTypes { get { return CustomDevice.MessageTypes; } }
public void Display(int MessageType, string value)
{
diff --git a/MobiFlightConnector.csproj b/MobiFlightConnector.csproj
index 58c303424..467a692ab 100644
--- a/MobiFlightConnector.csproj
+++ b/MobiFlightConnector.csproj
@@ -264,6 +264,7 @@
+
@@ -272,6 +273,10 @@
+
+
+
+
@@ -280,6 +285,8 @@
+
+
@@ -1054,6 +1061,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
diff --git a/UI/Dialogs/ConfigWizard.cs b/UI/Dialogs/ConfigWizard.cs
index fe3501b23..324e4381e 100644
--- a/UI/Dialogs/ConfigWizard.cs
+++ b/UI/Dialogs/ConfigWizard.cs
@@ -309,7 +309,7 @@ protected void _AddMobiFlightModules(List DisplayModuleList)
protected void _AddJoysticks(List DisplayModuleList)
{
- foreach (Joystick joystick in _execManager.GetJoystickManager().GetJoysticks())
+ foreach (IHidDevice joystick in _execManager.GetJoystickManager().GetJoysticks())
{
if (joystick.GetAvailableOutputDevicesAsListItems().Count == 0) continue;
diff --git a/UI/Dialogs/InputConfigWizard.cs b/UI/Dialogs/InputConfigWizard.cs
index f45fabd1d..dde417e2c 100644
--- a/UI/Dialogs/InputConfigWizard.cs
+++ b/UI/Dialogs/InputConfigWizard.cs
@@ -210,7 +210,7 @@ public void initWithArcazeCache(ArcazeCache arcazeCache)
});
}
- foreach (Joystick joystick in _execManager.GetJoystickManager().GetJoysticks())
+ foreach (IHidDevice joystick in _execManager.GetJoystickManager().GetJoysticks())
{
if (joystick.GetAvailableDevicesAsListItems().Count > 0)
inputModuleNameComboBox.Items.Add(new ListItem()
@@ -254,7 +254,7 @@ public void initWithoutArcazeCache()
// preconditionPinSerialComboBox.Items.Add(module.Name + "/ " + module.Serial);
}
- foreach (Joystick joystick in _execManager.GetJoystickManager().GetJoysticks())
+ foreach (IHidDevice joystick in _execManager.GetJoystickManager().GetJoysticks())
{
inputModuleNameComboBox.Items.Add(new ListItem()
{
@@ -468,7 +468,7 @@ private void ModuleSerialComboBox_SelectedIndexChanged(object sender, EventArgs
// Add all Joysticks
else if (Joystick.IsJoystickSerial(serial))
{
- Joystick joystick = _execManager.GetJoystickManager().GetJoystickBySerial(serial);
+ IHidDevice joystick = _execManager.GetJoystickManager().GetJoystickBySerial(serial);
inputTypeComboBox.Items.AddRange(joystick.GetAvailableDevicesAsListItems().ToArray());
}
// Add all MidiBoards
diff --git a/UI/MainForm.cs b/UI/MainForm.cs
index d15f7dee2..9f87fd2fd 100644
--- a/UI/MainForm.cs
+++ b/UI/MainForm.cs
@@ -1494,7 +1494,7 @@ private void _checkForOrphanedJoysticks(bool showNotNecessaryMessage)
List serials = new List();
List NotConnectedJoysticks = new List();
- foreach (Joystick j in execManager.GetJoystickManager().GetJoysticks())
+ foreach (IHidDevice j in execManager.GetJoystickManager().GetJoysticks())
{
serials.Add($"{j.Name} {SerialNumber.SerialSeparator}{j.Serial}");
}
diff --git a/UI/Panels/Output/CustomDevicePanel.cs b/UI/Panels/Output/CustomDevicePanel.cs
index c77bedf44..5dfbd6400 100644
--- a/UI/Panels/Output/CustomDevicePanel.cs
+++ b/UI/Panels/Output/CustomDevicePanel.cs
@@ -18,7 +18,7 @@ public CustomDevicePanel()
InitializeComponent();
}
- public void SetCustomDeviceNames(List> pins)
+ public void SetCustomDeviceNames(List> pins)
{
customDeviceNamesComboBox.ValueMember = "Value";
customDeviceNamesComboBox.DisplayMember = "Label";
@@ -50,7 +50,7 @@ internal OutputConfigItem syncToConfig(OutputConfigItem config)
{
if (customDeviceNamesComboBox.SelectedValue != null)
{
- config.CustomDevice.CustomName = (customDeviceNamesComboBox.SelectedValue as MobiFlightCustomDevice).Name.ToString ();
+ config.CustomDevice.CustomName = (customDeviceNamesComboBox.SelectedValue as ICustomDevice).Name.ToString ();
}
if (MessageTypeComboBox.SelectedValue != null)
@@ -66,13 +66,12 @@ internal OutputConfigItem syncToConfig(OutputConfigItem config)
private void customDeviceNameComboBox_SelectedValueChanged(object sender, EventArgs e)
{
var messages = new List>();
- var customDevice = (customDeviceNamesComboBox.SelectedValue as MobiFlightCustomDevice);
+ var customDevice = (customDeviceNamesComboBox.SelectedValue as ICustomDevice);
if (customDevice == null) return;
- customDevice.CustomDevice
- .MessageTypes
+ customDevice.MessageTypes
.ForEach(
(m) => { messages.Add(new ListItem() { Value = m, Label = m.Label }); }
);
diff --git a/UI/Panels/OutputWizard/DisplayPanel.cs b/UI/Panels/OutputWizard/DisplayPanel.cs
index dac1bfd54..a5ac5fe35 100644
--- a/UI/Panels/OutputWizard/DisplayPanel.cs
+++ b/UI/Panels/OutputWizard/DisplayPanel.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
+using System.Linq;
using System.Windows.Forms;
namespace MobiFlight.UI.Panels.OutputWizard
@@ -293,7 +294,16 @@ private void displaySerialComboBox_SelectedIndexChanged(object sender, EventArgs
}
else if (serial.IndexOf(Joystick.SerialPrefix) == 0)
{
- deviceTypeOptions.Add(new ListItem() { Value = MobiFlightOutput.TYPE, Label = "LED / Output" });
+ var joystick = _execManager.GetJoystickManager().GetJoystickBySerial(serial);
+ if (joystick.GetAvailableOutputDevicesAsListItems().ToList().Find(x=> x.Value is JoystickOutputDevice) != null)
+ {
+ deviceTypeOptions.Add(new ListItem() { Value = MobiFlightOutput.TYPE, Label = "LED / Output" });
+ }
+
+ if (joystick.GetAvailableOutputDevicesAsListItems().ToList().Find(x => x.Value is JoystickStringOutputDevice) != null)
+ {
+ deviceTypeOptions.Add(new ListItem() { Value = MobiFlightCustomDevice.TYPE, Label = "Text" });
+ }
}
else if (serial.IndexOf(MidiBoard.SerialPrefix) == 0)
{
@@ -445,21 +455,34 @@ private void displayTypeComboBox_SelectedIndexChanged(object sender, EventArgs e
private bool InitializeJoystickDisplays(ComboBox cb, string serial)
{
- Joystick joystick = _execManager.GetJoystickManager().GetJoystickBySerial(serial);
+ IHidDevice joystick = _execManager.GetJoystickManager().GetJoystickBySerial(serial);
displayPinPanel.SetModule(null);
displayPinPanel.displayPinBrightnessPanel.Visible = false;
displayPinPanel.displayPinBrightnessPanel.Enabled = false;
List outputs = new List();
- foreach (var device in joystick.GetAvailableOutputDevicesAsListItems())
+ foreach (var device in joystick.GetAvailableOutputDevicesAsListItems()) {
outputs.Add(new ListItem() { Value = device.Label, Label = device.Label });
+ }
- displayPinPanel.WideStyle = true;
- displayPinPanel.EnablePWMSelect(false);
- displayPinPanel.SetPorts(new List());
- displayPinPanel.SetPins(outputs);
+ if (outputs.Count>0)
+ {
+ displayPinPanel.WideStyle = true;
+ displayPinPanel.EnablePWMSelect(false);
+ displayPinPanel.SetPorts(new List());
+ displayPinPanel.SetPins(outputs);
+ }
+
+ var customDevices = new List>();
+ foreach (var device in joystick.GetAvailableOutputDevicesAsListItems())
+ {
+ if (device.Value.Type != DeviceType.CustomDevice) continue;
+ customDevices.Add(new ListItem() { Value = device.Value as ICustomDevice, Label = device.Label });
+ }
+
+ customDevicePanel.SetCustomDeviceNames(customDevices);
return true;
}
@@ -560,7 +583,7 @@ private bool InitializeMobiFlightDisplays(ComboBox cb, string serial)
List stepper = new List();
List lcdDisplays = new List();
List shiftRegisters = new List();
- List> customDevices = new List>();
+ List> customDevices = new List>();
if (module!=null)
@@ -596,7 +619,7 @@ private bool InitializeMobiFlightDisplays(ComboBox cb, string serial)
break;
case DeviceType.CustomDevice:
- customDevices.Add(new ListItem()
+ customDevices.Add(new ListItem()
{
Value = device as MobiFlightCustomDevice,
Label = device.Name
diff --git a/examples/mobiflight-in-action-episode-1.mcc b/examples/mobiflight-in-action-episode-1.mcc
index b154f864c..784056614 100644
--- a/examples/mobiflight-in-action-episode-1.mcc
+++ b/examples/mobiflight-in-action-episode-1.mcc
@@ -4,76 +4,146 @@
true
Left Green
-
-
-
-
+
+
+
+
+
+
+
+
true
Right Green
-
-
-
-
+
+
+
+
+
+
+
+
true
Left Red
-
-
-
-
+
+
+
+
+
+
+
+
- true
+ false
Right Red
-
-
-
-
+
+
+
+
+
+
+
+
- true
+ false
Top Red
-
-
-
-
+
+
+
+
+
+
+
+
- true
+ false
Top Green
-
-
-
-
+
+
+
+
+
+
+
+
- true
+ false
Wing Flaps Indicator
-
-
-
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+ true
+ LED
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ ALT
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ VS
+
+
+
+
+
+
+
+
+
@@ -81,23 +151,23 @@
true
Gear Up Switch
-
+
+
true
Gear Down Switch
-
+
+