diff --git a/Joysticks/honeycomb_alpha.joystick.json b/Joysticks/honeycomb_alpha.joystick.json deleted file mode 100644 index 5af80b7d7..000000000 --- a/Joysticks/honeycomb_alpha.joystick.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "$schema": "./mfjoystick.schema.json", - "Inputs": [ - { - "Name": "Button 1", - "Label": "Button - Left Hand - White - Back" - }, - { - "Name": "Button 2", - "Label": "Button - Left Hand - White - Front" - }, - { - "Name": "Button 3", - "Label": "Button - Right Hand - White" - }, - { - "Name": "Button 4", - "Label": "Button - Right Hand - Red" - }, - { - "Name": "Button 5", - "Label": "Rocker - Left Hand - Left Down" - }, - { - "Name": "Button 6", - "Label": "Rocker - Left Hand - Left Up" - }, - { - "Name": "Button 7", - "Label": "Rocker - Left Hand - Right Down" - }, - { - "Name": "Button 8", - "Label": "Rocker - Left Hand - Right Up" - }, - { - "Name": "Button 9", - "Label": "Rocker - Right Hand - Upper Left" - }, - { - "Name": "Button 10", - "Label": "Rocker - Right Hand - Upper Right" - }, - { - "Name": "Button 11", - "Label": "Rocker - Right Hand - Lower Left" - }, - { - "Name": "Button 12", - "Label": "Rocker - Right Hand - Lower Right" - }, - { - "Name": "Button 13", - "Label": "Master ALT - Up" - }, - { - "Name": "Button 14", - "Label": "Master ALT - Down" - }, - { - "Name": "Button 15", - "Label": "Master BAT - Up" - }, - { - "Name": "Button 16", - "Label": "Master BAT - Down" - }, - { - "Name": "Button 17", - "Label": "Avionics BUS1 - Up" - }, - { - "Name": "Button 18", - "Label": "Avionics BUS1 - Down" - }, - { - "Name": "Button 19", - "Label": "Avionics BUS2 - Up" - }, - { - "Name": "Button 20", - "Label": "Avionics BUS2 - Down" - }, - { - "Name": "Button 21", - "Label": "Lights - BCN - Up" - }, - { - "Name": "Button 22", - "Label": "Lights - BCN - Down" - }, - { - "Name": "Button 23", - "Label": "Lights - LAND - Up" - }, - { - "Name": "Button 24", - "Label": "Lights - LAND - Down" - }, - { - "Name": "Button 25", - "Label": "Lights - TAXI - Up" - }, - { - "Name": "Button 26", - "Label": "Lights - TAXI - Down" - }, - { - "Name": "Button 27", - "Label": "Lights - NAV - Up" - }, - { - "Name": "Button 28", - "Label": "Lights - NAV - Down" - }, - { - "Name": "Button 29", - "Label": "Lights - STROBE - Up" - }, - { - "Name": "Button 30", - "Label": "Lights - STROBE - Down" - }, - { - "Name": "Button 31", - "Label": "Magnetos - Off" - }, - { - "Name": "Button 32", - "Label": "Magnetos - R" - }, - { - "Name": "Button 33", - "Label": "Magnetos - L" - }, - { - "Name": "Button 34", - "Label": "Magnetos - BOTH" - }, - { - "Name": "Button 35", - "Label": "Magnetos - START" - }, - { - "Name": "X Axis", - "Label": "Axis - Roll" - }, - { - "Name": "Y Axis", - "Label": "Axis - Pitch" - } - ] -} diff --git a/Joysticks/honeycomb_bravo.joystick.json b/Joysticks/honeycomb_bravo.joystick.json deleted file mode 100644 index 8fa1f8bdc..000000000 --- a/Joysticks/honeycomb_bravo.joystick.json +++ /dev/null @@ -1,394 +0,0 @@ -{ - "$schema": "./mfjoystick.schema.json", - "InstanceName": "Bravo Throttle Quadrant", - "VendorId": 10571, - "ProductId": 6401, - "Inputs": [ - { - "Name": "Button 17", - "Label": "Mode - IAS" - }, - { - "Name": "Button 18", - "Label": "Mode - CRS" - }, - { - "Name": "Button 19", - "Label": "Mode - HDG" - }, - { - "Name": "Button 20", - "Label": "Mode - VS" - }, - { - "Name": "Button 21", - "Label": "Mode - ALT" - }, - { - "Name": "Button 1", - "Label": "AP - HDG" - }, - { - "Name": "Button 2", - "Label": "AP - NAV" - }, - { - "Name": "Button 3", - "Label": "AP - APR" - }, - { - "Name": "Button 4", - "Label": "AP - REV" - }, - { - "Name": "Button 5", - "Label": "AP - ALT" - }, - { - "Name": "Button 6", - "Label": "AP - VS" - }, - { - "Name": "Button 7", - "Label": "AP - IAS" - }, - { - "Name": "Button 8", - "Label": "AP - Autopilot" - }, - { - "Name": "Button 13", - "Label": "Encoder - Right" - }, - { - "Name": "Button 14", - "Label": "Encoder - Left" - }, - { - "Name": "Button 31", - "Label": "Gear - Up" - }, - { - "Name": "Button 32", - "Label": "Gear - Down" - }, - { - "Name": "Button 16", - "Label": "Flaps - Up" - }, - { - "Name": "Button 15", - "Label": "Flaps - Down" - }, - { - "Name": "Button 22", - "Label": "Trim - Nose Down" - }, - { - "Name": "Button 23", - "Label": "Trim - Nose Up" - }, - { - "Name": "Button 24", - "Label": "Lever 1 - Detent" - }, - { - "Name": "Button 25", - "Label": "Lever 2 - Detent" - }, - { - "Name": "Button 26", - "Label": "Lever 3 - Detent" - }, - { - "Name": "Button 27", - "Label": "Lever 4 - Detent" - }, - { - "Name": "Button 28", - "Label": "Lever 5 - Detent" - }, - { - "Name": "Button 33", - "Label": "Lever 6 - Detent" - }, - { - "Name": "Button 29", - "Label": "Lever 1 - Button" - }, - { - "Name": "Button 9", - "Label": "Lever 2 - Button" - }, - { - "Name": "Button 10", - "Label": "Lever 3 - Button" - }, - { - "Name": "Button 11", - "Label": "Lever 4 - Button" - }, - { - "Name": "Button 12", - "Label": "Lever 5 - Button" - }, - { - "Name": "Button 30", - "Label": "Lever 3 - Reverser" - }, - { - "Name": "Button 48", - "Label": "Lever 4 - Reverser" - }, - { - "Name": "Button 34", - "Label": "Switch 1 - Up" - }, - { - "Name": "Button 35", - "Label": "Switch 1 - Down" - }, - { - "Name": "Button 36", - "Label": "Switch 2 - Up" - }, - { - "Name": "Button 37", - "Label": "Switch 2 - Down" - }, - { - "Name": "Button 38", - "Label": "Switch 3 - Up" - }, - { - "Name": "Button 39", - "Label": "Switch 3 - Down" - }, - { - "Name": "Button 40", - "Label": "Switch 4 - Up" - }, - { - "Name": "Button 41", - "Label": "Switch 4 - Down" - }, - { - "Name": "Button 42", - "Label": "Switch 5 - Up" - }, - { - "Name": "Button 43", - "Label": "Switch 5 - Down" - }, - { - "Name": "Button 44", - "Label": "Switch 6 - Up" - }, - { - "Name": "Button 45", - "Label": "Switch 6 - Down" - }, - { - "Name": "Button 46", - "Label": "Switch 7 - Up" - }, - { - "Name": "Button 47", - "Label": "Switch 7 - Down" - }, - { - "Name": "Y Axis", - "Label": "Axis - Lever 1" - }, - { - "Name": "X Axis", - "Label": "Axis - Lever 2" - }, - { - "Name": "Z Rotation", - "Label": "Axis - Lever 3" - }, - { - "Name": "Y Rotation", - "Label": "Axis - Lever 4" - }, - { - "Name": "X Rotation", - "Label": "Axis - Lever 5" - }, - { - "Name": "Z Axis", - "Label": "Axis - Lever 6" - } - ], - "Outputs": [ - { - "Label": "AP Mode - HDG", - "Name": "AP.hdg", - "Byte": 1, - "Bit": 0 - }, - { - "Label": "AP Mode - NAV", - "Name": "AP.nav", - "Byte": 1, - "Bit": 1 - }, - { - "Label": "AP Mode - APR", - "Name": "AP.apr", - "Byte": 1, - "Bit": 2 - }, - { - "Label": "AP Mode - REV", - "Name": "AP.rev", - "Byte": 1, - "Bit": 3 - }, - { - "Label": "AP Mode - ALT", - "Name": "AP.alt", - "Byte": 1, - "Bit": 4 - }, - { - "Label": "AP Mode - VS", - "Name": "AP.vs", - "Byte": 1, - "Bit": 5 - }, - { - "Label": "AP Mode - IAS", - "Name": "AP.ias", - "Byte": 1, - "Bit": 6 - }, - { - "Label": "AP Mode - On/Off", - "Name": "AP.autopilot", - "Byte": 1, - "Bit": 7 - }, - { - "Label": "Gear - Left Green", - "Name": "Gear.LeftGreen", - "Byte": 2, - "Bit": 0 - }, - { - "Label": "Gear - Left Red", - "Name": "Gear.LeftRed", - "Byte": 2, - "Bit": 1 - }, - { - "Label": "Gear - Center Green", - "Name": "Gear.CenterGreen", - "Byte": 2, - "Bit": 2 - }, - { - "Label": "Gear - Center Red", - "Name": "Gear.CenterRed", - "Byte": 2, - "Bit": 3 - }, - { - "Label": "Gear - Right Green", - "Name": "Gear.RightGreen", - "Byte": 2, - "Bit": 4 - }, - { - "Label": "Gear - Right Red", - "Name": "Gear.RightRed", - "Byte": 2, - "Bit": 5 - }, - { - "Label": "Lights - Master Warning", - "Name": "Light.MasterWarn", - "Byte": 2, - "Bit": 6 - }, - { - "Label": "Lights - Engine Fire", - "Name": "Light.EngineFire", - "Byte": 2, - "Bit": 7 - }, - { - "Label": "Lights - Low Oil Pressure", - "Name": "Light.LowOil", - "Byte": 3, - "Bit": 0 - }, - { - "Label": "Lights - Low Fuel Pressure", - "Name": "Light.LowFuel", - "Byte": 3, - "Bit": 1 - }, - { - "Label": "Lights - Anti Ice", - "Name": "Light.Antiice", - "Byte": 3, - "Bit": 2 - }, - { - "Label": "Lights - Starter Engaged", - "Name": "Light.Starter", - "Byte": 3, - "Bit": 3 - }, - { - "Label": "Lights - APU", - "Name": "Light.APU", - "Byte": 3, - "Bit": 4 - }, - { - "Label": "Lights - Master Caution", - "Name": "Light.MasterCaution", - "Byte": 3, - "Bit": 5 - }, - { - "Label": "Lights - Vacuum", - "Name": "Light.Vacuum", - "Byte": 3, - "Bit": 6 - }, - { - "Label": "Lights - Low Hyd Pressure", - "Name": "Light.LowHydPressURE", - "Byte": 3, - "Bit": 7 - }, - { - "Label": "Lights - Aux Fuel Pump", - "Name": "Lights.AuxFuelPump", - "Byte": 4, - "Bit": 0 - }, - { - "Label": "Lights - Parking Brake", - "Name": "Lights.ParkingBrake", - "Byte": 4, - "Bit": 1 - }, - { - "Label": "Lights - Low Volts", - "Name": "Lights.LowVolts", - "Byte": 4, - "Bit": 2 - }, - { - "Label": "Lights - Door", - "Name": "Lights.door", - "Byte": 4, - "Bit": 3 - } - ] -} diff --git a/Joysticks/mfjoystick.schema.json b/Joysticks/mfjoystick.schema.json deleted file mode 100644 index 8be96fe97..000000000 --- a/Joysticks/mfjoystick.schema.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "definitions": {}, - "$schema": "https://json-schema.org/draft/2019-09/schema#", - "$id": "https://mobiflight.com/hid.schema.json", - "title": "Root", - "type": "object", - "required": ["InstanceName"], - "dependentRequired": { - "Outputs": ["VendorId", "ProductId"] - }, - "properties": { - "InstanceName": { - "$id": "#root/InstanceName", - "title": "InstanceName", - "type": "string", - "description": "Instance name for the device. Required. This is used to match the definition with a connected device." - }, - "Inputs": { - "$id": "#root/Inputs", - "title": "Inputs", - "description": "List of inputs supported by the device. Optional.", - "type": "array", - "default": [], - "items": { - "$id": "#root/Inputs/items", - "title": "Items", - "type": "object", - "required": ["Name", "Label"], - "properties": { - "Name": { - "$id": "#root/Inputs/items/Name", - "title": "Name", - "description": "Device's name for the input. Required.", - "type": "string" - }, - "Label": { - "$id": "#root/Inputs/items/Label", - "title": "Label", - "description": "Label for the input. Required.", - "type": "string" - } - } - } - }, - "Outputs": { - "$id": "#root/Outputs", - "title": "Outputs", - "description": "List of outputs supported by the device. Optional.", - "type": "array", - "default": [], - "items": { - "$id": "#root/Outputs/items", - "title": "Items", - "type": "object", - "required": ["Name", "Label", "Byte", "Bit"], - "properties": { - "Name": { - "$id": "#root/Inputs/items/Name", - "title": "Name", - "description": "Device's name for the input. Required.", - "type": "string" - }, - "Label": { - "$id": "#root/Inputs/items/Label", - "title": "Label", - "description": "Label for the input. Required.", - "type": "string" - }, - "Byte": { - "$id": "#root/Inputs/items/Byte", - "title": "Byte", - "description": "Byte location of the output. Required.", - "type": "number" - }, - "Bit": { - "$id": "#root/Inputs/items/Bit", - "title": "Bit", - "description": "Bit location within the byte of the output. Required.", - "type": "number" - } - } - } - }, - "ProductId": { - "$id": "#Root/VendorId", - "title": "VendorId", - "type": "number", - "description": "The device's USB VendorId. Required if Outputs are provided." - }, - "VendorId": { - "$id": "#Root/ProductId", - "title": "ProductId", - "type": "number", - "description": "The device's USB ProductId. Required if Outputs are provided." - } - } -} diff --git a/Joysticks/saitek_aviator_stick.joystick.json b/Joysticks/saitek_aviator_stick.joystick.json deleted file mode 100644 index d06b30134..000000000 --- a/Joysticks/saitek_aviator_stick.joystick.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "./mfjoystick.schema.json", - "InstanceName": "Saitek Aviator Stick", - "VendorId": 1699, - "ProductId": 1121, - "Inputs": [ - { - "Name": "Button 5", - "Label": "Button - T1" - }, - { - "Name": "Button 6", - "Label": "Button - T2" - }, - { - "Name": "Button 7", - "Label": "Button - T3" - }, - { - "Name": "Button 8", - "Label": "Button - T4" - }, - { - "Name": "Button 9", - "Label": "Button - T5" - }, - { - "Name": "Button 10", - "Label": "Button - T6" - }, - { - "Name": "Button 11", - "Label": "Button - T7" - }, - { - "Name": "Button 12", - "Label": "Button - T8" - }, - { - "Name": "Button 13", - "Label": "Mode A" - }, - { - "Name": "Button 14", - "Label": "Mode B" - } - ], - "Outputs": [] -} diff --git a/MobiFlight/Joysticks/Joystick.cs b/MobiFlight/Joystick.cs similarity index 86% rename from MobiFlight/Joysticks/Joystick.cs rename to MobiFlight/Joystick.cs index 434a24569..47b1d7af8 100644 --- a/MobiFlight/Joysticks/Joystick.cs +++ b/MobiFlight/Joystick.cs @@ -1,11 +1,7 @@ -using HidSharp; -using SharpDX.DirectInput; +using SharpDX.DirectInput; using System; using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Text.RegularExpressions; -using System.Xml.Linq; namespace MobiFlight { @@ -54,8 +50,7 @@ public class Joystick public event ButtonEventHandler OnButtonPressed; public event ButtonEventHandler OnAxisChanged; public event EventHandler OnDisconnected; - private readonly SharpDX.DirectInput.Joystick joystick; - private readonly JoystickDefinition definition; + private SharpDX.DirectInput.Joystick joystick; JoystickState state = null; protected List Buttons = new List(); protected List Axes = new List(); @@ -63,9 +58,6 @@ public class Joystick protected List Lights = new List(); protected bool RequiresOutputUpdate = false; public static string[] AxisNames = { "X", "Y", "Z", "RotationX", "RotationY", "RotationZ", "Slider1", "Slider2"}; - private HidStream Stream; - private HidDevice Device; - public static bool IsJoystickSerial(string serial) { @@ -92,10 +84,9 @@ public Capabilities Capabilities { } } - public Joystick(SharpDX.DirectInput.Joystick joystick, JoystickDefinition definition) + public Joystick(SharpDX.DirectInput.Joystick joystick) { this.joystick = joystick; - this.definition = definition; } protected virtual void EnumerateDevices() @@ -105,6 +96,7 @@ protected virtual void EnumerateDevices() this.joystick.GetObjectInfoById(device.ObjectId); + int offset = device.Offset; int usage = device.Usage; ObjectAspect aspect = device.Aspect; @@ -167,18 +159,11 @@ protected string GetFriendlyButtonName(string name, int v) return MapDeviceNameToLabel(Regex.Replace(name, @"\d+", v.ToString()).ToString()); } - public string MapDeviceNameToLabel(string deviceName) + public virtual string MapDeviceNameToLabel(string deviceName) { - // First try and look for a custom label. - var input = definition?.FindInputByName(deviceName); - if (input != null) - { - return input.Label; - } + var result = deviceName; - string result = string.Empty; - - if (deviceName.StartsWith(ButtonPrefix)) + if(deviceName.StartsWith(ButtonPrefix)) { result = Buttons.Find(b => b.Name == deviceName)?.Label ?? string.Empty; } else if (deviceName.StartsWith(AxisPrefix)) @@ -204,11 +189,9 @@ public void Connect(IntPtr handle) joystick.Acquire(); } - private void EnumerateOutputDevices() + virtual protected void EnumerateOutputDevices() { Lights.Clear(); - - definition?.Outputs?.ForEach(output => Lights.Add(new JoystickOutputDevice() { Label = output.Label, Name = output.Name, Byte = output.Byte, Bit = output.Bit })); return; } @@ -233,43 +216,14 @@ public List GetAvailableDevices() protected virtual List GetButtonsSorted() { - var buttons = Buttons.ToArray().ToList(); - buttons.Sort(SortByPositionInDefintion); return Buttons; } protected virtual 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; - } - - - private void Connect() - { - if (Device == null) - { - Device = DeviceList.Local.GetHidDeviceOrNull(vendorID: definition.VendorId, productID: definition.ProductId); - if (Device == null) return; - } - - Stream = Device.Open(); - } - public List GetAvailableOutputDevices() { List result = new List(); @@ -455,19 +409,6 @@ public void SetOutputDeviceState(string name, string value) 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; } diff --git a/MobiFlight/Joysticks/JoystickManager.cs b/MobiFlight/JoystickManager.cs similarity index 70% rename from MobiFlight/Joysticks/JoystickManager.cs rename to MobiFlight/JoystickManager.cs index 439c1ef37..a4111734a 100644 --- a/MobiFlight/Joysticks/JoystickManager.cs +++ b/MobiFlight/JoystickManager.cs @@ -1,8 +1,6 @@ -using Newtonsoft.Json; -using SharpDX.DirectInput; +using SharpDX.DirectInput; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; @@ -11,56 +9,21 @@ namespace MobiFlight { public class JoystickManager { - private readonly List Definitions = new List(); public event EventHandler Connected; public event ButtonEventHandler OnButtonPressed; - readonly Timer PollTimer = new Timer(); - readonly List joysticks = new List(); + Timer PollTimer = new Timer(); + List joysticks = new List(); public JoystickManager () { PollTimer.Interval = 50; PollTimer.Tick += PollTimer_Tick; - LoadDefinitions(); - } - - /// - /// Finds a JoystickDefinition by the device's instance name. - /// - /// The instance name of the device. - /// The first definition matching the instanceMae, or null if none found. - private JoystickDefinition GetDefinitionByInstanceName(String instanceName) - { - return Definitions.Find(definition => definition.InstanceName == instanceName); - } - - /// - /// Loads all joystick definitions from disk. - /// - private void LoadDefinitions() - { - foreach (var definitionFile in Directory.GetFiles("Joysticks", "*.joystick.json")) - { - try - { - var joystick = JsonConvert.DeserializeObject(File.ReadAllText(definitionFile)); - joystick.Migrate(); - Definitions.Add(joystick); - Log.Instance.log($"Loaded joystick definition for {joystick.InstanceName}", LogSeverity.Info); - } - catch (Exception ex) - { - Log.Instance.log($"Unable to load {definitionFile}: {ex.Message}", LogSeverity.Error); - } - } - } public bool JoysticksConnected() { return joysticks.Count > 0; } - private void PollTimer_Tick(object sender, EventArgs e) { try @@ -71,7 +34,7 @@ private void PollTimer_Tick(object sender, EventArgs e) js?.Update(); } } - } catch (InvalidOperationException) + } catch (InvalidOperationException ex) { // this exception is thrown when a joystick is disconnected and removed from the list of joysticks } @@ -114,8 +77,18 @@ public void Connect(IntPtr Handle) if (!IsSupportedDeviceType(d)) continue; MobiFlight.Joystick js; - - js = new Joystick(new SharpDX.DirectInput.Joystick(di, d.InstanceGuid), GetDefinitionByInstanceName(d.InstanceName)); + if (d.InstanceName == "Bravo Throttle Quadrant") + { + js = new Joysticks.HoneycombBravo(new SharpDX.DirectInput.Joystick(di, d.InstanceGuid)); + } else if (d.InstanceName == "Saitek Aviator Stick") + { + js = new Joysticks.SaitekAviatorStick(new SharpDX.DirectInput.Joystick(di, d.InstanceGuid)); + } + else + { + js = new Joystick(new SharpDX.DirectInput.Joystick(di, d.InstanceGuid)); + } + if (!HasAxisOrButtons(js)) continue; @@ -177,11 +150,10 @@ internal Joystick GetJoystickBySerial(string serial) public Dictionary GetStatistics() { - Dictionary result = new Dictionary - { - ["Joysticks.Count"] = joysticks.Count() - }; + Dictionary result = new Dictionary(); + result["Joysticks.Count"] = joysticks.Count(); + foreach (Joystick joystick in joysticks) { string key = "Joysticks.Model." + joystick.Name; diff --git a/MobiFlight/Joysticks/HoneycombBravo.cs b/MobiFlight/Joysticks/HoneycombBravo.cs new file mode 100644 index 000000000..cead86fd5 --- /dev/null +++ b/MobiFlight/Joysticks/HoneycombBravo.cs @@ -0,0 +1,143 @@ +using HidSharp; +using System.Collections.Generic; + +namespace MobiFlight.Joysticks +{ + internal class HoneycombBravo : LabeledJoystick + { + int VendorId = 0x294B; + int ProductId = 0x1901; + HidStream Stream { get; set; } + HidDevice Device { get; set; } + + public HoneycombBravo(SharpDX.DirectInput.Joystick joystick) : base(joystick) { + Labels = new Dictionary() + { + // Mode + { "Button 17", "Mode - IAS" }, + { "Button 18", "Mode - CRS" }, + { "Button 19", "Mode - HDG" }, + { "Button 20", "Mode - VS" }, + { "Button 21", "Mode - ALT" }, + // AP Buttons + { "Button 1", "AP - HDG" }, + { "Button 2", "AP - NAV" }, + { "Button 3", "AP - APR" }, + { "Button 4", "AP - REV" }, + { "Button 5", "AP - ALT" }, + { "Button 6", "AP - VS" }, + { "Button 7", "AP - IAS" }, + { "Button 8", "AP - Autopilot" }, + // Generic Encoder + { "Button 13", "Encoder - Right" }, + { "Button 14", "Encoder - Left" }, + // Gear + { "Button 31", "Gear - Up" }, + { "Button 32", "Gear - Down" }, + // Flaps + { "Button 16", "Flaps - Up" }, + { "Button 15", "Flaps - Down" }, + // Trim + { "Button 22", "Trim - Nose Down" }, + { "Button 23", "Trim - Nose Up" }, + // Levers + { "Button 24", "Lever 1 - Detent" }, + { "Button 25", "Lever 2 - Detent" }, + { "Button 26", "Lever 3 - Detent" }, + { "Button 27", "Lever 4 - Detent" }, + { "Button 28", "Lever 5 - Detent" }, + { "Button 33", "Lever 6 - Detent" }, + // + { "Button 29", "Lever 1 - Button" }, + { "Button 9", "Lever 2 - Button" }, + { "Button 10", "Lever 3 - Button" }, + { "Button 11", "Lever 4 - Button" }, + { "Button 12", "Lever 5 - Button" }, + // + { "Button 30", "Lever 3 - Reverser" }, + { "Button 48", "Lever 4 - Reverser" }, + + // + { "Button 34", "Switch 1 - Up" }, + { "Button 35", "Switch 1 - Down" }, + { "Button 36", "Switch 2 - Up" }, + { "Button 37", "Switch 2 - Down" }, + { "Button 38", "Switch 3 - Up" }, + { "Button 39", "Switch 3 - Down" }, + { "Button 40", "Switch 4 - Up" }, + { "Button 41", "Switch 4 - Down" }, + { "Button 42", "Switch 5 - Up" }, + { "Button 43", "Switch 5 - Down" }, + { "Button 44", "Switch 6 - Up" }, + { "Button 45", "Switch 6 - Down" }, + { "Button 46", "Switch 7 - Up" }, + { "Button 47", "Switch 7 - Down" }, + // Axis + { "Y Axis", "Axis - Lever 1" }, + { "X Axis", "Axis - Lever 2" }, + { "Z Rotation", "Axis - Lever 3" }, + { "Y Rotation", "Axis - Lever 4" }, + { "X Rotation", "Axis - Lever 5" }, + { "Z Axis", "Axis - Lever 6" }, + }; + } + + public void Connect() + { + if (Device == null) + { + Device = DeviceList.Local.GetHidDeviceOrNull(vendorID: VendorId, productID: ProductId); + if (Device == null) return; + } + + Stream = Device.Open(); + } + + protected override void SendData(byte[] data) + { + if (!RequiresOutputUpdate) return; + if (Stream == null) + { + Connect(); + }; + Stream.SetFeature(data); + base.SendData(data); + } + + protected override void EnumerateOutputDevices() + { + base.EnumerateOutputDevices(); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - HDG", Name = "AP.hdg", Byte = 1, Bit = 0 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - NAV", Name = "AP.nav", Byte = 1, Bit = 1 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - APR", Name = "AP.apr", Byte = 1, Bit = 2 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - REV", Name = "AP.rev", Byte = 1, Bit = 3 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - ALT", Name = "AP.alt", Byte = 1, Bit = 4 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - VS", Name = "AP.vs", Byte = 1, Bit = 5 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - IAS", Name = "AP.ias", Byte = 1, Bit = 6 }); + Lights.Add(new JoystickOutputDevice() { Label = "AP Mode - On/Off", Name = "AP.autopilot", Byte = 1, Bit = 7 }); + // -- Byte 2 + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Left Green", Name = "Gear.LeftGreen", Byte = 2, Bit = 0 }); + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Left Red", Name = "Gear.LeftRed", Byte = 2, Bit = 1 }); + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Center Green", Name = "Gear.CenterGreen", Byte = 2, Bit = 2 }); + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Center Red", Name = "Gear.CenterRed", Byte = 2, Bit = 3 }); + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Right Green", Name = "Gear.RightGreen", Byte = 2, Bit = 4 }); + Lights.Add(new JoystickOutputDevice() { Label = "Gear - Right Red", Name = "Gear.RightRed", Byte = 2, Bit = 5 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Master Warning", Name = "Light.MasterWarn", Byte = 2, Bit = 6 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Engine Fire", Name = "Light.EngineFire", Byte = 2, Bit = 7 }); + // -- Byte 3 + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Low Oil Pressure", Name = "Light.LowOil", Byte = 3, Bit = 0 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Low Fuel Pressure", Name = "Light.LowFuel", Byte = 3, Bit = 1 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Anti Ice", Name = "Light.Antiice", Byte = 3, Bit = 2 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Starter Engaged", Name = "Light.Starter", Byte = 3, Bit = 3 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - APU", Name = "Light.APU", Byte = 3, Bit = 4 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Master Caution", Name = "Light.MasterCaution", Byte = 3, Bit = 5 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Vacuum", Name = "Light.Vacuum", Byte = 3, Bit = 6 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Low Hyd Pressure", Name = "Light.LowHydPressURE", Byte = 3, Bit = 7 }); + // -- Byte 4 + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Aux Fuel Pump", Name = "Lights.AuxFuelPump", Byte = 4, Bit = 0 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Parking Brake", Name = "Lights.ParkingBrake", Byte = 4, Bit = 1 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Low Volts", Name = "Lights.LowVolts", Byte = 4, Bit = 2 }); + Lights.Add(new JoystickOutputDevice() { Label = "Lights - Door", Name = "Lights.door", Byte = 4, Bit = 3 }); + } + } +} diff --git a/MobiFlight/Joysticks/JoystickDefinition.cs b/MobiFlight/Joysticks/JoystickDefinition.cs deleted file mode 100644 index e325189f2..000000000 --- a/MobiFlight/Joysticks/JoystickDefinition.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MobiFlight -{ - public class JoystickDefinition - { - /// - /// List of inputs supported by the device. - /// - public List Inputs; - /// - /// Instance name for the device. This is used to match the definition with a connected device. - /// - public string InstanceName; - /// - /// List of options supported by the device. - /// - public List Outputs; - /// - /// The device's USB ProductId. Required if Outputs are provided. - /// - public int ProductId; - /// - /// The device's USB VendorId. Required if Outputs are provided. - /// - public int VendorId; - - public JoystickInput FindInputByName(string name) - { - return Inputs.Find(input => input.Name == name); - } - - public void Migrate() { } - } -} diff --git a/MobiFlight/Joysticks/JoystickInput.cs b/MobiFlight/Joysticks/JoystickInput.cs deleted file mode 100644 index a9a006cc0..000000000 --- a/MobiFlight/Joysticks/JoystickInput.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MobiFlight -{ - public class JoystickInput - { - /// - /// Display value for the input. - /// - public string Label; - /// - /// Device's name for the input. - /// - public string Name; - } -} diff --git a/MobiFlight/Joysticks/JoystickOutput.cs b/MobiFlight/Joysticks/JoystickOutput.cs deleted file mode 100644 index 41c8e1933..000000000 --- a/MobiFlight/Joysticks/JoystickOutput.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MobiFlight -{ - public class JoystickOutput - { - /// - /// Display name for the output. - /// - public string Label; - /// - /// Device's name for the input. - /// - public string Name; - /// - /// Byte location of the output. - /// - public byte Byte; - /// - /// Bit location within the byte of the output. - /// - public byte Bit; - } -} diff --git a/MobiFlight/Joysticks/LabeledJoystick.cs b/MobiFlight/Joysticks/LabeledJoystick.cs new file mode 100644 index 000000000..d63ee0f84 --- /dev/null +++ b/MobiFlight/Joysticks/LabeledJoystick.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MobiFlight.Joysticks +{ + public class LabeledJoystick : Joystick + { + protected Dictionary Labels = new Dictionary(); + + public LabeledJoystick(SharpDX.DirectInput.Joystick joystick) : base(joystick) { } + + protected override List GetButtonsSorted() + { + var buttons = Buttons.ToArray().ToList(); + buttons.Sort(SortByPositionInDictionary); + + return buttons; + } + + public override string MapDeviceNameToLabel(string name) + { + var result = name; + + if (Labels.ContainsKey(name)) + result = Labels[name]; + else + result = base.MapDeviceNameToLabel(name); + + return result; + } + + protected override List GetAxisSorted() + { + var axes = Axes.ToArray().ToList(); + Axes.Sort(SortByPositionInDictionary); + + return axes; + } + + public int GetIndexForKey(string key) + { + int result = Array.IndexOf(Labels.Keys.ToArray(), key); + return result; + } + + int SortByPositionInDictionary(JoystickDevice b1, JoystickDevice b2) + { + if (GetIndexForKey(b1.Name) == GetIndexForKey(b2.Name)) return 0; + if (GetIndexForKey(b1.Name) > GetIndexForKey(b2.Name)) return 1; + return -1; + } + } +} diff --git a/MobiFlight/Joysticks/SaitekAviatorStick.cs b/MobiFlight/Joysticks/SaitekAviatorStick.cs new file mode 100644 index 000000000..2c7466758 --- /dev/null +++ b/MobiFlight/Joysticks/SaitekAviatorStick.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +namespace MobiFlight.Joysticks +{ + internal class SaitekAviatorStick : LabeledJoystick + { + int VendorId = 0x06A3; + int ProductId = 0x0461; + + public SaitekAviatorStick(SharpDX.DirectInput.Joystick joystick) : base(joystick) { + Labels = new Dictionary() + { + // Button 1-4 are not labeled + // --- + // Front switches + { "Button 5", "Button - T1" }, + { "Button 6", "Button - T2" }, + { "Button 7", "Button - T3" }, + { "Button 8", "Button - T4" }, + { "Button 9", "Button - T5" }, + { "Button 10", "Button - T6" }, + { "Button 11", "Button - T7" }, + { "Button 12", "Button - T8" }, + { "Button 13", "Mode A" }, + { "Button 14", "Mode B" } + // Throttles & Axis are not labeled + }; + } + } +} diff --git a/MobiFlightConnector.csproj b/MobiFlightConnector.csproj index f67e9ee26..cf4448f1d 100644 --- a/MobiFlightConnector.csproj +++ b/MobiFlightConnector.csproj @@ -259,12 +259,12 @@ - - + + - - - + + + @@ -882,9 +882,7 @@ PreserveNewest - - PreserveNewest - + PreserveNewest @@ -935,18 +933,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - Always