diff --git a/DirectInputExplorer~/DirectInputExplorer/Form1.Designer.cs b/DirectInputExplorer~/DirectInputExplorer/Form1.Designer.cs index 23c9147..5501835 100644 --- a/DirectInputExplorer~/DirectInputExplorer/Form1.Designer.cs +++ b/DirectInputExplorer~/DirectInputExplorer/Form1.Designer.cs @@ -21,868 +21,1834 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - #region Windows Form Designer generated code + #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.ComboBoxDevices = new System.Windows.Forms.ComboBox(); - this.ButtonEnumerateDevices = new System.Windows.Forms.Button(); - this.LabelDeviceInfo = new System.Windows.Forms.Label(); - this.TimerPoll = new System.Windows.Forms.Timer(this.components); - this.ButtonAttach = new System.Windows.Forms.Button(); - this.ButtonRemove = new System.Windows.Forms.Button(); - this.TabController = new System.Windows.Forms.TabControl(); - this.TabDeviceInfo = new System.Windows.Forms.TabPage(); - this.LabelFFBCapabilities = new System.Windows.Forms.Label(); - this.LabelCapabilities = new System.Windows.Forms.Label(); - this.TabInput = new System.Windows.Forms.TabPage(); - this.LabelInput = new System.Windows.Forms.Label(); - this.TabFFB = new System.Windows.Forms.TabPage(); - this.GBSpring = new System.Windows.Forms.GroupBox(); - this.CBSpring = new System.Windows.Forms.CheckBox(); - this.UDSpringDeadband = new System.Windows.Forms.NumericUpDown(); - this.UDSpringSaturation = new System.Windows.Forms.NumericUpDown(); - this.UDSpringCoefficient = new System.Windows.Forms.NumericUpDown(); - this.UDSpringOffset = new System.Windows.Forms.NumericUpDown(); - this.SliderSpringDeadband = new System.Windows.Forms.TrackBar(); - this.LabelSpringDeadband = new System.Windows.Forms.Label(); - this.SliderSpringSaturation = new System.Windows.Forms.TrackBar(); - this.LabelSpringSaturation = new System.Windows.Forms.Label(); - this.SliderSpringCoefficient = new System.Windows.Forms.TrackBar(); - this.LabelSpringCoefficient = new System.Windows.Forms.Label(); - this.SliderSpringOffset = new System.Windows.Forms.TrackBar(); - this.LabelSpringOffset = new System.Windows.Forms.Label(); - this.GBInertia = new System.Windows.Forms.GroupBox(); - this.CBInertia = new System.Windows.Forms.CheckBox(); - this.UDInertiaMagnitude = new System.Windows.Forms.NumericUpDown(); - this.LabelInertiaMagnitude = new System.Windows.Forms.Label(); - this.SliderInertiaMagnitude = new System.Windows.Forms.TrackBar(); - this.GBFriction = new System.Windows.Forms.GroupBox(); - this.UDFrictionMagnitude = new System.Windows.Forms.NumericUpDown(); - this.CBFriction = new System.Windows.Forms.CheckBox(); - this.LabelFrictionMagnitude = new System.Windows.Forms.Label(); - this.SliderFrictionMagnitude = new System.Windows.Forms.TrackBar(); - this.GBDamper = new System.Windows.Forms.GroupBox(); - this.UDDamperMagnitude = new System.Windows.Forms.NumericUpDown(); - this.LabelDamperMagnitude = new System.Windows.Forms.Label(); - this.CBDamper = new System.Windows.Forms.CheckBox(); - this.SliderDamperMagnitude = new System.Windows.Forms.TrackBar(); - this.GBConstantForce = new System.Windows.Forms.GroupBox(); - this.CBConstantForce = new System.Windows.Forms.CheckBox(); - this.UDConstantForceMagnitude = new System.Windows.Forms.NumericUpDown(); - this.LabelConstantForceMagnitude = new System.Windows.Forms.Label(); - this.SliderConstantForceMagnitude = new System.Windows.Forms.TrackBar(); - this.TabMisc = new System.Windows.Forms.TabPage(); - this.LabelDebug = new System.Windows.Forms.Label(); - this.ButtonDebug = new System.Windows.Forms.Button(); - this.TabController.SuspendLayout(); - this.TabDeviceInfo.SuspendLayout(); - this.TabInput.SuspendLayout(); - this.TabFFB.SuspendLayout(); - this.GBSpring.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringDeadband)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringSaturation)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringCoefficient)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringOffset)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringDeadband)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringSaturation)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringCoefficient)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringOffset)).BeginInit(); - this.GBInertia.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDInertiaMagnitude)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderInertiaMagnitude)).BeginInit(); - this.GBFriction.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDFrictionMagnitude)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderFrictionMagnitude)).BeginInit(); - this.GBDamper.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDDamperMagnitude)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderDamperMagnitude)).BeginInit(); - this.GBConstantForce.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDConstantForceMagnitude)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderConstantForceMagnitude)).BeginInit(); - this.TabMisc.SuspendLayout(); - this.SuspendLayout(); - // - // ComboBoxDevices - // - this.ComboBoxDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.ComboBoxDevices.FormattingEnabled = true; - this.ComboBoxDevices.Location = new System.Drawing.Point(12, 12); - this.ComboBoxDevices.Name = "ComboBoxDevices"; - this.ComboBoxDevices.Size = new System.Drawing.Size(976, 23); - this.ComboBoxDevices.TabIndex = 1; - this.ComboBoxDevices.SelectedIndexChanged += new System.EventHandler(this.ComboBoxDevices_SelectedIndexChanged); - // - // ButtonEnumerateDevices - // - this.ButtonEnumerateDevices.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.ButtonEnumerateDevices.Location = new System.Drawing.Point(994, 12); - this.ButtonEnumerateDevices.Name = "ButtonEnumerateDevices"; - this.ButtonEnumerateDevices.Size = new System.Drawing.Size(40, 23); - this.ButtonEnumerateDevices.TabIndex = 2; - this.ButtonEnumerateDevices.Text = "🔄"; - this.ButtonEnumerateDevices.UseVisualStyleBackColor = true; - this.ButtonEnumerateDevices.Click += new System.EventHandler(this.ButtonEnumerateDevices_Click); - // - // LabelDeviceInfo - // - this.LabelDeviceInfo.AutoSize = true; - this.LabelDeviceInfo.Location = new System.Drawing.Point(5, 5); - this.LabelDeviceInfo.Name = "LabelDeviceInfo"; - this.LabelDeviceInfo.Size = new System.Drawing.Size(69, 15); - this.LabelDeviceInfo.TabIndex = 3; - this.LabelDeviceInfo.Text = "Device Info:"; - // - // TimerPoll - // - this.TimerPoll.Enabled = true; - this.TimerPoll.Interval = 20; - this.TimerPoll.Tick += new System.EventHandler(this.TimerPoll_Tick_1); - // - // ButtonAttach - // - this.ButtonAttach.Location = new System.Drawing.Point(1040, 12); - this.ButtonAttach.Name = "ButtonAttach"; - this.ButtonAttach.Size = new System.Drawing.Size(100, 23); - this.ButtonAttach.TabIndex = 5; - this.ButtonAttach.Text = "Attach"; - this.ButtonAttach.UseVisualStyleBackColor = true; - this.ButtonAttach.Click += new System.EventHandler(this.ButtonAttach_Click); - // - // ButtonRemove - // - this.ButtonRemove.Location = new System.Drawing.Point(1146, 12); - this.ButtonRemove.Name = "ButtonRemove"; - this.ButtonRemove.Size = new System.Drawing.Size(100, 23); - this.ButtonRemove.TabIndex = 6; - this.ButtonRemove.Text = "Remove"; - this.ButtonRemove.UseVisualStyleBackColor = true; - this.ButtonRemove.Click += new System.EventHandler(this.ButtonRemove_Click); - // - // TabController - // - this.TabController.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.TabController.Controls.Add(this.TabDeviceInfo); - this.TabController.Controls.Add(this.TabInput); - this.TabController.Controls.Add(this.TabFFB); - this.TabController.Controls.Add(this.TabMisc); - this.TabController.Location = new System.Drawing.Point(12, 41); - this.TabController.Name = "TabController"; - this.TabController.SelectedIndex = 0; - this.TabController.Size = new System.Drawing.Size(1234, 665); - this.TabController.TabIndex = 7; - // - // TabDeviceInfo - // - this.TabDeviceInfo.Controls.Add(this.LabelDeviceInfo); - this.TabDeviceInfo.Controls.Add(this.LabelFFBCapabilities); - this.TabDeviceInfo.Controls.Add(this.LabelCapabilities); - this.TabDeviceInfo.Location = new System.Drawing.Point(4, 24); - this.TabDeviceInfo.Name = "TabDeviceInfo"; - this.TabDeviceInfo.Size = new System.Drawing.Size(1226, 637); - this.TabDeviceInfo.TabIndex = 3; - this.TabDeviceInfo.Text = "Info"; - this.TabDeviceInfo.UseVisualStyleBackColor = true; - // - // LabelFFBCapabilities - // - this.LabelFFBCapabilities.AutoSize = true; - this.LabelFFBCapabilities.Location = new System.Drawing.Point(5, 408); - this.LabelFFBCapabilities.MaximumSize = new System.Drawing.Size(1226, 0); - this.LabelFFBCapabilities.Name = "LabelFFBCapabilities"; - this.LabelFFBCapabilities.Size = new System.Drawing.Size(157, 15); - this.LabelFFBCapabilities.TabIndex = 4; - this.LabelFFBCapabilities.Text = "FFBCapabilities: Attatch First"; - // - // LabelCapabilities - // - this.LabelCapabilities.AutoSize = true; - this.LabelCapabilities.Location = new System.Drawing.Point(5, 165); - this.LabelCapabilities.MaximumSize = new System.Drawing.Size(1226, 0); - this.LabelCapabilities.Name = "LabelCapabilities"; - this.LabelCapabilities.Size = new System.Drawing.Size(138, 15); - this.LabelCapabilities.TabIndex = 4; - this.LabelCapabilities.Text = "Capabilities: Attatch First"; - // - // TabInput - // - this.TabInput.Controls.Add(this.LabelInput); - this.TabInput.Location = new System.Drawing.Point(4, 24); - this.TabInput.Name = "TabInput"; - this.TabInput.Padding = new System.Windows.Forms.Padding(3); - this.TabInput.Size = new System.Drawing.Size(1226, 637); - this.TabInput.TabIndex = 0; - this.TabInput.Text = "Input"; - this.TabInput.UseVisualStyleBackColor = true; - // - // LabelInput - // - this.LabelInput.AutoSize = true; - this.LabelInput.Location = new System.Drawing.Point(5, 5); - this.LabelInput.Name = "LabelInput"; - this.LabelInput.Size = new System.Drawing.Size(101, 15); - this.LabelInput.TabIndex = 4; - this.LabelInput.Text = "Input: Attach First"; - // - // TabFFB - // - this.TabFFB.Controls.Add(this.GBSpring); - this.TabFFB.Controls.Add(this.GBInertia); - this.TabFFB.Controls.Add(this.GBFriction); - this.TabFFB.Controls.Add(this.GBDamper); - this.TabFFB.Controls.Add(this.GBConstantForce); - this.TabFFB.Location = new System.Drawing.Point(4, 24); - this.TabFFB.Name = "TabFFB"; - this.TabFFB.Padding = new System.Windows.Forms.Padding(3); - this.TabFFB.Size = new System.Drawing.Size(1226, 637); - this.TabFFB.TabIndex = 1; - this.TabFFB.Text = "FFB"; - this.TabFFB.UseVisualStyleBackColor = true; - // - // GBSpring - // - this.GBSpring.Controls.Add(this.CBSpring); - this.GBSpring.Controls.Add(this.UDSpringDeadband); - this.GBSpring.Controls.Add(this.UDSpringSaturation); - this.GBSpring.Controls.Add(this.UDSpringCoefficient); - this.GBSpring.Controls.Add(this.UDSpringOffset); - this.GBSpring.Controls.Add(this.SliderSpringDeadband); - this.GBSpring.Controls.Add(this.LabelSpringDeadband); - this.GBSpring.Controls.Add(this.SliderSpringSaturation); - this.GBSpring.Controls.Add(this.LabelSpringSaturation); - this.GBSpring.Controls.Add(this.SliderSpringCoefficient); - this.GBSpring.Controls.Add(this.LabelSpringCoefficient); - this.GBSpring.Controls.Add(this.SliderSpringOffset); - this.GBSpring.Controls.Add(this.LabelSpringOffset); - this.GBSpring.Location = new System.Drawing.Point(6, 80); - this.GBSpring.Name = "GBSpring"; - this.GBSpring.Size = new System.Drawing.Size(1214, 180); - this.GBSpring.TabIndex = 0; - this.GBSpring.TabStop = false; - this.GBSpring.Tag = "Spring"; - this.GBSpring.Text = " Spring Force"; - this.GBSpring.Click += new System.EventHandler(this.FFB_GroupBox_Click); - // - // CBSpring - // - this.CBSpring.AutoSize = true; - this.CBSpring.Location = new System.Drawing.Point(0, 3); - this.CBSpring.Name = "CBSpring"; - this.CBSpring.Size = new System.Drawing.Size(15, 14); - this.CBSpring.TabIndex = 1; - this.CBSpring.Tag = "Spring"; - this.CBSpring.UseVisualStyleBackColor = true; - this.CBSpring.CheckedChanged += new System.EventHandler(this.FFB_CheckBox_CheckedChanged); - // - // UDSpringDeadband - // - this.UDSpringDeadband.Enabled = false; - this.UDSpringDeadband.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDSpringDeadband.Location = new System.Drawing.Point(1112, 141); - this.UDSpringDeadband.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDSpringDeadband.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDSpringDeadband.Name = "UDSpringDeadband"; - this.UDSpringDeadband.Size = new System.Drawing.Size(96, 23); - this.UDSpringDeadband.TabIndex = 2; - this.UDSpringDeadband.Tag = "SpringDeadband"; - this.UDSpringDeadband.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // UDSpringSaturation - // - this.UDSpringSaturation.Enabled = false; - this.UDSpringSaturation.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDSpringSaturation.Location = new System.Drawing.Point(1112, 104); - this.UDSpringSaturation.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDSpringSaturation.Name = "UDSpringSaturation"; - this.UDSpringSaturation.Size = new System.Drawing.Size(96, 23); - this.UDSpringSaturation.TabIndex = 2; - this.UDSpringSaturation.Tag = "SpringSaturation"; - this.UDSpringSaturation.Value = new decimal(new int[] { - 5000, - 0, - 0, - 0}); - this.UDSpringSaturation.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // UDSpringCoefficient - // - this.UDSpringCoefficient.Enabled = false; - this.UDSpringCoefficient.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDSpringCoefficient.Location = new System.Drawing.Point(1112, 67); - this.UDSpringCoefficient.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDSpringCoefficient.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDSpringCoefficient.Name = "UDSpringCoefficient"; - this.UDSpringCoefficient.Size = new System.Drawing.Size(96, 23); - this.UDSpringCoefficient.TabIndex = 2; - this.UDSpringCoefficient.Tag = "SpringCoefficient"; - this.UDSpringCoefficient.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // UDSpringOffset - // - this.UDSpringOffset.Enabled = false; - this.UDSpringOffset.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDSpringOffset.Location = new System.Drawing.Point(1112, 30); - this.UDSpringOffset.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDSpringOffset.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDSpringOffset.Name = "UDSpringOffset"; - this.UDSpringOffset.Size = new System.Drawing.Size(96, 23); - this.UDSpringOffset.TabIndex = 2; - this.UDSpringOffset.Tag = "SpringOffset"; - this.UDSpringOffset.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // SliderSpringDeadband - // - this.SliderSpringDeadband.AutoSize = false; - this.SliderSpringDeadband.BackColor = System.Drawing.SystemColors.Control; - this.SliderSpringDeadband.Enabled = false; - this.SliderSpringDeadband.LargeChange = 50; - this.SliderSpringDeadband.Location = new System.Drawing.Point(108, 141); - this.SliderSpringDeadband.Maximum = 10000; - this.SliderSpringDeadband.Name = "SliderSpringDeadband"; - this.SliderSpringDeadband.Size = new System.Drawing.Size(998, 31); - this.SliderSpringDeadband.TabIndex = 0; - this.SliderSpringDeadband.Tag = "SpringDeadband"; - this.SliderSpringDeadband.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderSpringDeadband.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // LabelSpringDeadband - // - this.LabelSpringDeadband.AutoSize = true; - this.LabelSpringDeadband.Location = new System.Drawing.Point(6, 143); - this.LabelSpringDeadband.Name = "LabelSpringDeadband"; - this.LabelSpringDeadband.Size = new System.Drawing.Size(64, 15); - this.LabelSpringDeadband.TabIndex = 3; - this.LabelSpringDeadband.Tag = "SpringDeadband"; - this.LabelSpringDeadband.Text = "Deadband:"; - this.LabelSpringDeadband.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderSpringSaturation - // - this.SliderSpringSaturation.AutoSize = false; - this.SliderSpringSaturation.BackColor = System.Drawing.SystemColors.Control; - this.SliderSpringSaturation.Enabled = false; - this.SliderSpringSaturation.LargeChange = 50; - this.SliderSpringSaturation.Location = new System.Drawing.Point(108, 104); - this.SliderSpringSaturation.Maximum = 10000; - this.SliderSpringSaturation.Name = "SliderSpringSaturation"; - this.SliderSpringSaturation.Size = new System.Drawing.Size(998, 31); - this.SliderSpringSaturation.TabIndex = 0; - this.SliderSpringSaturation.Tag = "SpringSaturation"; - this.SliderSpringSaturation.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderSpringSaturation.Value = 5000; - this.SliderSpringSaturation.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // LabelSpringSaturation - // - this.LabelSpringSaturation.AutoSize = true; - this.LabelSpringSaturation.Location = new System.Drawing.Point(6, 106); - this.LabelSpringSaturation.Name = "LabelSpringSaturation"; - this.LabelSpringSaturation.Size = new System.Drawing.Size(64, 15); - this.LabelSpringSaturation.TabIndex = 3; - this.LabelSpringSaturation.Tag = "SpringSaturation"; - this.LabelSpringSaturation.Text = "Saturation:"; - this.LabelSpringSaturation.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderSpringCoefficient - // - this.SliderSpringCoefficient.AutoSize = false; - this.SliderSpringCoefficient.BackColor = System.Drawing.SystemColors.Control; - this.SliderSpringCoefficient.Enabled = false; - this.SliderSpringCoefficient.LargeChange = 50; - this.SliderSpringCoefficient.Location = new System.Drawing.Point(108, 67); - this.SliderSpringCoefficient.Maximum = 10000; - this.SliderSpringCoefficient.Minimum = -10000; - this.SliderSpringCoefficient.Name = "SliderSpringCoefficient"; - this.SliderSpringCoefficient.Size = new System.Drawing.Size(998, 31); - this.SliderSpringCoefficient.TabIndex = 0; - this.SliderSpringCoefficient.Tag = "SpringCoefficient"; - this.SliderSpringCoefficient.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderSpringCoefficient.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // LabelSpringCoefficient - // - this.LabelSpringCoefficient.AutoSize = true; - this.LabelSpringCoefficient.Location = new System.Drawing.Point(6, 69); - this.LabelSpringCoefficient.Name = "LabelSpringCoefficient"; - this.LabelSpringCoefficient.Size = new System.Drawing.Size(68, 15); - this.LabelSpringCoefficient.TabIndex = 3; - this.LabelSpringCoefficient.Tag = "SpringCoefficient"; - this.LabelSpringCoefficient.Text = "Coefficient:"; - this.LabelSpringCoefficient.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderSpringOffset - // - this.SliderSpringOffset.AutoSize = false; - this.SliderSpringOffset.BackColor = System.Drawing.SystemColors.Control; - this.SliderSpringOffset.Enabled = false; - this.SliderSpringOffset.LargeChange = 50; - this.SliderSpringOffset.Location = new System.Drawing.Point(108, 30); - this.SliderSpringOffset.Maximum = 10000; - this.SliderSpringOffset.Minimum = -10000; - this.SliderSpringOffset.Name = "SliderSpringOffset"; - this.SliderSpringOffset.Size = new System.Drawing.Size(998, 31); - this.SliderSpringOffset.TabIndex = 0; - this.SliderSpringOffset.Tag = "SpringOffset"; - this.SliderSpringOffset.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderSpringOffset.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // LabelSpringOffset - // - this.LabelSpringOffset.AutoSize = true; - this.LabelSpringOffset.Location = new System.Drawing.Point(6, 32); - this.LabelSpringOffset.Name = "LabelSpringOffset"; - this.LabelSpringOffset.Size = new System.Drawing.Size(42, 15); - this.LabelSpringOffset.TabIndex = 3; - this.LabelSpringOffset.Tag = "SpringOffset"; - this.LabelSpringOffset.Text = "Offset:"; - this.LabelSpringOffset.Click += new System.EventHandler(this.FFB_Label_Click); - // - // GBInertia - // - this.GBInertia.Controls.Add(this.CBInertia); - this.GBInertia.Controls.Add(this.UDInertiaMagnitude); - this.GBInertia.Controls.Add(this.LabelInertiaMagnitude); - this.GBInertia.Controls.Add(this.SliderInertiaMagnitude); - this.GBInertia.Location = new System.Drawing.Point(6, 414); - this.GBInertia.Name = "GBInertia"; - this.GBInertia.Size = new System.Drawing.Size(1214, 68); - this.GBInertia.TabIndex = 0; - this.GBInertia.TabStop = false; - this.GBInertia.Tag = "Inertia"; - this.GBInertia.Text = " Inertia"; - this.GBInertia.Click += new System.EventHandler(this.FFB_GroupBox_Click); - // - // CBInertia - // - this.CBInertia.AutoSize = true; - this.CBInertia.Location = new System.Drawing.Point(0, 3); - this.CBInertia.Name = "CBInertia"; - this.CBInertia.Size = new System.Drawing.Size(15, 14); - this.CBInertia.TabIndex = 1; - this.CBInertia.Tag = "Inertia"; - this.CBInertia.UseVisualStyleBackColor = true; - this.CBInertia.CheckedChanged += new System.EventHandler(this.FFB_CheckBox_CheckedChanged); - // - // UDInertiaMagnitude - // - this.UDInertiaMagnitude.Enabled = false; - this.UDInertiaMagnitude.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDInertiaMagnitude.Location = new System.Drawing.Point(1112, 30); - this.UDInertiaMagnitude.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDInertiaMagnitude.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDInertiaMagnitude.Name = "UDInertiaMagnitude"; - this.UDInertiaMagnitude.Size = new System.Drawing.Size(96, 23); - this.UDInertiaMagnitude.TabIndex = 2; - this.UDInertiaMagnitude.Tag = "InertiaMagnitude"; - this.UDInertiaMagnitude.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // LabelInertiaMagnitude - // - this.LabelInertiaMagnitude.AutoSize = true; - this.LabelInertiaMagnitude.Location = new System.Drawing.Point(6, 32); - this.LabelInertiaMagnitude.Name = "LabelInertiaMagnitude"; - this.LabelInertiaMagnitude.Size = new System.Drawing.Size(68, 15); - this.LabelInertiaMagnitude.TabIndex = 3; - this.LabelInertiaMagnitude.Tag = "InertiaMagnitude"; - this.LabelInertiaMagnitude.Text = "Magnitude:"; - this.LabelInertiaMagnitude.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderInertiaMagnitude - // - this.SliderInertiaMagnitude.AutoSize = false; - this.SliderInertiaMagnitude.BackColor = System.Drawing.SystemColors.Control; - this.SliderInertiaMagnitude.Enabled = false; - this.SliderInertiaMagnitude.LargeChange = 50; - this.SliderInertiaMagnitude.Location = new System.Drawing.Point(108, 30); - this.SliderInertiaMagnitude.Maximum = 10000; - this.SliderInertiaMagnitude.Minimum = -10000; - this.SliderInertiaMagnitude.Name = "SliderInertiaMagnitude"; - this.SliderInertiaMagnitude.Size = new System.Drawing.Size(998, 31); - this.SliderInertiaMagnitude.TabIndex = 0; - this.SliderInertiaMagnitude.Tag = "InertiaMagnitude"; - this.SliderInertiaMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderInertiaMagnitude.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // GBFriction - // - this.GBFriction.Controls.Add(this.UDFrictionMagnitude); - this.GBFriction.Controls.Add(this.CBFriction); - this.GBFriction.Controls.Add(this.LabelFrictionMagnitude); - this.GBFriction.Controls.Add(this.SliderFrictionMagnitude); - this.GBFriction.Location = new System.Drawing.Point(6, 340); - this.GBFriction.Name = "GBFriction"; - this.GBFriction.Size = new System.Drawing.Size(1214, 68); - this.GBFriction.TabIndex = 0; - this.GBFriction.TabStop = false; - this.GBFriction.Tag = "Friction"; - this.GBFriction.Text = " Friction"; - this.GBFriction.Click += new System.EventHandler(this.FFB_GroupBox_Click); - // - // UDFrictionMagnitude - // - this.UDFrictionMagnitude.Enabled = false; - this.UDFrictionMagnitude.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDFrictionMagnitude.Location = new System.Drawing.Point(1112, 30); - this.UDFrictionMagnitude.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDFrictionMagnitude.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDFrictionMagnitude.Name = "UDFrictionMagnitude"; - this.UDFrictionMagnitude.Size = new System.Drawing.Size(96, 23); - this.UDFrictionMagnitude.TabIndex = 2; - this.UDFrictionMagnitude.Tag = "FrictionMagnitude"; - this.UDFrictionMagnitude.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // CBFriction - // - this.CBFriction.AutoSize = true; - this.CBFriction.Location = new System.Drawing.Point(0, 3); - this.CBFriction.Name = "CBFriction"; - this.CBFriction.Size = new System.Drawing.Size(15, 14); - this.CBFriction.TabIndex = 1; - this.CBFriction.Tag = "Friction"; - this.CBFriction.UseVisualStyleBackColor = true; - this.CBFriction.CheckedChanged += new System.EventHandler(this.FFB_CheckBox_CheckedChanged); - // - // LabelFrictionMagnitude - // - this.LabelFrictionMagnitude.AutoSize = true; - this.LabelFrictionMagnitude.Location = new System.Drawing.Point(6, 32); - this.LabelFrictionMagnitude.Name = "LabelFrictionMagnitude"; - this.LabelFrictionMagnitude.Size = new System.Drawing.Size(68, 15); - this.LabelFrictionMagnitude.TabIndex = 3; - this.LabelFrictionMagnitude.Tag = "FrictionMagnitude"; - this.LabelFrictionMagnitude.Text = "Magnitude:"; - this.LabelFrictionMagnitude.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderFrictionMagnitude - // - this.SliderFrictionMagnitude.AutoSize = false; - this.SliderFrictionMagnitude.BackColor = System.Drawing.SystemColors.Control; - this.SliderFrictionMagnitude.Enabled = false; - this.SliderFrictionMagnitude.LargeChange = 50; - this.SliderFrictionMagnitude.Location = new System.Drawing.Point(108, 30); - this.SliderFrictionMagnitude.Maximum = 10000; - this.SliderFrictionMagnitude.Minimum = -10000; - this.SliderFrictionMagnitude.Name = "SliderFrictionMagnitude"; - this.SliderFrictionMagnitude.Size = new System.Drawing.Size(998, 31); - this.SliderFrictionMagnitude.TabIndex = 0; - this.SliderFrictionMagnitude.Tag = "FrictionMagnitude"; - this.SliderFrictionMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderFrictionMagnitude.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // GBDamper - // - this.GBDamper.Controls.Add(this.UDDamperMagnitude); - this.GBDamper.Controls.Add(this.LabelDamperMagnitude); - this.GBDamper.Controls.Add(this.CBDamper); - this.GBDamper.Controls.Add(this.SliderDamperMagnitude); - this.GBDamper.Location = new System.Drawing.Point(6, 266); - this.GBDamper.Name = "GBDamper"; - this.GBDamper.Size = new System.Drawing.Size(1214, 68); - this.GBDamper.TabIndex = 0; - this.GBDamper.TabStop = false; - this.GBDamper.Tag = "Damper"; - this.GBDamper.Text = " Damper"; - this.GBDamper.Click += new System.EventHandler(this.FFB_GroupBox_Click); - // - // UDDamperMagnitude - // - this.UDDamperMagnitude.Enabled = false; - this.UDDamperMagnitude.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDDamperMagnitude.Location = new System.Drawing.Point(1112, 30); - this.UDDamperMagnitude.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDDamperMagnitude.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDDamperMagnitude.Name = "UDDamperMagnitude"; - this.UDDamperMagnitude.Size = new System.Drawing.Size(96, 23); - this.UDDamperMagnitude.TabIndex = 2; - this.UDDamperMagnitude.Tag = "DamperMagnitude"; - this.UDDamperMagnitude.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // LabelDamperMagnitude - // - this.LabelDamperMagnitude.AutoSize = true; - this.LabelDamperMagnitude.Location = new System.Drawing.Point(6, 32); - this.LabelDamperMagnitude.Name = "LabelDamperMagnitude"; - this.LabelDamperMagnitude.Size = new System.Drawing.Size(68, 15); - this.LabelDamperMagnitude.TabIndex = 3; - this.LabelDamperMagnitude.Tag = "DamperMagnitude"; - this.LabelDamperMagnitude.Text = "Magnitude:"; - this.LabelDamperMagnitude.Click += new System.EventHandler(this.FFB_Label_Click); - // - // CBDamper - // - this.CBDamper.AutoSize = true; - this.CBDamper.Location = new System.Drawing.Point(0, 3); - this.CBDamper.Name = "CBDamper"; - this.CBDamper.Size = new System.Drawing.Size(15, 14); - this.CBDamper.TabIndex = 1; - this.CBDamper.Tag = "Damper"; - this.CBDamper.UseVisualStyleBackColor = true; - this.CBDamper.CheckedChanged += new System.EventHandler(this.FFB_CheckBox_CheckedChanged); - // - // SliderDamperMagnitude - // - this.SliderDamperMagnitude.AutoSize = false; - this.SliderDamperMagnitude.BackColor = System.Drawing.SystemColors.Control; - this.SliderDamperMagnitude.Enabled = false; - this.SliderDamperMagnitude.LargeChange = 50; - this.SliderDamperMagnitude.Location = new System.Drawing.Point(108, 30); - this.SliderDamperMagnitude.Maximum = 10000; - this.SliderDamperMagnitude.Minimum = -10000; - this.SliderDamperMagnitude.Name = "SliderDamperMagnitude"; - this.SliderDamperMagnitude.Size = new System.Drawing.Size(998, 31); - this.SliderDamperMagnitude.TabIndex = 0; - this.SliderDamperMagnitude.Tag = "DamperMagnitude"; - this.SliderDamperMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderDamperMagnitude.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // GBConstantForce - // - this.GBConstantForce.Controls.Add(this.CBConstantForce); - this.GBConstantForce.Controls.Add(this.UDConstantForceMagnitude); - this.GBConstantForce.Controls.Add(this.LabelConstantForceMagnitude); - this.GBConstantForce.Controls.Add(this.SliderConstantForceMagnitude); - this.GBConstantForce.Location = new System.Drawing.Point(6, 6); - this.GBConstantForce.Name = "GBConstantForce"; - this.GBConstantForce.Size = new System.Drawing.Size(1214, 68); - this.GBConstantForce.TabIndex = 0; - this.GBConstantForce.TabStop = false; - this.GBConstantForce.Tag = "ConstantForce"; - this.GBConstantForce.Text = " Constant Force"; - this.GBConstantForce.Click += new System.EventHandler(this.FFB_GroupBox_Click); - // - // CBConstantForce - // - this.CBConstantForce.AutoSize = true; - this.CBConstantForce.Location = new System.Drawing.Point(0, 3); - this.CBConstantForce.Name = "CBConstantForce"; - this.CBConstantForce.Size = new System.Drawing.Size(15, 14); - this.CBConstantForce.TabIndex = 1; - this.CBConstantForce.Tag = "ConstantForce"; - this.CBConstantForce.UseVisualStyleBackColor = true; - this.CBConstantForce.CheckedChanged += new System.EventHandler(this.FFB_CheckBox_CheckedChanged); - // - // UDConstantForceMagnitude - // - this.UDConstantForceMagnitude.Enabled = false; - this.UDConstantForceMagnitude.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.UDConstantForceMagnitude.Location = new System.Drawing.Point(1112, 30); - this.UDConstantForceMagnitude.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.UDConstantForceMagnitude.Minimum = new decimal(new int[] { - 10000, - 0, - 0, - -2147483648}); - this.UDConstantForceMagnitude.Name = "UDConstantForceMagnitude"; - this.UDConstantForceMagnitude.Size = new System.Drawing.Size(96, 23); - this.UDConstantForceMagnitude.TabIndex = 2; - this.UDConstantForceMagnitude.Tag = "ConstantForceMagnitude"; - this.UDConstantForceMagnitude.ValueChanged += new System.EventHandler(this.FFB_UpDown_ValueChanged); - // - // LabelConstantForceMagnitude - // - this.LabelConstantForceMagnitude.AutoSize = true; - this.LabelConstantForceMagnitude.Location = new System.Drawing.Point(6, 32); - this.LabelConstantForceMagnitude.Name = "LabelConstantForceMagnitude"; - this.LabelConstantForceMagnitude.Size = new System.Drawing.Size(68, 15); - this.LabelConstantForceMagnitude.TabIndex = 3; - this.LabelConstantForceMagnitude.Tag = "ConstantForceMagnitude"; - this.LabelConstantForceMagnitude.Text = "Magnitude:"; - this.LabelConstantForceMagnitude.Click += new System.EventHandler(this.FFB_Label_Click); - // - // SliderConstantForceMagnitude - // - this.SliderConstantForceMagnitude.AutoSize = false; - this.SliderConstantForceMagnitude.BackColor = System.Drawing.SystemColors.Control; - this.SliderConstantForceMagnitude.Enabled = false; - this.SliderConstantForceMagnitude.LargeChange = 50; - this.SliderConstantForceMagnitude.Location = new System.Drawing.Point(108, 30); - this.SliderConstantForceMagnitude.Maximum = 10000; - this.SliderConstantForceMagnitude.Minimum = -10000; - this.SliderConstantForceMagnitude.Name = "SliderConstantForceMagnitude"; - this.SliderConstantForceMagnitude.Size = new System.Drawing.Size(998, 31); - this.SliderConstantForceMagnitude.TabIndex = 0; - this.SliderConstantForceMagnitude.Tag = "ConstantForceMagnitude"; - this.SliderConstantForceMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; - this.SliderConstantForceMagnitude.Scroll += new System.EventHandler(this.FFB_Slider_Scroll); - // - // TabMisc - // - this.TabMisc.Controls.Add(this.LabelDebug); - this.TabMisc.Controls.Add(this.ButtonDebug); - this.TabMisc.Location = new System.Drawing.Point(4, 24); - this.TabMisc.Name = "TabMisc"; - this.TabMisc.Padding = new System.Windows.Forms.Padding(3); - this.TabMisc.Size = new System.Drawing.Size(1226, 637); - this.TabMisc.TabIndex = 4; - this.TabMisc.Text = "Misc"; - this.TabMisc.UseVisualStyleBackColor = true; - // - // LabelDebug - // - this.LabelDebug.AutoSize = true; - this.LabelDebug.Location = new System.Drawing.Point(6, 3); - this.LabelDebug.Name = "LabelDebug"; - this.LabelDebug.Size = new System.Drawing.Size(73, 15); - this.LabelDebug.TabIndex = 1; - this.LabelDebug.Text = "Debug Stuff:"; - // - // ButtonDebug - // - this.ButtonDebug.Location = new System.Drawing.Point(1077, 6); - this.ButtonDebug.Name = "ButtonDebug"; - this.ButtonDebug.Size = new System.Drawing.Size(143, 55); - this.ButtonDebug.TabIndex = 0; - this.ButtonDebug.Text = "Debug"; - this.ButtonDebug.UseVisualStyleBackColor = true; - this.ButtonDebug.Click += new System.EventHandler(this.ButtonDebug_Click); - // - // Form1 - // - this.ClientSize = new System.Drawing.Size(1258, 718); - this.Controls.Add(this.TabController); - this.Controls.Add(this.ButtonRemove); - this.Controls.Add(this.ButtonAttach); - this.Controls.Add(this.ButtonEnumerateDevices); - this.Controls.Add(this.ComboBoxDevices); - this.Name = "Form1"; - this.Text = "Direct Input Explorer"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); - this.Load += new System.EventHandler(this.Form1_Load); - this.TabController.ResumeLayout(false); - this.TabDeviceInfo.ResumeLayout(false); - this.TabDeviceInfo.PerformLayout(); - this.TabInput.ResumeLayout(false); - this.TabInput.PerformLayout(); - this.TabFFB.ResumeLayout(false); - this.GBSpring.ResumeLayout(false); - this.GBSpring.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringDeadband)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringSaturation)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringCoefficient)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.UDSpringOffset)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringDeadband)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringSaturation)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringCoefficient)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderSpringOffset)).EndInit(); - this.GBInertia.ResumeLayout(false); - this.GBInertia.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDInertiaMagnitude)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderInertiaMagnitude)).EndInit(); - this.GBFriction.ResumeLayout(false); - this.GBFriction.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDFrictionMagnitude)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderFrictionMagnitude)).EndInit(); - this.GBDamper.ResumeLayout(false); - this.GBDamper.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDDamperMagnitude)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderDamperMagnitude)).EndInit(); - this.GBConstantForce.ResumeLayout(false); - this.GBConstantForce.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UDConstantForceMagnitude)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SliderConstantForceMagnitude)).EndInit(); - this.TabMisc.ResumeLayout(false); - this.TabMisc.PerformLayout(); - this.ResumeLayout(false); + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + ComboBoxDevices = new System.Windows.Forms.ComboBox(); + ButtonEnumerateDevices = new System.Windows.Forms.Button(); + LabelDeviceInfo = new System.Windows.Forms.Label(); + TimerPoll = new System.Windows.Forms.Timer(components); + ButtonAttach = new System.Windows.Forms.Button(); + ButtonRemove = new System.Windows.Forms.Button(); + TabController = new System.Windows.Forms.TabControl(); + TabDeviceInfo = new System.Windows.Forms.TabPage(); + LabelFFBCapabilities = new System.Windows.Forms.Label(); + LabelCapabilities = new System.Windows.Forms.Label(); + TabInput = new System.Windows.Forms.TabPage(); + LabelInput = new System.Windows.Forms.Label(); + TabFFB = new System.Windows.Forms.TabPage(); + GBSine = new System.Windows.Forms.GroupBox(); + checkBox6 = new System.Windows.Forms.CheckBox(); + UDSineMagnitude = new System.Windows.Forms.NumericUpDown(); + label6 = new System.Windows.Forms.Label(); + SliderSineMagnitude = new System.Windows.Forms.TrackBar(); + GBSquare = new System.Windows.Forms.GroupBox(); + checkBox5 = new System.Windows.Forms.CheckBox(); + UDSquareMagnitude = new System.Windows.Forms.NumericUpDown(); + label5 = new System.Windows.Forms.Label(); + SliderSquareMagnitude = new System.Windows.Forms.TrackBar(); + GBTriangle = new System.Windows.Forms.GroupBox(); + checkBox4 = new System.Windows.Forms.CheckBox(); + UDTriangleMagnitude = new System.Windows.Forms.NumericUpDown(); + label4 = new System.Windows.Forms.Label(); + SliderTriangleMagnitude = new System.Windows.Forms.TrackBar(); + GBRampForce = new System.Windows.Forms.GroupBox(); + checkBox3 = new System.Windows.Forms.CheckBox(); + UDRampForceMagnitude = new System.Windows.Forms.NumericUpDown(); + label3 = new System.Windows.Forms.Label(); + SliderRampForceMagnitude = new System.Windows.Forms.TrackBar(); + GBSawtoothUp = new System.Windows.Forms.GroupBox(); + checkBox2 = new System.Windows.Forms.CheckBox(); + UDSawtoothUpMagnitude = new System.Windows.Forms.NumericUpDown(); + label2 = new System.Windows.Forms.Label(); + SliderSawtoothUpMagnitude = new System.Windows.Forms.TrackBar(); + GBSawtoothDown = new System.Windows.Forms.GroupBox(); + checkBox1 = new System.Windows.Forms.CheckBox(); + UDSawtoothDownMagnitude = new System.Windows.Forms.NumericUpDown(); + label1 = new System.Windows.Forms.Label(); + SliderSawtoothDownMagnitude = new System.Windows.Forms.TrackBar(); + GBSpring = new System.Windows.Forms.GroupBox(); + CBSpring = new System.Windows.Forms.CheckBox(); + UDSpringDeadband = new System.Windows.Forms.NumericUpDown(); + UDSpringSaturation = new System.Windows.Forms.NumericUpDown(); + UDSpringCoefficient = new System.Windows.Forms.NumericUpDown(); + UDSpringOffset = new System.Windows.Forms.NumericUpDown(); + SliderSpringDeadband = new System.Windows.Forms.TrackBar(); + LabelSpringDeadband = new System.Windows.Forms.Label(); + SliderSpringSaturation = new System.Windows.Forms.TrackBar(); + LabelSpringSaturation = new System.Windows.Forms.Label(); + SliderSpringCoefficient = new System.Windows.Forms.TrackBar(); + LabelSpringCoefficient = new System.Windows.Forms.Label(); + SliderSpringOffset = new System.Windows.Forms.TrackBar(); + LabelSpringOffset = new System.Windows.Forms.Label(); + GBInertia = new System.Windows.Forms.GroupBox(); + CBInertia = new System.Windows.Forms.CheckBox(); + UDInertiaMagnitude = new System.Windows.Forms.NumericUpDown(); + LabelInertiaMagnitude = new System.Windows.Forms.Label(); + SliderInertiaMagnitude = new System.Windows.Forms.TrackBar(); + GBFriction = new System.Windows.Forms.GroupBox(); + UDFrictionMagnitude = new System.Windows.Forms.NumericUpDown(); + CBFriction = new System.Windows.Forms.CheckBox(); + LabelFrictionMagnitude = new System.Windows.Forms.Label(); + SliderFrictionMagnitude = new System.Windows.Forms.TrackBar(); + GBDamper = new System.Windows.Forms.GroupBox(); + UDDamperMagnitude = new System.Windows.Forms.NumericUpDown(); + LabelDamperMagnitude = new System.Windows.Forms.Label(); + CBDamper = new System.Windows.Forms.CheckBox(); + SliderDamperMagnitude = new System.Windows.Forms.TrackBar(); + GBConstantForce = new System.Windows.Forms.GroupBox(); + CBConstantForce = new System.Windows.Forms.CheckBox(); + UDConstantForceMagnitude = new System.Windows.Forms.NumericUpDown(); + LabelConstantForceMagnitude = new System.Windows.Forms.Label(); + SliderConstantForceMagnitude = new System.Windows.Forms.TrackBar(); + tabPage1 = new System.Windows.Forms.TabPage(); + GBCuss = new System.Windows.Forms.GroupBox(); + UDCustomForceSamplePeriod = new System.Windows.Forms.NumericUpDown(); + label16 = new System.Windows.Forms.Label(); + SliderCustomForceSamplePeriod = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude9 = new System.Windows.Forms.NumericUpDown(); + label15 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude9 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude8 = new System.Windows.Forms.NumericUpDown(); + label14 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude8 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude7 = new System.Windows.Forms.NumericUpDown(); + label13 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude7 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude6 = new System.Windows.Forms.NumericUpDown(); + label12 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude6 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude5 = new System.Windows.Forms.NumericUpDown(); + label11 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude5 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude4 = new System.Windows.Forms.NumericUpDown(); + label10 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude4 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude3 = new System.Windows.Forms.NumericUpDown(); + label9 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude3 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude2 = new System.Windows.Forms.NumericUpDown(); + label8 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude2 = new System.Windows.Forms.TrackBar(); + UDCustomForceMagnitude1 = new System.Windows.Forms.NumericUpDown(); + label7 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude1 = new System.Windows.Forms.TrackBar(); + CBCustomForce = new System.Windows.Forms.CheckBox(); + UDCustomForceMagnitude0 = new System.Windows.Forms.NumericUpDown(); + LblCustomForceMagnitude0 = new System.Windows.Forms.Label(); + SliderCustomForceMagnitude0 = new System.Windows.Forms.TrackBar(); + TabMisc = new System.Windows.Forms.TabPage(); + LabelDebug = new System.Windows.Forms.Label(); + ButtonDebug = new System.Windows.Forms.Button(); + TabController.SuspendLayout(); + TabDeviceInfo.SuspendLayout(); + TabInput.SuspendLayout(); + TabFFB.SuspendLayout(); + GBSine.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDSineMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSineMagnitude).BeginInit(); + GBSquare.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDSquareMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSquareMagnitude).BeginInit(); + GBTriangle.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDTriangleMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderTriangleMagnitude).BeginInit(); + GBRampForce.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDRampForceMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderRampForceMagnitude).BeginInit(); + GBSawtoothUp.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDSawtoothUpMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSawtoothUpMagnitude).BeginInit(); + GBSawtoothDown.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDSawtoothDownMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSawtoothDownMagnitude).BeginInit(); + GBSpring.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDSpringDeadband).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringSaturation).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringCoefficient).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringOffset).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringDeadband).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringSaturation).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringCoefficient).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringOffset).BeginInit(); + GBInertia.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDInertiaMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderInertiaMagnitude).BeginInit(); + GBFriction.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDFrictionMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderFrictionMagnitude).BeginInit(); + GBDamper.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDDamperMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderDamperMagnitude).BeginInit(); + GBConstantForce.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDConstantForceMagnitude).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderConstantForceMagnitude).BeginInit(); + tabPage1.SuspendLayout(); + GBCuss.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceSamplePeriod).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceSamplePeriod).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude9).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude9).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude8).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude8).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude7).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude7).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude6).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude6).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude5).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude5).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude4).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude4).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude1).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude1).BeginInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude0).BeginInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude0).BeginInit(); + TabMisc.SuspendLayout(); + SuspendLayout(); + // + // ComboBoxDevices + // + ComboBoxDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + ComboBoxDevices.FormattingEnabled = true; + ComboBoxDevices.Location = new System.Drawing.Point(12, 12); + ComboBoxDevices.Name = "ComboBoxDevices"; + ComboBoxDevices.Size = new System.Drawing.Size(976, 23); + ComboBoxDevices.TabIndex = 1; + ComboBoxDevices.SelectedIndexChanged += ComboBoxDevices_SelectedIndexChanged; + // + // ButtonEnumerateDevices + // + ButtonEnumerateDevices.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + ButtonEnumerateDevices.Location = new System.Drawing.Point(994, 12); + ButtonEnumerateDevices.Name = "ButtonEnumerateDevices"; + ButtonEnumerateDevices.Size = new System.Drawing.Size(40, 23); + ButtonEnumerateDevices.TabIndex = 2; + ButtonEnumerateDevices.Text = "🔄"; + ButtonEnumerateDevices.UseVisualStyleBackColor = true; + ButtonEnumerateDevices.Click += ButtonEnumerateDevices_Click; + // + // LabelDeviceInfo + // + LabelDeviceInfo.AutoSize = true; + LabelDeviceInfo.Location = new System.Drawing.Point(5, 5); + LabelDeviceInfo.Name = "LabelDeviceInfo"; + LabelDeviceInfo.Size = new System.Drawing.Size(69, 15); + LabelDeviceInfo.TabIndex = 3; + LabelDeviceInfo.Text = "Device Info:"; + // + // TimerPoll + // + TimerPoll.Enabled = true; + TimerPoll.Interval = 20; + TimerPoll.Tick += TimerPoll_Tick_1; + // + // ButtonAttach + // + ButtonAttach.Location = new System.Drawing.Point(1040, 12); + ButtonAttach.Name = "ButtonAttach"; + ButtonAttach.Size = new System.Drawing.Size(100, 23); + ButtonAttach.TabIndex = 5; + ButtonAttach.Text = "Attach"; + ButtonAttach.UseVisualStyleBackColor = true; + ButtonAttach.Click += ButtonAttach_Click; + // + // ButtonRemove + // + ButtonRemove.Location = new System.Drawing.Point(1146, 12); + ButtonRemove.Name = "ButtonRemove"; + ButtonRemove.Size = new System.Drawing.Size(100, 23); + ButtonRemove.TabIndex = 6; + ButtonRemove.Text = "Remove"; + ButtonRemove.UseVisualStyleBackColor = true; + ButtonRemove.Click += ButtonRemove_Click; + // + // TabController + // + TabController.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + TabController.Controls.Add(TabDeviceInfo); + TabController.Controls.Add(TabInput); + TabController.Controls.Add(TabFFB); + TabController.Controls.Add(tabPage1); + TabController.Controls.Add(TabMisc); + TabController.Location = new System.Drawing.Point(12, 41); + TabController.Name = "TabController"; + TabController.SelectedIndex = 0; + TabController.Size = new System.Drawing.Size(1234, 665); + TabController.TabIndex = 7; + // + // TabDeviceInfo + // + TabDeviceInfo.Controls.Add(LabelDeviceInfo); + TabDeviceInfo.Controls.Add(LabelFFBCapabilities); + TabDeviceInfo.Controls.Add(LabelCapabilities); + TabDeviceInfo.Location = new System.Drawing.Point(4, 24); + TabDeviceInfo.Name = "TabDeviceInfo"; + TabDeviceInfo.Size = new System.Drawing.Size(1226, 637); + TabDeviceInfo.TabIndex = 3; + TabDeviceInfo.Text = "Info"; + TabDeviceInfo.UseVisualStyleBackColor = true; + // + // LabelFFBCapabilities + // + LabelFFBCapabilities.AutoSize = true; + LabelFFBCapabilities.Location = new System.Drawing.Point(5, 408); + LabelFFBCapabilities.MaximumSize = new System.Drawing.Size(1226, 0); + LabelFFBCapabilities.Name = "LabelFFBCapabilities"; + LabelFFBCapabilities.Size = new System.Drawing.Size(157, 15); + LabelFFBCapabilities.TabIndex = 4; + LabelFFBCapabilities.Text = "FFBCapabilities: Attatch First"; + // + // LabelCapabilities + // + LabelCapabilities.AutoSize = true; + LabelCapabilities.Location = new System.Drawing.Point(5, 165); + LabelCapabilities.MaximumSize = new System.Drawing.Size(1226, 0); + LabelCapabilities.Name = "LabelCapabilities"; + LabelCapabilities.Size = new System.Drawing.Size(138, 15); + LabelCapabilities.TabIndex = 4; + LabelCapabilities.Text = "Capabilities: Attatch First"; + // + // TabInput + // + TabInput.Controls.Add(LabelInput); + TabInput.Location = new System.Drawing.Point(4, 24); + TabInput.Name = "TabInput"; + TabInput.Padding = new System.Windows.Forms.Padding(3); + TabInput.Size = new System.Drawing.Size(1226, 637); + TabInput.TabIndex = 0; + TabInput.Text = "Input"; + TabInput.UseVisualStyleBackColor = true; + // + // LabelInput + // + LabelInput.AutoSize = true; + LabelInput.Location = new System.Drawing.Point(5, 5); + LabelInput.Name = "LabelInput"; + LabelInput.Size = new System.Drawing.Size(101, 15); + LabelInput.TabIndex = 4; + LabelInput.Text = "Input: Attach First"; + // + // TabFFB + // + TabFFB.Controls.Add(GBSine); + TabFFB.Controls.Add(GBSquare); + TabFFB.Controls.Add(GBTriangle); + TabFFB.Controls.Add(GBRampForce); + TabFFB.Controls.Add(GBSawtoothUp); + TabFFB.Controls.Add(GBSawtoothDown); + TabFFB.Controls.Add(GBSpring); + TabFFB.Controls.Add(GBInertia); + TabFFB.Controls.Add(GBFriction); + TabFFB.Controls.Add(GBDamper); + TabFFB.Controls.Add(GBConstantForce); + TabFFB.Location = new System.Drawing.Point(4, 24); + TabFFB.Name = "TabFFB"; + TabFFB.Padding = new System.Windows.Forms.Padding(3); + TabFFB.Size = new System.Drawing.Size(1226, 637); + TabFFB.TabIndex = 1; + TabFFB.Text = "FFB"; + TabFFB.UseVisualStyleBackColor = true; + // + // GBSine + // + GBSine.Controls.Add(checkBox6); + GBSine.Controls.Add(UDSineMagnitude); + GBSine.Controls.Add(label6); + GBSine.Controls.Add(SliderSineMagnitude); + GBSine.Location = new System.Drawing.Point(6, 568); + GBSine.Name = "GBSine"; + GBSine.Size = new System.Drawing.Size(403, 69); + GBSine.TabIndex = 5; + GBSine.TabStop = false; + GBSine.Tag = "Sine"; + GBSine.Text = " Sine"; + // + // checkBox6 + // + checkBox6.AutoSize = true; + checkBox6.Location = new System.Drawing.Point(0, 3); + checkBox6.Name = "checkBox6"; + checkBox6.Size = new System.Drawing.Size(15, 14); + checkBox6.TabIndex = 1; + checkBox6.Tag = "Sine"; + checkBox6.UseVisualStyleBackColor = true; + checkBox6.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDSineMagnitude + // + UDSineMagnitude.Enabled = false; + UDSineMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSineMagnitude.Location = new System.Drawing.Point(301, 31); + UDSineMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSineMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSineMagnitude.Name = "UDSineMagnitude"; + UDSineMagnitude.Size = new System.Drawing.Size(96, 23); + UDSineMagnitude.TabIndex = 2; + UDSineMagnitude.Tag = "SineMagnitude"; + UDSineMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label6 + // + label6.AutoSize = true; + label6.Location = new System.Drawing.Point(6, 32); + label6.Name = "label6"; + label6.Size = new System.Drawing.Size(68, 15); + label6.TabIndex = 3; + label6.Tag = "InertiaMagnitude"; + label6.Text = "Magnitude:"; + // + // SliderSineMagnitude + // + SliderSineMagnitude.AccessibleName = "SliderSineMagnitude"; + SliderSineMagnitude.AutoSize = false; + SliderSineMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderSineMagnitude.Enabled = false; + SliderSineMagnitude.LargeChange = 50; + SliderSineMagnitude.Location = new System.Drawing.Point(74, 31); + SliderSineMagnitude.Maximum = 10000; + SliderSineMagnitude.Name = "SliderSineMagnitude"; + SliderSineMagnitude.Size = new System.Drawing.Size(221, 31); + SliderSineMagnitude.TabIndex = 0; + SliderSineMagnitude.Tag = "SineMagnitude"; + SliderSineMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSineMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBSquare + // + GBSquare.Controls.Add(checkBox5); + GBSquare.Controls.Add(UDSquareMagnitude); + GBSquare.Controls.Add(label5); + GBSquare.Controls.Add(SliderSquareMagnitude); + GBSquare.Location = new System.Drawing.Point(415, 568); + GBSquare.Name = "GBSquare"; + GBSquare.Size = new System.Drawing.Size(410, 71); + GBSquare.TabIndex = 5; + GBSquare.TabStop = false; + GBSquare.Tag = "Square"; + GBSquare.Text = " Square"; + // + // checkBox5 + // + checkBox5.AutoSize = true; + checkBox5.Location = new System.Drawing.Point(0, 3); + checkBox5.Name = "checkBox5"; + checkBox5.Size = new System.Drawing.Size(15, 14); + checkBox5.TabIndex = 1; + checkBox5.Tag = "Square"; + checkBox5.UseVisualStyleBackColor = true; + checkBox5.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDSquareMagnitude + // + UDSquareMagnitude.Enabled = false; + UDSquareMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSquareMagnitude.Location = new System.Drawing.Point(308, 32); + UDSquareMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSquareMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSquareMagnitude.Name = "UDSquareMagnitude"; + UDSquareMagnitude.Size = new System.Drawing.Size(96, 23); + UDSquareMagnitude.TabIndex = 2; + UDSquareMagnitude.Tag = "SquareMagnitude"; + UDSquareMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label5 + // + label5.AutoSize = true; + label5.Location = new System.Drawing.Point(6, 32); + label5.Name = "label5"; + label5.Size = new System.Drawing.Size(68, 15); + label5.TabIndex = 3; + label5.Tag = "InertiaMagnitude"; + label5.Text = "Magnitude:"; + // + // SliderSquareMagnitude + // + SliderSquareMagnitude.AccessibleName = "SliderSquareMagnitude"; + SliderSquareMagnitude.AutoSize = false; + SliderSquareMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderSquareMagnitude.Enabled = false; + SliderSquareMagnitude.LargeChange = 50; + SliderSquareMagnitude.Location = new System.Drawing.Point(80, 31); + SliderSquareMagnitude.Maximum = 10000; + SliderSquareMagnitude.Name = "SliderSquareMagnitude"; + SliderSquareMagnitude.Size = new System.Drawing.Size(222, 31); + SliderSquareMagnitude.TabIndex = 0; + SliderSquareMagnitude.Tag = "SquareMagnitude"; + SliderSquareMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSquareMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBTriangle + // + GBTriangle.Controls.Add(checkBox4); + GBTriangle.Controls.Add(UDTriangleMagnitude); + GBTriangle.Controls.Add(label4); + GBTriangle.Controls.Add(SliderTriangleMagnitude); + GBTriangle.Location = new System.Drawing.Point(831, 571); + GBTriangle.Name = "GBTriangle"; + GBTriangle.Size = new System.Drawing.Size(389, 68); + GBTriangle.TabIndex = 4; + GBTriangle.TabStop = false; + GBTriangle.Tag = "Triangle"; + GBTriangle.Text = " Triangle"; + // + // checkBox4 + // + checkBox4.AutoSize = true; + checkBox4.Location = new System.Drawing.Point(0, 3); + checkBox4.Name = "checkBox4"; + checkBox4.Size = new System.Drawing.Size(15, 14); + checkBox4.TabIndex = 1; + checkBox4.Tag = "Triangle"; + checkBox4.UseVisualStyleBackColor = true; + checkBox4.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDTriangleMagnitude + // + UDTriangleMagnitude.Enabled = false; + UDTriangleMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDTriangleMagnitude.Location = new System.Drawing.Point(287, 32); + UDTriangleMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDTriangleMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDTriangleMagnitude.Name = "UDTriangleMagnitude"; + UDTriangleMagnitude.Size = new System.Drawing.Size(96, 23); + UDTriangleMagnitude.TabIndex = 2; + UDTriangleMagnitude.Tag = "TriangleMagnitude"; + UDTriangleMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new System.Drawing.Point(6, 32); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(68, 15); + label4.TabIndex = 3; + label4.Tag = "InertiaMagnitude"; + label4.Text = "Magnitude:"; + // + // SliderTriangleMagnitude + // + SliderTriangleMagnitude.AccessibleName = "SliderTriangleMagnitude"; + SliderTriangleMagnitude.AutoSize = false; + SliderTriangleMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderTriangleMagnitude.Enabled = false; + SliderTriangleMagnitude.LargeChange = 50; + SliderTriangleMagnitude.Location = new System.Drawing.Point(80, 31); + SliderTriangleMagnitude.Maximum = 10000; + SliderTriangleMagnitude.Name = "SliderTriangleMagnitude"; + SliderTriangleMagnitude.Size = new System.Drawing.Size(201, 31); + SliderTriangleMagnitude.TabIndex = 0; + SliderTriangleMagnitude.Tag = "TriangleMagnitude"; + SliderTriangleMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderTriangleMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBRampForce + // + GBRampForce.Controls.Add(checkBox3); + GBRampForce.Controls.Add(UDRampForceMagnitude); + GBRampForce.Controls.Add(label3); + GBRampForce.Controls.Add(SliderRampForceMagnitude); + GBRampForce.Location = new System.Drawing.Point(415, 491); + GBRampForce.Name = "GBRampForce"; + GBRampForce.Size = new System.Drawing.Size(410, 71); + GBRampForce.TabIndex = 4; + GBRampForce.TabStop = false; + GBRampForce.Tag = "RampForce"; + GBRampForce.Text = " RampForce"; + // + // checkBox3 + // + checkBox3.AutoSize = true; + checkBox3.Location = new System.Drawing.Point(0, 3); + checkBox3.Name = "checkBox3"; + checkBox3.Size = new System.Drawing.Size(15, 14); + checkBox3.TabIndex = 1; + checkBox3.Tag = "RampForce"; + checkBox3.UseVisualStyleBackColor = true; + checkBox3.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDRampForceMagnitude + // + UDRampForceMagnitude.Enabled = false; + UDRampForceMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDRampForceMagnitude.Location = new System.Drawing.Point(301, 31); + UDRampForceMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDRampForceMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDRampForceMagnitude.Name = "UDRampForceMagnitude"; + UDRampForceMagnitude.Size = new System.Drawing.Size(96, 23); + UDRampForceMagnitude.TabIndex = 2; + UDRampForceMagnitude.Tag = "RampForceMagnitude"; + UDRampForceMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(6, 32); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(68, 15); + label3.TabIndex = 3; + label3.Tag = "InertiaMagnitude"; + label3.Text = "Magnitude:"; + // + // SliderRampForceMagnitude + // + SliderRampForceMagnitude.AccessibleName = "SliderRampForceMagnitude"; + SliderRampForceMagnitude.AutoSize = false; + SliderRampForceMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderRampForceMagnitude.Enabled = false; + SliderRampForceMagnitude.LargeChange = 50; + SliderRampForceMagnitude.Location = new System.Drawing.Point(74, 31); + SliderRampForceMagnitude.Maximum = 10000; + SliderRampForceMagnitude.Minimum = -10000; + SliderRampForceMagnitude.Name = "SliderRampForceMagnitude"; + SliderRampForceMagnitude.Size = new System.Drawing.Size(221, 31); + SliderRampForceMagnitude.TabIndex = 0; + SliderRampForceMagnitude.Tag = "RampForceMagnitude"; + SliderRampForceMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderRampForceMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBSawtoothUp + // + GBSawtoothUp.Controls.Add(checkBox2); + GBSawtoothUp.Controls.Add(UDSawtoothUpMagnitude); + GBSawtoothUp.Controls.Add(label2); + GBSawtoothUp.Controls.Add(SliderSawtoothUpMagnitude); + GBSawtoothUp.Location = new System.Drawing.Point(6, 491); + GBSawtoothUp.Name = "GBSawtoothUp"; + GBSawtoothUp.Size = new System.Drawing.Size(403, 71); + GBSawtoothUp.TabIndex = 4; + GBSawtoothUp.TabStop = false; + GBSawtoothUp.Tag = "SawtoothUp"; + GBSawtoothUp.Text = " SawtoothUp"; + // + // checkBox2 + // + checkBox2.AutoSize = true; + checkBox2.Location = new System.Drawing.Point(0, 3); + checkBox2.Name = "checkBox2"; + checkBox2.Size = new System.Drawing.Size(15, 14); + checkBox2.TabIndex = 1; + checkBox2.Tag = "SawtoothUp"; + checkBox2.UseVisualStyleBackColor = true; + checkBox2.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDSawtoothUpMagnitude + // + UDSawtoothUpMagnitude.Enabled = false; + UDSawtoothUpMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSawtoothUpMagnitude.Location = new System.Drawing.Point(301, 31); + UDSawtoothUpMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSawtoothUpMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSawtoothUpMagnitude.Name = "UDSawtoothUpMagnitude"; + UDSawtoothUpMagnitude.Size = new System.Drawing.Size(96, 23); + UDSawtoothUpMagnitude.TabIndex = 2; + UDSawtoothUpMagnitude.Tag = "SawtoothUpMagnitude"; + UDSawtoothUpMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(6, 32); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(68, 15); + label2.TabIndex = 3; + label2.Tag = "InertiaMagnitude"; + label2.Text = "Magnitude:"; + // + // SliderSawtoothUpMagnitude + // + SliderSawtoothUpMagnitude.AccessibleName = "SliderSawtoothUpMagnitude"; + SliderSawtoothUpMagnitude.AutoSize = false; + SliderSawtoothUpMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderSawtoothUpMagnitude.Enabled = false; + SliderSawtoothUpMagnitude.LargeChange = 50; + SliderSawtoothUpMagnitude.Location = new System.Drawing.Point(80, 31); + SliderSawtoothUpMagnitude.Maximum = 10000; + SliderSawtoothUpMagnitude.Name = "SliderSawtoothUpMagnitude"; + SliderSawtoothUpMagnitude.Size = new System.Drawing.Size(215, 31); + SliderSawtoothUpMagnitude.TabIndex = 0; + SliderSawtoothUpMagnitude.Tag = "SawtoothUpMagnitude"; + SliderSawtoothUpMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSawtoothUpMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBSawtoothDown + // + GBSawtoothDown.Controls.Add(checkBox1); + GBSawtoothDown.Controls.Add(UDSawtoothDownMagnitude); + GBSawtoothDown.Controls.Add(label1); + GBSawtoothDown.Controls.Add(SliderSawtoothDownMagnitude); + GBSawtoothDown.Location = new System.Drawing.Point(831, 494); + GBSawtoothDown.Name = "GBSawtoothDown"; + GBSawtoothDown.Size = new System.Drawing.Size(389, 68); + GBSawtoothDown.TabIndex = 1; + GBSawtoothDown.TabStop = false; + GBSawtoothDown.Tag = "SawtoothDown"; + GBSawtoothDown.Text = " SawtoothDown"; + // + // checkBox1 + // + checkBox1.AutoSize = true; + checkBox1.Location = new System.Drawing.Point(0, 3); + checkBox1.Name = "checkBox1"; + checkBox1.Size = new System.Drawing.Size(15, 14); + checkBox1.TabIndex = 1; + checkBox1.Tag = "SawtoothDown"; + checkBox1.UseVisualStyleBackColor = true; + checkBox1.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDSawtoothDownMagnitude + // + UDSawtoothDownMagnitude.Enabled = false; + UDSawtoothDownMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSawtoothDownMagnitude.Location = new System.Drawing.Point(287, 32); + UDSawtoothDownMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSawtoothDownMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSawtoothDownMagnitude.Name = "UDSawtoothDownMagnitude"; + UDSawtoothDownMagnitude.Size = new System.Drawing.Size(96, 23); + UDSawtoothDownMagnitude.TabIndex = 2; + UDSawtoothDownMagnitude.Tag = "SawtoothDownMagnitude"; + UDSawtoothDownMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(6, 32); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(68, 15); + label1.TabIndex = 3; + label1.Tag = "InertiaMagnitude"; + label1.Text = "Magnitude:"; + // + // SliderSawtoothDownMagnitude + // + SliderSawtoothDownMagnitude.AccessibleName = "SliderSawtoothDownMagnitude"; + SliderSawtoothDownMagnitude.AutoSize = false; + SliderSawtoothDownMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderSawtoothDownMagnitude.Enabled = false; + SliderSawtoothDownMagnitude.LargeChange = 50; + SliderSawtoothDownMagnitude.Location = new System.Drawing.Point(80, 31); + SliderSawtoothDownMagnitude.Maximum = 10000; + SliderSawtoothDownMagnitude.Name = "SliderSawtoothDownMagnitude"; + SliderSawtoothDownMagnitude.Size = new System.Drawing.Size(201, 31); + SliderSawtoothDownMagnitude.TabIndex = 0; + SliderSawtoothDownMagnitude.Tag = "SawtoothDownMagnitude"; + SliderSawtoothDownMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSawtoothDownMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBSpring + // + GBSpring.Controls.Add(CBSpring); + GBSpring.Controls.Add(UDSpringDeadband); + GBSpring.Controls.Add(UDSpringSaturation); + GBSpring.Controls.Add(UDSpringCoefficient); + GBSpring.Controls.Add(UDSpringOffset); + GBSpring.Controls.Add(SliderSpringDeadband); + GBSpring.Controls.Add(LabelSpringDeadband); + GBSpring.Controls.Add(SliderSpringSaturation); + GBSpring.Controls.Add(LabelSpringSaturation); + GBSpring.Controls.Add(SliderSpringCoefficient); + GBSpring.Controls.Add(LabelSpringCoefficient); + GBSpring.Controls.Add(SliderSpringOffset); + GBSpring.Controls.Add(LabelSpringOffset); + GBSpring.Location = new System.Drawing.Point(6, 80); + GBSpring.Name = "GBSpring"; + GBSpring.Size = new System.Drawing.Size(1214, 180); + GBSpring.TabIndex = 0; + GBSpring.TabStop = false; + GBSpring.Tag = "Spring"; + GBSpring.Text = " Spring Force"; + GBSpring.Click += FFB_GroupBox_Click; + // + // CBSpring + // + CBSpring.AutoSize = true; + CBSpring.Location = new System.Drawing.Point(0, 3); + CBSpring.Name = "CBSpring"; + CBSpring.Size = new System.Drawing.Size(15, 14); + CBSpring.TabIndex = 1; + CBSpring.Tag = "Spring"; + CBSpring.UseVisualStyleBackColor = true; + CBSpring.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDSpringDeadband + // + UDSpringDeadband.Enabled = false; + UDSpringDeadband.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSpringDeadband.Location = new System.Drawing.Point(1112, 141); + UDSpringDeadband.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSpringDeadband.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSpringDeadband.Name = "UDSpringDeadband"; + UDSpringDeadband.Size = new System.Drawing.Size(96, 23); + UDSpringDeadband.TabIndex = 2; + UDSpringDeadband.Tag = "SpringDeadband"; + UDSpringDeadband.ValueChanged += FFB_UpDown_ValueChanged; + // + // UDSpringSaturation + // + UDSpringSaturation.Enabled = false; + UDSpringSaturation.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSpringSaturation.Location = new System.Drawing.Point(1112, 104); + UDSpringSaturation.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSpringSaturation.Name = "UDSpringSaturation"; + UDSpringSaturation.Size = new System.Drawing.Size(96, 23); + UDSpringSaturation.TabIndex = 2; + UDSpringSaturation.Tag = "SpringSaturation"; + UDSpringSaturation.Value = new decimal(new int[] { 5000, 0, 0, 0 }); + UDSpringSaturation.ValueChanged += FFB_UpDown_ValueChanged; + // + // UDSpringCoefficient + // + UDSpringCoefficient.Enabled = false; + UDSpringCoefficient.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSpringCoefficient.Location = new System.Drawing.Point(1112, 67); + UDSpringCoefficient.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSpringCoefficient.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSpringCoefficient.Name = "UDSpringCoefficient"; + UDSpringCoefficient.Size = new System.Drawing.Size(96, 23); + UDSpringCoefficient.TabIndex = 2; + UDSpringCoefficient.Tag = "SpringCoefficient"; + UDSpringCoefficient.ValueChanged += FFB_UpDown_ValueChanged; + // + // UDSpringOffset + // + UDSpringOffset.Enabled = false; + UDSpringOffset.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDSpringOffset.Location = new System.Drawing.Point(1112, 30); + UDSpringOffset.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDSpringOffset.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDSpringOffset.Name = "UDSpringOffset"; + UDSpringOffset.Size = new System.Drawing.Size(96, 23); + UDSpringOffset.TabIndex = 2; + UDSpringOffset.Tag = "SpringOffset"; + UDSpringOffset.ValueChanged += FFB_UpDown_ValueChanged; + // + // SliderSpringDeadband + // + SliderSpringDeadband.AutoSize = false; + SliderSpringDeadband.BackColor = System.Drawing.SystemColors.Control; + SliderSpringDeadband.Enabled = false; + SliderSpringDeadband.LargeChange = 50; + SliderSpringDeadband.Location = new System.Drawing.Point(108, 141); + SliderSpringDeadband.Maximum = 10000; + SliderSpringDeadband.Name = "SliderSpringDeadband"; + SliderSpringDeadband.Size = new System.Drawing.Size(998, 31); + SliderSpringDeadband.TabIndex = 0; + SliderSpringDeadband.Tag = "SpringDeadband"; + SliderSpringDeadband.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSpringDeadband.Scroll += FFB_Slider_Scroll; + // + // LabelSpringDeadband + // + LabelSpringDeadband.AutoSize = true; + LabelSpringDeadband.Location = new System.Drawing.Point(6, 143); + LabelSpringDeadband.Name = "LabelSpringDeadband"; + LabelSpringDeadband.Size = new System.Drawing.Size(64, 15); + LabelSpringDeadband.TabIndex = 3; + LabelSpringDeadband.Tag = "SpringDeadband"; + LabelSpringDeadband.Text = "Deadband:"; + LabelSpringDeadband.Click += FFB_Label_Click; + // + // SliderSpringSaturation + // + SliderSpringSaturation.AutoSize = false; + SliderSpringSaturation.BackColor = System.Drawing.SystemColors.Control; + SliderSpringSaturation.Enabled = false; + SliderSpringSaturation.LargeChange = 50; + SliderSpringSaturation.Location = new System.Drawing.Point(108, 104); + SliderSpringSaturation.Maximum = 10000; + SliderSpringSaturation.Name = "SliderSpringSaturation"; + SliderSpringSaturation.Size = new System.Drawing.Size(998, 31); + SliderSpringSaturation.TabIndex = 0; + SliderSpringSaturation.Tag = "SpringSaturation"; + SliderSpringSaturation.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSpringSaturation.Value = 5000; + SliderSpringSaturation.Scroll += FFB_Slider_Scroll; + // + // LabelSpringSaturation + // + LabelSpringSaturation.AutoSize = true; + LabelSpringSaturation.Location = new System.Drawing.Point(6, 106); + LabelSpringSaturation.Name = "LabelSpringSaturation"; + LabelSpringSaturation.Size = new System.Drawing.Size(64, 15); + LabelSpringSaturation.TabIndex = 3; + LabelSpringSaturation.Tag = "SpringSaturation"; + LabelSpringSaturation.Text = "Saturation:"; + LabelSpringSaturation.Click += FFB_Label_Click; + // + // SliderSpringCoefficient + // + SliderSpringCoefficient.AutoSize = false; + SliderSpringCoefficient.BackColor = System.Drawing.SystemColors.Control; + SliderSpringCoefficient.Enabled = false; + SliderSpringCoefficient.LargeChange = 50; + SliderSpringCoefficient.Location = new System.Drawing.Point(108, 67); + SliderSpringCoefficient.Maximum = 10000; + SliderSpringCoefficient.Minimum = -10000; + SliderSpringCoefficient.Name = "SliderSpringCoefficient"; + SliderSpringCoefficient.Size = new System.Drawing.Size(998, 31); + SliderSpringCoefficient.TabIndex = 0; + SliderSpringCoefficient.Tag = "SpringCoefficient"; + SliderSpringCoefficient.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSpringCoefficient.Scroll += FFB_Slider_Scroll; + // + // LabelSpringCoefficient + // + LabelSpringCoefficient.AutoSize = true; + LabelSpringCoefficient.Location = new System.Drawing.Point(6, 69); + LabelSpringCoefficient.Name = "LabelSpringCoefficient"; + LabelSpringCoefficient.Size = new System.Drawing.Size(68, 15); + LabelSpringCoefficient.TabIndex = 3; + LabelSpringCoefficient.Tag = "SpringCoefficient"; + LabelSpringCoefficient.Text = "Coefficient:"; + LabelSpringCoefficient.Click += FFB_Label_Click; + // + // SliderSpringOffset + // + SliderSpringOffset.AutoSize = false; + SliderSpringOffset.BackColor = System.Drawing.SystemColors.Control; + SliderSpringOffset.Enabled = false; + SliderSpringOffset.LargeChange = 50; + SliderSpringOffset.Location = new System.Drawing.Point(108, 30); + SliderSpringOffset.Maximum = 10000; + SliderSpringOffset.Minimum = -10000; + SliderSpringOffset.Name = "SliderSpringOffset"; + SliderSpringOffset.Size = new System.Drawing.Size(998, 31); + SliderSpringOffset.TabIndex = 0; + SliderSpringOffset.Tag = "SpringOffset"; + SliderSpringOffset.TickStyle = System.Windows.Forms.TickStyle.None; + SliderSpringOffset.Scroll += FFB_Slider_Scroll; + // + // LabelSpringOffset + // + LabelSpringOffset.AutoSize = true; + LabelSpringOffset.Location = new System.Drawing.Point(6, 32); + LabelSpringOffset.Name = "LabelSpringOffset"; + LabelSpringOffset.Size = new System.Drawing.Size(42, 15); + LabelSpringOffset.TabIndex = 3; + LabelSpringOffset.Tag = "SpringOffset"; + LabelSpringOffset.Text = "Offset:"; + LabelSpringOffset.Click += FFB_Label_Click; + // + // GBInertia + // + GBInertia.Controls.Add(CBInertia); + GBInertia.Controls.Add(UDInertiaMagnitude); + GBInertia.Controls.Add(LabelInertiaMagnitude); + GBInertia.Controls.Add(SliderInertiaMagnitude); + GBInertia.Location = new System.Drawing.Point(6, 414); + GBInertia.Name = "GBInertia"; + GBInertia.Size = new System.Drawing.Size(1214, 68); + GBInertia.TabIndex = 0; + GBInertia.TabStop = false; + GBInertia.Tag = "Inertia"; + GBInertia.Text = " Inertia"; + GBInertia.Click += FFB_GroupBox_Click; + // + // CBInertia + // + CBInertia.AutoSize = true; + CBInertia.Location = new System.Drawing.Point(0, 3); + CBInertia.Name = "CBInertia"; + CBInertia.Size = new System.Drawing.Size(15, 14); + CBInertia.TabIndex = 1; + CBInertia.Tag = "Inertia"; + CBInertia.UseVisualStyleBackColor = true; + CBInertia.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDInertiaMagnitude + // + UDInertiaMagnitude.Enabled = false; + UDInertiaMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDInertiaMagnitude.Location = new System.Drawing.Point(1112, 30); + UDInertiaMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDInertiaMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDInertiaMagnitude.Name = "UDInertiaMagnitude"; + UDInertiaMagnitude.Size = new System.Drawing.Size(96, 23); + UDInertiaMagnitude.TabIndex = 2; + UDInertiaMagnitude.Tag = "InertiaMagnitude"; + UDInertiaMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // LabelInertiaMagnitude + // + LabelInertiaMagnitude.AutoSize = true; + LabelInertiaMagnitude.Location = new System.Drawing.Point(6, 32); + LabelInertiaMagnitude.Name = "LabelInertiaMagnitude"; + LabelInertiaMagnitude.Size = new System.Drawing.Size(68, 15); + LabelInertiaMagnitude.TabIndex = 3; + LabelInertiaMagnitude.Tag = "InertiaMagnitude"; + LabelInertiaMagnitude.Text = "Magnitude:"; + LabelInertiaMagnitude.Click += FFB_Label_Click; + // + // SliderInertiaMagnitude + // + SliderInertiaMagnitude.AutoSize = false; + SliderInertiaMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderInertiaMagnitude.Enabled = false; + SliderInertiaMagnitude.LargeChange = 50; + SliderInertiaMagnitude.Location = new System.Drawing.Point(108, 30); + SliderInertiaMagnitude.Maximum = 10000; + SliderInertiaMagnitude.Minimum = -10000; + SliderInertiaMagnitude.Name = "SliderInertiaMagnitude"; + SliderInertiaMagnitude.Size = new System.Drawing.Size(998, 31); + SliderInertiaMagnitude.TabIndex = 0; + SliderInertiaMagnitude.Tag = "InertiaMagnitude"; + SliderInertiaMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderInertiaMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBFriction + // + GBFriction.Controls.Add(UDFrictionMagnitude); + GBFriction.Controls.Add(CBFriction); + GBFriction.Controls.Add(LabelFrictionMagnitude); + GBFriction.Controls.Add(SliderFrictionMagnitude); + GBFriction.Location = new System.Drawing.Point(6, 340); + GBFriction.Name = "GBFriction"; + GBFriction.Size = new System.Drawing.Size(1214, 68); + GBFriction.TabIndex = 0; + GBFriction.TabStop = false; + GBFriction.Tag = "Friction"; + GBFriction.Text = " Friction"; + GBFriction.Click += FFB_GroupBox_Click; + // + // UDFrictionMagnitude + // + UDFrictionMagnitude.Enabled = false; + UDFrictionMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDFrictionMagnitude.Location = new System.Drawing.Point(1112, 30); + UDFrictionMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDFrictionMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDFrictionMagnitude.Name = "UDFrictionMagnitude"; + UDFrictionMagnitude.Size = new System.Drawing.Size(96, 23); + UDFrictionMagnitude.TabIndex = 2; + UDFrictionMagnitude.Tag = "FrictionMagnitude"; + UDFrictionMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // CBFriction + // + CBFriction.AutoSize = true; + CBFriction.Location = new System.Drawing.Point(0, 3); + CBFriction.Name = "CBFriction"; + CBFriction.Size = new System.Drawing.Size(15, 14); + CBFriction.TabIndex = 1; + CBFriction.Tag = "Friction"; + CBFriction.UseVisualStyleBackColor = true; + CBFriction.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // LabelFrictionMagnitude + // + LabelFrictionMagnitude.AutoSize = true; + LabelFrictionMagnitude.Location = new System.Drawing.Point(6, 32); + LabelFrictionMagnitude.Name = "LabelFrictionMagnitude"; + LabelFrictionMagnitude.Size = new System.Drawing.Size(68, 15); + LabelFrictionMagnitude.TabIndex = 3; + LabelFrictionMagnitude.Tag = "FrictionMagnitude"; + LabelFrictionMagnitude.Text = "Magnitude:"; + LabelFrictionMagnitude.Click += FFB_Label_Click; + // + // SliderFrictionMagnitude + // + SliderFrictionMagnitude.AutoSize = false; + SliderFrictionMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderFrictionMagnitude.Enabled = false; + SliderFrictionMagnitude.LargeChange = 50; + SliderFrictionMagnitude.Location = new System.Drawing.Point(108, 30); + SliderFrictionMagnitude.Maximum = 10000; + SliderFrictionMagnitude.Minimum = -10000; + SliderFrictionMagnitude.Name = "SliderFrictionMagnitude"; + SliderFrictionMagnitude.Size = new System.Drawing.Size(998, 31); + SliderFrictionMagnitude.TabIndex = 0; + SliderFrictionMagnitude.Tag = "FrictionMagnitude"; + SliderFrictionMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderFrictionMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBDamper + // + GBDamper.Controls.Add(UDDamperMagnitude); + GBDamper.Controls.Add(LabelDamperMagnitude); + GBDamper.Controls.Add(CBDamper); + GBDamper.Controls.Add(SliderDamperMagnitude); + GBDamper.Location = new System.Drawing.Point(6, 266); + GBDamper.Name = "GBDamper"; + GBDamper.Size = new System.Drawing.Size(1214, 68); + GBDamper.TabIndex = 0; + GBDamper.TabStop = false; + GBDamper.Tag = "Damper"; + GBDamper.Text = " Damper"; + GBDamper.Click += FFB_GroupBox_Click; + // + // UDDamperMagnitude + // + UDDamperMagnitude.Enabled = false; + UDDamperMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDDamperMagnitude.Location = new System.Drawing.Point(1112, 30); + UDDamperMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDDamperMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDDamperMagnitude.Name = "UDDamperMagnitude"; + UDDamperMagnitude.Size = new System.Drawing.Size(96, 23); + UDDamperMagnitude.TabIndex = 2; + UDDamperMagnitude.Tag = "DamperMagnitude"; + UDDamperMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // LabelDamperMagnitude + // + LabelDamperMagnitude.AutoSize = true; + LabelDamperMagnitude.Location = new System.Drawing.Point(6, 32); + LabelDamperMagnitude.Name = "LabelDamperMagnitude"; + LabelDamperMagnitude.Size = new System.Drawing.Size(68, 15); + LabelDamperMagnitude.TabIndex = 3; + LabelDamperMagnitude.Tag = "DamperMagnitude"; + LabelDamperMagnitude.Text = "Magnitude:"; + LabelDamperMagnitude.Click += FFB_Label_Click; + // + // CBDamper + // + CBDamper.AutoSize = true; + CBDamper.Location = new System.Drawing.Point(0, 3); + CBDamper.Name = "CBDamper"; + CBDamper.Size = new System.Drawing.Size(15, 14); + CBDamper.TabIndex = 1; + CBDamper.Tag = "Damper"; + CBDamper.UseVisualStyleBackColor = true; + CBDamper.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // SliderDamperMagnitude + // + SliderDamperMagnitude.AutoSize = false; + SliderDamperMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderDamperMagnitude.Enabled = false; + SliderDamperMagnitude.LargeChange = 50; + SliderDamperMagnitude.Location = new System.Drawing.Point(108, 30); + SliderDamperMagnitude.Maximum = 10000; + SliderDamperMagnitude.Minimum = -10000; + SliderDamperMagnitude.Name = "SliderDamperMagnitude"; + SliderDamperMagnitude.Size = new System.Drawing.Size(998, 31); + SliderDamperMagnitude.TabIndex = 0; + SliderDamperMagnitude.Tag = "DamperMagnitude"; + SliderDamperMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderDamperMagnitude.Scroll += FFB_Slider_Scroll; + // + // GBConstantForce + // + GBConstantForce.Controls.Add(CBConstantForce); + GBConstantForce.Controls.Add(UDConstantForceMagnitude); + GBConstantForce.Controls.Add(LabelConstantForceMagnitude); + GBConstantForce.Controls.Add(SliderConstantForceMagnitude); + GBConstantForce.Location = new System.Drawing.Point(6, 6); + GBConstantForce.Name = "GBConstantForce"; + GBConstantForce.Size = new System.Drawing.Size(1214, 68); + GBConstantForce.TabIndex = 0; + GBConstantForce.TabStop = false; + GBConstantForce.Tag = "ConstantForce"; + GBConstantForce.Text = " Constant Force"; + GBConstantForce.Click += FFB_GroupBox_Click; + // + // CBConstantForce + // + CBConstantForce.AutoSize = true; + CBConstantForce.Location = new System.Drawing.Point(0, 3); + CBConstantForce.Name = "CBConstantForce"; + CBConstantForce.Size = new System.Drawing.Size(15, 14); + CBConstantForce.TabIndex = 1; + CBConstantForce.Tag = "ConstantForce"; + CBConstantForce.UseVisualStyleBackColor = true; + CBConstantForce.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDConstantForceMagnitude + // + UDConstantForceMagnitude.Enabled = false; + UDConstantForceMagnitude.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDConstantForceMagnitude.Location = new System.Drawing.Point(1112, 30); + UDConstantForceMagnitude.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDConstantForceMagnitude.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDConstantForceMagnitude.Name = "UDConstantForceMagnitude"; + UDConstantForceMagnitude.Size = new System.Drawing.Size(96, 23); + UDConstantForceMagnitude.TabIndex = 2; + UDConstantForceMagnitude.Tag = "ConstantForceMagnitude"; + UDConstantForceMagnitude.ValueChanged += FFB_UpDown_ValueChanged; + // + // LabelConstantForceMagnitude + // + LabelConstantForceMagnitude.AutoSize = true; + LabelConstantForceMagnitude.Location = new System.Drawing.Point(6, 32); + LabelConstantForceMagnitude.Name = "LabelConstantForceMagnitude"; + LabelConstantForceMagnitude.Size = new System.Drawing.Size(68, 15); + LabelConstantForceMagnitude.TabIndex = 3; + LabelConstantForceMagnitude.Tag = "ConstantForceMagnitude"; + LabelConstantForceMagnitude.Text = "Magnitude:"; + LabelConstantForceMagnitude.Click += FFB_Label_Click; + // + // SliderConstantForceMagnitude + // + SliderConstantForceMagnitude.AutoSize = false; + SliderConstantForceMagnitude.BackColor = System.Drawing.SystemColors.Control; + SliderConstantForceMagnitude.Enabled = false; + SliderConstantForceMagnitude.LargeChange = 50; + SliderConstantForceMagnitude.Location = new System.Drawing.Point(108, 30); + SliderConstantForceMagnitude.Maximum = 10000; + SliderConstantForceMagnitude.Minimum = -10000; + SliderConstantForceMagnitude.Name = "SliderConstantForceMagnitude"; + SliderConstantForceMagnitude.Size = new System.Drawing.Size(998, 31); + SliderConstantForceMagnitude.TabIndex = 0; + SliderConstantForceMagnitude.Tag = "ConstantForceMagnitude"; + SliderConstantForceMagnitude.TickStyle = System.Windows.Forms.TickStyle.None; + SliderConstantForceMagnitude.Scroll += FFB_Slider_Scroll; + // + // tabPage1 + // + tabPage1.Controls.Add(GBCuss); + tabPage1.Location = new System.Drawing.Point(4, 24); + tabPage1.Name = "tabPage1"; + tabPage1.Padding = new System.Windows.Forms.Padding(3); + tabPage1.Size = new System.Drawing.Size(1226, 637); + tabPage1.TabIndex = 5; + tabPage1.Text = "custom forces"; + tabPage1.UseVisualStyleBackColor = true; + // + // GBCuss + // + GBCuss.Controls.Add(UDCustomForceSamplePeriod); + GBCuss.Controls.Add(label16); + GBCuss.Controls.Add(SliderCustomForceSamplePeriod); + GBCuss.Controls.Add(UDCustomForceMagnitude9); + GBCuss.Controls.Add(label15); + GBCuss.Controls.Add(SliderCustomForceMagnitude9); + GBCuss.Controls.Add(UDCustomForceMagnitude8); + GBCuss.Controls.Add(label14); + GBCuss.Controls.Add(SliderCustomForceMagnitude8); + GBCuss.Controls.Add(UDCustomForceMagnitude7); + GBCuss.Controls.Add(label13); + GBCuss.Controls.Add(SliderCustomForceMagnitude7); + GBCuss.Controls.Add(UDCustomForceMagnitude6); + GBCuss.Controls.Add(label12); + GBCuss.Controls.Add(SliderCustomForceMagnitude6); + GBCuss.Controls.Add(UDCustomForceMagnitude5); + GBCuss.Controls.Add(label11); + GBCuss.Controls.Add(SliderCustomForceMagnitude5); + GBCuss.Controls.Add(UDCustomForceMagnitude4); + GBCuss.Controls.Add(label10); + GBCuss.Controls.Add(SliderCustomForceMagnitude4); + GBCuss.Controls.Add(UDCustomForceMagnitude3); + GBCuss.Controls.Add(label9); + GBCuss.Controls.Add(SliderCustomForceMagnitude3); + GBCuss.Controls.Add(UDCustomForceMagnitude2); + GBCuss.Controls.Add(label8); + GBCuss.Controls.Add(SliderCustomForceMagnitude2); + GBCuss.Controls.Add(UDCustomForceMagnitude1); + GBCuss.Controls.Add(label7); + GBCuss.Controls.Add(SliderCustomForceMagnitude1); + GBCuss.Controls.Add(CBCustomForce); + GBCuss.Controls.Add(UDCustomForceMagnitude0); + GBCuss.Controls.Add(LblCustomForceMagnitude0); + GBCuss.Controls.Add(SliderCustomForceMagnitude0); + GBCuss.Location = new System.Drawing.Point(6, 22); + GBCuss.Name = "GBCuss"; + GBCuss.Size = new System.Drawing.Size(1214, 609); + GBCuss.TabIndex = 1; + GBCuss.TabStop = false; + GBCuss.Tag = "CustomForce"; + GBCuss.Text = " CustomForce"; + // + // UDCustomForceSamplePeriod + // + UDCustomForceSamplePeriod.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceSamplePeriod.Enabled = false; + UDCustomForceSamplePeriod.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceSamplePeriod.Location = new System.Drawing.Point(1112, 553); + UDCustomForceSamplePeriod.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceSamplePeriod.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceSamplePeriod.Name = "UDCustomForceSamplePeriod"; + UDCustomForceSamplePeriod.Size = new System.Drawing.Size(96, 23); + UDCustomForceSamplePeriod.TabIndex = 32; + UDCustomForceSamplePeriod.Tag = "CustomForceMagnitude"; + UDCustomForceSamplePeriod.ValueChanged += FFB_UpDown_ValueChanged; + // + // label16 + // + label16.AutoSize = true; + label16.Location = new System.Drawing.Point(6, 555); + label16.Name = "label16"; + label16.Size = new System.Drawing.Size(86, 15); + label16.TabIndex = 33; + label16.Tag = "CustomForceMag"; + label16.Text = "Sample Period:"; + // + // SliderCustomForceSamplePeriod + // + SliderCustomForceSamplePeriod.AutoSize = false; + SliderCustomForceSamplePeriod.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceSamplePeriod.Enabled = false; + SliderCustomForceSamplePeriod.LargeChange = 50; + SliderCustomForceSamplePeriod.Location = new System.Drawing.Point(108, 553); + SliderCustomForceSamplePeriod.Maximum = 10000; + SliderCustomForceSamplePeriod.Minimum = 1000; + SliderCustomForceSamplePeriod.Name = "SliderCustomForceSamplePeriod"; + SliderCustomForceSamplePeriod.Size = new System.Drawing.Size(998, 31); + SliderCustomForceSamplePeriod.TabIndex = 31; + SliderCustomForceSamplePeriod.Tag = "CustomForceMagnitude"; + SliderCustomForceSamplePeriod.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceSamplePeriod.Value = 1000; + SliderCustomForceSamplePeriod.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude9 + // + UDCustomForceMagnitude9.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude9.Enabled = false; + UDCustomForceMagnitude9.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude9.Location = new System.Drawing.Point(1112, 487); + UDCustomForceMagnitude9.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude9.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude9.Name = "UDCustomForceMagnitude9"; + UDCustomForceMagnitude9.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude9.TabIndex = 29; + UDCustomForceMagnitude9.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude9.ValueChanged += FFB_UpDown_ValueChanged; + // + // label15 + // + label15.AccessibleName = "LblCustomForceMagnitude0"; + label15.AutoSize = true; + label15.Location = new System.Drawing.Point(6, 489); + label15.Name = "label15"; + label15.Size = new System.Drawing.Size(68, 15); + label15.TabIndex = 30; + label15.Tag = "LblCustomForceMag0"; + label15.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude9 + // + SliderCustomForceMagnitude9.AutoSize = false; + SliderCustomForceMagnitude9.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude9.Enabled = false; + SliderCustomForceMagnitude9.LargeChange = 50; + SliderCustomForceMagnitude9.Location = new System.Drawing.Point(108, 487); + SliderCustomForceMagnitude9.Maximum = 10000; + SliderCustomForceMagnitude9.Minimum = -10000; + SliderCustomForceMagnitude9.Name = "SliderCustomForceMagnitude9"; + SliderCustomForceMagnitude9.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude9.TabIndex = 28; + SliderCustomForceMagnitude9.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude9.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude9.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude8 + // + UDCustomForceMagnitude8.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude8.Enabled = false; + UDCustomForceMagnitude8.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude8.Location = new System.Drawing.Point(1112, 433); + UDCustomForceMagnitude8.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude8.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude8.Name = "UDCustomForceMagnitude8"; + UDCustomForceMagnitude8.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude8.TabIndex = 26; + UDCustomForceMagnitude8.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude8.ValueChanged += FFB_UpDown_ValueChanged; + // + // label14 + // + label14.AccessibleName = "LblCustomForceMagnitude0"; + label14.AutoSize = true; + label14.Location = new System.Drawing.Point(6, 435); + label14.Name = "label14"; + label14.Size = new System.Drawing.Size(68, 15); + label14.TabIndex = 27; + label14.Tag = "LblCustomForceMag0"; + label14.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude8 + // + SliderCustomForceMagnitude8.AutoSize = false; + SliderCustomForceMagnitude8.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude8.Enabled = false; + SliderCustomForceMagnitude8.LargeChange = 50; + SliderCustomForceMagnitude8.Location = new System.Drawing.Point(108, 433); + SliderCustomForceMagnitude8.Maximum = 10000; + SliderCustomForceMagnitude8.Minimum = -10000; + SliderCustomForceMagnitude8.Name = "SliderCustomForceMagnitude8"; + SliderCustomForceMagnitude8.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude8.TabIndex = 25; + SliderCustomForceMagnitude8.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude8.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude8.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude7 + // + UDCustomForceMagnitude7.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude7.Enabled = false; + UDCustomForceMagnitude7.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude7.Location = new System.Drawing.Point(1112, 380); + UDCustomForceMagnitude7.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude7.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude7.Name = "UDCustomForceMagnitude7"; + UDCustomForceMagnitude7.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude7.TabIndex = 23; + UDCustomForceMagnitude7.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude7.ValueChanged += FFB_UpDown_ValueChanged; + // + // label13 + // + label13.AccessibleName = "LblCustomForceMagnitude0"; + label13.AutoSize = true; + label13.Location = new System.Drawing.Point(6, 382); + label13.Name = "label13"; + label13.Size = new System.Drawing.Size(68, 15); + label13.TabIndex = 24; + label13.Tag = "LblCustomForceMag0"; + label13.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude7 + // + SliderCustomForceMagnitude7.AutoSize = false; + SliderCustomForceMagnitude7.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude7.Enabled = false; + SliderCustomForceMagnitude7.LargeChange = 50; + SliderCustomForceMagnitude7.Location = new System.Drawing.Point(108, 380); + SliderCustomForceMagnitude7.Maximum = 10000; + SliderCustomForceMagnitude7.Minimum = -10000; + SliderCustomForceMagnitude7.Name = "SliderCustomForceMagnitude7"; + SliderCustomForceMagnitude7.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude7.TabIndex = 22; + SliderCustomForceMagnitude7.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude7.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude7.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude6 + // + UDCustomForceMagnitude6.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude6.Enabled = false; + UDCustomForceMagnitude6.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude6.Location = new System.Drawing.Point(1112, 328); + UDCustomForceMagnitude6.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude6.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude6.Name = "UDCustomForceMagnitude6"; + UDCustomForceMagnitude6.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude6.TabIndex = 20; + UDCustomForceMagnitude6.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude6.ValueChanged += FFB_UpDown_ValueChanged; + // + // label12 + // + label12.AccessibleName = "LblCustomForceMagnitude0"; + label12.AutoSize = true; + label12.Location = new System.Drawing.Point(6, 330); + label12.Name = "label12"; + label12.Size = new System.Drawing.Size(68, 15); + label12.TabIndex = 21; + label12.Tag = "LblCustomForceMag0"; + label12.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude6 + // + SliderCustomForceMagnitude6.AutoSize = false; + SliderCustomForceMagnitude6.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude6.Enabled = false; + SliderCustomForceMagnitude6.LargeChange = 50; + SliderCustomForceMagnitude6.Location = new System.Drawing.Point(108, 328); + SliderCustomForceMagnitude6.Maximum = 10000; + SliderCustomForceMagnitude6.Minimum = -10000; + SliderCustomForceMagnitude6.Name = "SliderCustomForceMagnitude6"; + SliderCustomForceMagnitude6.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude6.TabIndex = 19; + SliderCustomForceMagnitude6.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude6.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude6.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude5 + // + UDCustomForceMagnitude5.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude5.Enabled = false; + UDCustomForceMagnitude5.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude5.Location = new System.Drawing.Point(1112, 276); + UDCustomForceMagnitude5.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude5.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude5.Name = "UDCustomForceMagnitude5"; + UDCustomForceMagnitude5.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude5.TabIndex = 17; + UDCustomForceMagnitude5.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude5.ValueChanged += FFB_UpDown_ValueChanged; + // + // label11 + // + label11.AccessibleName = "LblCustomForceMagnitude0"; + label11.AutoSize = true; + label11.Location = new System.Drawing.Point(6, 278); + label11.Name = "label11"; + label11.Size = new System.Drawing.Size(68, 15); + label11.TabIndex = 18; + label11.Tag = "LblCustomForceMag0"; + label11.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude5 + // + SliderCustomForceMagnitude5.AutoSize = false; + SliderCustomForceMagnitude5.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude5.Enabled = false; + SliderCustomForceMagnitude5.LargeChange = 50; + SliderCustomForceMagnitude5.Location = new System.Drawing.Point(108, 276); + SliderCustomForceMagnitude5.Maximum = 10000; + SliderCustomForceMagnitude5.Minimum = -10000; + SliderCustomForceMagnitude5.Name = "SliderCustomForceMagnitude5"; + SliderCustomForceMagnitude5.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude5.TabIndex = 16; + SliderCustomForceMagnitude5.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude5.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude5.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude4 + // + UDCustomForceMagnitude4.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude4.Enabled = false; + UDCustomForceMagnitude4.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude4.Location = new System.Drawing.Point(1112, 226); + UDCustomForceMagnitude4.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude4.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude4.Name = "UDCustomForceMagnitude4"; + UDCustomForceMagnitude4.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude4.TabIndex = 14; + UDCustomForceMagnitude4.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude4.ValueChanged += FFB_UpDown_ValueChanged; + // + // label10 + // + label10.AccessibleName = "LblCustomForceMagnitude0"; + label10.AutoSize = true; + label10.Location = new System.Drawing.Point(6, 228); + label10.Name = "label10"; + label10.Size = new System.Drawing.Size(68, 15); + label10.TabIndex = 15; + label10.Tag = "LblCustomForceMag0"; + label10.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude4 + // + SliderCustomForceMagnitude4.AutoSize = false; + SliderCustomForceMagnitude4.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude4.Enabled = false; + SliderCustomForceMagnitude4.LargeChange = 50; + SliderCustomForceMagnitude4.Location = new System.Drawing.Point(108, 226); + SliderCustomForceMagnitude4.Maximum = 10000; + SliderCustomForceMagnitude4.Minimum = -10000; + SliderCustomForceMagnitude4.Name = "SliderCustomForceMagnitude4"; + SliderCustomForceMagnitude4.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude4.TabIndex = 13; + SliderCustomForceMagnitude4.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude4.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude4.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude3 + // + UDCustomForceMagnitude3.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude3.Enabled = false; + UDCustomForceMagnitude3.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude3.Location = new System.Drawing.Point(1112, 179); + UDCustomForceMagnitude3.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude3.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude3.Name = "UDCustomForceMagnitude3"; + UDCustomForceMagnitude3.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude3.TabIndex = 11; + UDCustomForceMagnitude3.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude3.ValueChanged += FFB_UpDown_ValueChanged; + // + // label9 + // + label9.AccessibleName = "LblCustomForceMagnitude0"; + label9.AutoSize = true; + label9.Location = new System.Drawing.Point(6, 181); + label9.Name = "label9"; + label9.Size = new System.Drawing.Size(68, 15); + label9.TabIndex = 12; + label9.Tag = "LblCustomForceMag0"; + label9.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude3 + // + SliderCustomForceMagnitude3.AutoSize = false; + SliderCustomForceMagnitude3.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude3.Enabled = false; + SliderCustomForceMagnitude3.LargeChange = 50; + SliderCustomForceMagnitude3.Location = new System.Drawing.Point(108, 179); + SliderCustomForceMagnitude3.Maximum = 10000; + SliderCustomForceMagnitude3.Minimum = -10000; + SliderCustomForceMagnitude3.Name = "SliderCustomForceMagnitude3"; + SliderCustomForceMagnitude3.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude3.TabIndex = 10; + SliderCustomForceMagnitude3.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude3.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude3.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude2 + // + UDCustomForceMagnitude2.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude2.Enabled = false; + UDCustomForceMagnitude2.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude2.Location = new System.Drawing.Point(1112, 129); + UDCustomForceMagnitude2.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude2.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude2.Name = "UDCustomForceMagnitude2"; + UDCustomForceMagnitude2.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude2.TabIndex = 8; + UDCustomForceMagnitude2.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude2.ValueChanged += FFB_UpDown_ValueChanged; + // + // label8 + // + label8.AccessibleName = "LblCustomForceMagnitude0"; + label8.AutoSize = true; + label8.Location = new System.Drawing.Point(6, 131); + label8.Name = "label8"; + label8.Size = new System.Drawing.Size(68, 15); + label8.TabIndex = 9; + label8.Tag = "LblCustomForceMag0"; + label8.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude2 + // + SliderCustomForceMagnitude2.AutoSize = false; + SliderCustomForceMagnitude2.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude2.Enabled = false; + SliderCustomForceMagnitude2.LargeChange = 50; + SliderCustomForceMagnitude2.Location = new System.Drawing.Point(108, 129); + SliderCustomForceMagnitude2.Maximum = 10000; + SliderCustomForceMagnitude2.Minimum = -10000; + SliderCustomForceMagnitude2.Name = "SliderCustomForceMagnitude2"; + SliderCustomForceMagnitude2.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude2.TabIndex = 7; + SliderCustomForceMagnitude2.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude2.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude2.Scroll += FFB_Slider_Scroll; + // + // UDCustomForceMagnitude1 + // + UDCustomForceMagnitude1.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude1.Enabled = false; + UDCustomForceMagnitude1.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude1.Location = new System.Drawing.Point(1112, 80); + UDCustomForceMagnitude1.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude1.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude1.Name = "UDCustomForceMagnitude1"; + UDCustomForceMagnitude1.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude1.TabIndex = 5; + UDCustomForceMagnitude1.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude1.ValueChanged += FFB_UpDown_ValueChanged; + // + // label7 + // + label7.AccessibleName = "LblCustomForceMagnitude0"; + label7.AutoSize = true; + label7.Location = new System.Drawing.Point(6, 82); + label7.Name = "label7"; + label7.Size = new System.Drawing.Size(68, 15); + label7.TabIndex = 6; + label7.Tag = "LblCustomForceMag0"; + label7.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude1 + // + SliderCustomForceMagnitude1.AutoSize = false; + SliderCustomForceMagnitude1.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude1.Enabled = false; + SliderCustomForceMagnitude1.LargeChange = 50; + SliderCustomForceMagnitude1.Location = new System.Drawing.Point(108, 80); + SliderCustomForceMagnitude1.Maximum = 10000; + SliderCustomForceMagnitude1.Minimum = -10000; + SliderCustomForceMagnitude1.Name = "SliderCustomForceMagnitude1"; + SliderCustomForceMagnitude1.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude1.TabIndex = 4; + SliderCustomForceMagnitude1.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude1.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude1.Scroll += FFB_Slider_Scroll; + // + // CBCustomForce + // + CBCustomForce.AutoSize = true; + CBCustomForce.Location = new System.Drawing.Point(0, 3); + CBCustomForce.Name = "CBCustomForce"; + CBCustomForce.Size = new System.Drawing.Size(15, 14); + CBCustomForce.TabIndex = 1; + CBCustomForce.Tag = "CustomForce"; + CBCustomForce.UseVisualStyleBackColor = true; + CBCustomForce.CheckedChanged += FFB_CheckBox_CheckedChanged; + // + // UDCustomForceMagnitude0 + // + UDCustomForceMagnitude0.AccessibleDescription = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude0.Enabled = false; + UDCustomForceMagnitude0.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + UDCustomForceMagnitude0.Location = new System.Drawing.Point(1112, 30); + UDCustomForceMagnitude0.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + UDCustomForceMagnitude0.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + UDCustomForceMagnitude0.Name = "UDCustomForceMagnitude0"; + UDCustomForceMagnitude0.Size = new System.Drawing.Size(96, 23); + UDCustomForceMagnitude0.TabIndex = 2; + UDCustomForceMagnitude0.Tag = "CustomForceMagnitude"; + UDCustomForceMagnitude0.ValueChanged += FFB_UpDown_ValueChanged; + // + // LblCustomForceMagnitude0 + // + LblCustomForceMagnitude0.AutoSize = true; + LblCustomForceMagnitude0.Location = new System.Drawing.Point(6, 32); + LblCustomForceMagnitude0.Name = "LblCustomForceMagnitude0"; + LblCustomForceMagnitude0.Size = new System.Drawing.Size(68, 15); + LblCustomForceMagnitude0.TabIndex = 3; + LblCustomForceMagnitude0.Tag = "LblCustomForceMag0"; + LblCustomForceMagnitude0.Text = "Magnitude:"; + // + // SliderCustomForceMagnitude0 + // + SliderCustomForceMagnitude0.AutoSize = false; + SliderCustomForceMagnitude0.BackColor = System.Drawing.SystemColors.Control; + SliderCustomForceMagnitude0.Enabled = false; + SliderCustomForceMagnitude0.LargeChange = 50; + SliderCustomForceMagnitude0.Location = new System.Drawing.Point(108, 30); + SliderCustomForceMagnitude0.Maximum = 10000; + SliderCustomForceMagnitude0.Minimum = -10000; + SliderCustomForceMagnitude0.Name = "SliderCustomForceMagnitude0"; + SliderCustomForceMagnitude0.Size = new System.Drawing.Size(998, 31); + SliderCustomForceMagnitude0.TabIndex = 0; + SliderCustomForceMagnitude0.Tag = "CustomForceMagnitude"; + SliderCustomForceMagnitude0.TickStyle = System.Windows.Forms.TickStyle.None; + SliderCustomForceMagnitude0.Scroll += FFB_Slider_Scroll; + // + // TabMisc + // + TabMisc.Controls.Add(LabelDebug); + TabMisc.Controls.Add(ButtonDebug); + TabMisc.Location = new System.Drawing.Point(4, 24); + TabMisc.Name = "TabMisc"; + TabMisc.Padding = new System.Windows.Forms.Padding(3); + TabMisc.Size = new System.Drawing.Size(1226, 637); + TabMisc.TabIndex = 4; + TabMisc.Text = "Misc"; + TabMisc.UseVisualStyleBackColor = true; + // + // LabelDebug + // + LabelDebug.AutoSize = true; + LabelDebug.Location = new System.Drawing.Point(6, 3); + LabelDebug.Name = "LabelDebug"; + LabelDebug.Size = new System.Drawing.Size(73, 15); + LabelDebug.TabIndex = 1; + LabelDebug.Text = "Debug Stuff:"; + // + // ButtonDebug + // + ButtonDebug.Location = new System.Drawing.Point(1077, 6); + ButtonDebug.Name = "ButtonDebug"; + ButtonDebug.Size = new System.Drawing.Size(143, 55); + ButtonDebug.TabIndex = 0; + ButtonDebug.Text = "Debug"; + ButtonDebug.UseVisualStyleBackColor = true; + ButtonDebug.Click += ButtonDebug_Click; + // + // Form1 + // + ClientSize = new System.Drawing.Size(1258, 718); + Controls.Add(TabController); + Controls.Add(ButtonRemove); + Controls.Add(ButtonAttach); + Controls.Add(ButtonEnumerateDevices); + Controls.Add(ComboBoxDevices); + Name = "Form1"; + Text = "Direct Input Explorer"; + FormClosing += Form1_FormClosing; + Load += Form1_Load; + TabController.ResumeLayout(false); + TabDeviceInfo.ResumeLayout(false); + TabDeviceInfo.PerformLayout(); + TabInput.ResumeLayout(false); + TabInput.PerformLayout(); + TabFFB.ResumeLayout(false); + GBSine.ResumeLayout(false); + GBSine.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDSineMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSineMagnitude).EndInit(); + GBSquare.ResumeLayout(false); + GBSquare.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDSquareMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSquareMagnitude).EndInit(); + GBTriangle.ResumeLayout(false); + GBTriangle.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDTriangleMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderTriangleMagnitude).EndInit(); + GBRampForce.ResumeLayout(false); + GBRampForce.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDRampForceMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderRampForceMagnitude).EndInit(); + GBSawtoothUp.ResumeLayout(false); + GBSawtoothUp.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDSawtoothUpMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSawtoothUpMagnitude).EndInit(); + GBSawtoothDown.ResumeLayout(false); + GBSawtoothDown.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDSawtoothDownMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSawtoothDownMagnitude).EndInit(); + GBSpring.ResumeLayout(false); + GBSpring.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDSpringDeadband).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringSaturation).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringCoefficient).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDSpringOffset).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringDeadband).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringSaturation).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringCoefficient).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderSpringOffset).EndInit(); + GBInertia.ResumeLayout(false); + GBInertia.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDInertiaMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderInertiaMagnitude).EndInit(); + GBFriction.ResumeLayout(false); + GBFriction.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDFrictionMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderFrictionMagnitude).EndInit(); + GBDamper.ResumeLayout(false); + GBDamper.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDDamperMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderDamperMagnitude).EndInit(); + GBConstantForce.ResumeLayout(false); + GBConstantForce.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDConstantForceMagnitude).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderConstantForceMagnitude).EndInit(); + tabPage1.ResumeLayout(false); + GBCuss.ResumeLayout(false); + GBCuss.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceSamplePeriod).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceSamplePeriod).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude9).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude9).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude8).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude8).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude7).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude7).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude6).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude6).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude5).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude5).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude4).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude4).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude3).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude3).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude2).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude2).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude1).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude1).EndInit(); + ((System.ComponentModel.ISupportInitialize)UDCustomForceMagnitude0).EndInit(); + ((System.ComponentModel.ISupportInitialize)SliderCustomForceMagnitude0).EndInit(); + TabMisc.ResumeLayout(false); + TabMisc.PerformLayout(); + ResumeLayout(false); + } - } - - #endregion - private System.Windows.Forms.ComboBox ComboBoxDevices; + #endregion + private System.Windows.Forms.ComboBox ComboBoxDevices; private System.Windows.Forms.Button ButtonEnumerateDevices; private System.Windows.Forms.Label LabelDeviceInfo; private System.Windows.Forms.Timer TimerPoll; @@ -932,6 +1898,72 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox CBFriction; private System.Windows.Forms.CheckBox CBDamper; private System.Windows.Forms.Label LabelFFBCapabilities; - } + private System.Windows.Forms.GroupBox GBSawtoothDown; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.NumericUpDown UDSawtoothDownMagnitude; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TrackBar SliderSawtoothDownMagnitude; + private System.Windows.Forms.GroupBox GBRampForce; + private System.Windows.Forms.CheckBox checkBox3; + private System.Windows.Forms.NumericUpDown UDRampForceMagnitude; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TrackBar SliderRampForceMagnitude; + private System.Windows.Forms.GroupBox GBSawtoothUp; + private System.Windows.Forms.CheckBox checkBox2; + private System.Windows.Forms.NumericUpDown UDSawtoothUpMagnitude; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TrackBar SliderSawtoothUpMagnitude; + private System.Windows.Forms.GroupBox GBSine; + private System.Windows.Forms.CheckBox checkBox6; + private System.Windows.Forms.NumericUpDown UDSineMagnitude; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.TrackBar SliderSineMagnitude; + private System.Windows.Forms.GroupBox GBSquare; + private System.Windows.Forms.CheckBox checkBox5; + private System.Windows.Forms.NumericUpDown UDSquareMagnitude; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TrackBar SliderSquareMagnitude; + private System.Windows.Forms.GroupBox GBTriangle; + private System.Windows.Forms.CheckBox checkBox4; + private System.Windows.Forms.NumericUpDown UDTriangleMagnitude; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TrackBar SliderTriangleMagnitude; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.GroupBox GBCuss; + private System.Windows.Forms.CheckBox CBCustomForce; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude0; + private System.Windows.Forms.Label LblCustomForceMagnitude0; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude0; + private System.Windows.Forms.NumericUpDown UDCustomForceSamplePeriod; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.TrackBar SliderCustomForceSamplePeriod; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude9; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude9; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude8; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude8; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude7; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude7; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude6; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude6; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude5; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude5; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude4; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude4; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude3; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude3; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude2; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude2; + private System.Windows.Forms.NumericUpDown UDCustomForceMagnitude1; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TrackBar SliderCustomForceMagnitude1; + } } diff --git a/DirectInputExplorer~/DirectInputExplorer/Form1.cs b/DirectInputExplorer~/DirectInputExplorer/Form1.cs index d351ad9..147051c 100644 --- a/DirectInputExplorer~/DirectInputExplorer/Form1.cs +++ b/DirectInputExplorer~/DirectInputExplorer/Form1.cs @@ -1,232 +1,493 @@ īģŋusing System; +using System.Diagnostics; using System.Linq; +using System.Runtime.InteropServices; using System.Windows.Forms; using DirectInputManager; -namespace DirectInputExplorer { - public partial class Form1 : Form { - public Form1() { - InitializeComponent(); - } - - ////////////////////////////////////////////////////////////// - // .NET Events/Actions - ////////////////////////////////////////////////////////////// - - private void Form1_Load(object sender, EventArgs e) { - DIManager.Initialize(); - DIManager.OnDeviceAdded += DIDeviceAdded; // Register handler for when a device is attached - DIManager.OnDeviceRemoved += DIDeviceRemoved; // Register handler for when a device is removed - ButtonEnumerateDevices.PerformClick(); - if(DIManager.devices.Length != 0) { ComboBoxDevices.SelectedIndex = 0; } // Select first device by default - - // Disable tabs until device is attached - foreach (TabPage tab in TabController.TabPages) { - tab.Enabled = false; - } - (TabController.TabPages[0] as TabPage).Enabled = true; - (TabController.TabPages["TabMisc"] as TabPage).Enabled = true; - } +namespace DirectInputExplorer +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } - private void Form1_FormClosing(object sender, FormClosingEventArgs e) { - DIManager.StopDirectInput(); - } + ////////////////////////////////////////////////////////////// + // .NET Events/Actions + ////////////////////////////////////////////////////////////// + + private void Form1_Load(object sender, EventArgs e) + { + DIManager.Initialize(); + DIManager.OnDeviceAdded += DIDeviceAdded; // Register handler for when a device is attached + DIManager.OnDeviceRemoved += DIDeviceRemoved; // Register handler for when a device is removed + ButtonEnumerateDevices.PerformClick(); + if (DIManager.devices.Length != 0) { ComboBoxDevices.SelectedIndex = 0; } // Select first device by default + + // Disable tabs until device is attached + foreach (TabPage tab in TabController.TabPages) + { + tab.Enabled = false; + } + (TabController.TabPages[0] as TabPage).Enabled = true; + (TabController.TabPages["TabMisc"] as TabPage).Enabled = true; + } - private void ButtonEnumerateDevices_Click(object sender, EventArgs e) { - string ExistingGUID = ComboBoxDevices.SelectedIndex != -1 ? DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance : ""; // GUID of device selected, empty if not - DIManager.EnumerateDevices(); // Fetch currently plugged in devices + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + DIManager.StopDirectInput(); + } - ComboBoxDevices.Items.Clear(); - foreach(DeviceInfo device in DIManager.devices) { - ComboBoxDevices.Items.Add( device.productName ); - } + private void ButtonEnumerateDevices_Click(object sender, EventArgs e) + { + string ExistingGUID = ComboBoxDevices.SelectedIndex != -1 ? DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance : ""; // GUID of device selected, empty if not + DIManager.EnumerateDevices(); // Fetch currently plugged in devices - if (!String.IsNullOrEmpty(ExistingGUID)) { ComboBoxDevices.SelectedIndex = Array.FindIndex(DIManager.devices, d => d.guidInstance == ExistingGUID); } // Reselect that device - } + ComboBoxDevices.Items.Clear(); + foreach (DeviceInfo device in DIManager.devices) + { + ComboBoxDevices.Items.Add(device.productName); + } - private void ComboBoxDevices_SelectedIndexChanged(object sender, EventArgs e) { - UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); - } + if (!String.IsNullOrEmpty(ExistingGUID)) { ComboBoxDevices.SelectedIndex = Array.FindIndex(DIManager.devices, d => d.guidInstance == ExistingGUID); } // Reselect that device + } - private void ButtonAttach_Click(object sender, EventArgs e) { - DeviceInfo targetDevice = DIManager.devices[ComboBoxDevices.SelectedIndex]; - DIManager.Attach(targetDevice); // Connect to device - UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); - - // Attach Events - ActiveDeviceInfo ADI; - if (DIManager.GetADI(targetDevice, out ADI)) { // Check if device active - //ADI.OnDeviceRemoved += DIDeviceRemoved; // Register a handler for when the device is removed - ADI.OnDeviceStateChange += DeviceStateChanged; // Register a handler for when the device state changes - } - } + private void ComboBoxDevices_SelectedIndexChanged(object sender, EventArgs e) + { + UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); + } - private void ButtonRemove_Click(object sender, EventArgs e) { - DIManager.StopAllFFBEffects(DIManager.devices[ComboBoxDevices.SelectedIndex]); - DIManager.Destroy(DIManager.devices[ComboBoxDevices.SelectedIndex]); // Destroy device - UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); - } + private void ButtonAttach_Click(object sender, EventArgs e) + { + DeviceInfo targetDevice = DIManager.devices[ComboBoxDevices.SelectedIndex]; + DIManager.Attach(targetDevice); // Connect to device + UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); + + // Attach Events + ActiveDeviceInfo ADI; + if (DIManager.GetADI(targetDevice, out ADI)) + { // Check if device active + ADI.OnDeviceRemoved += DIDeviceRemoved; // Register a handler for when the device is removed + ADI.OnDeviceStateChange += DeviceStateChanged; // Register a handler for when the device state changes + if (DIManager.FFBCapable(targetDevice)) + { + (TabController.TabPages["tabPage1"] as TabPage).Enabled = true; + } + else + { + (TabController.TabPages["tabPage1"] as TabPage).Enabled = false; + } + } + } - private void TimerPoll_Tick_1(object sender, EventArgs e) { - // If device connected get data - /*if (DIManager.devices.Length != 0 && DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) { // Currently selected device is attached - FlatJoyState2 DeviceState = DIManager.GetDeviceState(DIManager.devices[ComboBoxDevices.SelectedIndex]); - LabelInput.Text = $"buttonsA: {Convert.ToString((long)DeviceState.buttonsA, 2).PadLeft(64, '0')}\nbuttonsB: {Convert.ToString((long)DeviceState.buttonsB, 2).PadLeft(64, '0')}\nlX: {DeviceState.lX}\nlY: {DeviceState.lY}\nlZ: {DeviceState.lZ}\nlU: {DeviceState.lU}\nlV: {DeviceState.lV}\nlRx: {DeviceState.lRx}\nlRy: {DeviceState.lRy}\nlRz: {DeviceState.lRz}\nlVX: {DeviceState.lVX}\nlVY: {DeviceState.lVY}\nlVZ: {DeviceState.lVZ}\nlVU: {DeviceState.lVU}\nlVV: {DeviceState.lVV}\nlVRx: {DeviceState.lVRx}\nlVRy: {DeviceState.lVRy}\nlVRz: {DeviceState.lVRz}\nlAX: {DeviceState.lAX}\nlAY: {DeviceState.lAY}\nlAZ: {DeviceState.lAZ}\nlAU: {DeviceState.lAU}\nlAV: {DeviceState.lAV}\nlARx: {DeviceState.lARx}\nlARy: {DeviceState.lARy}\nlARz: {DeviceState.lARz}\nlFX: {DeviceState.lFX}\nlFY: {DeviceState.lFY}\nlFZ: {DeviceState.lFZ}\nlFU: {DeviceState.lFU}\nlFV: {DeviceState.lFV}\nlFRx: {DeviceState.lFRx}\nlFRy: {DeviceState.lFRy}\nlFRz: {DeviceState.lFRz}\nrgdwPOV: {Convert.ToString((long)DeviceState.rgdwPOV, 2).PadLeft(16, '0')}\n"; - }*/ - - DIManager.PollAll(); // Fetch data from all active devices - if (DIManager.devices.Length != 0 && DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) { // Currently selected device is attached - UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); // Update readouts with active device data - } - } + private void ButtonRemove_Click(object sender, EventArgs e) + { + DIManager.StopAllFFBEffects(DIManager.devices[ComboBoxDevices.SelectedIndex]); + DIManager.Destroy(DIManager.devices[ComboBoxDevices.SelectedIndex]); // Destroy device + UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); + (TabController.TabPages["tabPage1"] as TabPage).Enabled = false; + } - ////////////////////////////////////////////////////////////// - // FFB Tab Functions - ////////////////////////////////////////////////////////////// + private void TimerPoll_Tick_1(object sender, EventArgs e) + { + // If device connected get data + /*if (DIManager.devices.Length != 0 && DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) { // Currently selected device is attached + FlatJoyState2 DeviceState = DIManager.GetDeviceState(DIManager.devices[ComboBoxDevices.SelectedIndex]); + LabelInput.Text = $"buttonsA: {Convert.ToString((long)DeviceState.buttonsA, 2).PadLeft(64, '0')}\nbuttonsB: {Convert.ToString((long)DeviceState.buttonsB, 2).PadLeft(64, '0')}\nlX: {DeviceState.lX}\nlY: {DeviceState.lY}\nlZ: {DeviceState.lZ}\nlU: {DeviceState.lU}\nlV: {DeviceState.lV}\nlRx: {DeviceState.lRx}\nlRy: {DeviceState.lRy}\nlRz: {DeviceState.lRz}\nlVX: {DeviceState.lVX}\nlVY: {DeviceState.lVY}\nlVZ: {DeviceState.lVZ}\nlVU: {DeviceState.lVU}\nlVV: {DeviceState.lVV}\nlVRx: {DeviceState.lVRx}\nlVRy: {DeviceState.lVRy}\nlVRz: {DeviceState.lVRz}\nlAX: {DeviceState.lAX}\nlAY: {DeviceState.lAY}\nlAZ: {DeviceState.lAZ}\nlAU: {DeviceState.lAU}\nlAV: {DeviceState.lAV}\nlARx: {DeviceState.lARx}\nlARy: {DeviceState.lARy}\nlARz: {DeviceState.lARz}\nlFX: {DeviceState.lFX}\nlFY: {DeviceState.lFY}\nlFZ: {DeviceState.lFZ}\nlFU: {DeviceState.lFU}\nlFV: {DeviceState.lFV}\nlFRx: {DeviceState.lFRx}\nlFRy: {DeviceState.lFRy}\nlFRz: {DeviceState.lFRz}\nrgdwPOV: {Convert.ToString((long)DeviceState.rgdwPOV, 2).PadLeft(16, '0')}\n"; + }*/ + + DIManager.PollAll(); // Fetch data from all active devices + if (DIManager.devices.Length != 0 && DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) + { // Currently selected device is attached + UpdateReadoutsWithDeviceData(DIManager.devices[ComboBoxDevices.SelectedIndex]); // Update readouts with active device data + } + } - private void FFB_CheckBox_CheckedChanged(object sender, EventArgs e) { - CheckBox TriggeringCheckBox = (CheckBox)sender; - FFBEffects TriggeringEffectType = (FFBEffects)Enum.Parse(typeof(FFBEffects), TriggeringCheckBox.Tag.ToString()); + ////////////////////////////////////////////////////////////// + // FFB Tab Functions + ////////////////////////////////////////////////////////////// + + private void FFB_CheckBox_CheckedChanged(object sender, EventArgs e) + { + CheckBox TriggeringCheckBox = (CheckBox)sender; + FFBEffects TriggeringEffectType = (FFBEffects)Enum.Parse(typeof(FFBEffects), TriggeringCheckBox.Tag.ToString()); + if (TriggeringCheckBox.Checked) + { + // Special handling for the periodic effects + if (TriggeringCheckBox.Tag.ToString() == "Sine" || + TriggeringCheckBox.Tag.ToString() == "SawtoothDown" || + TriggeringCheckBox.Tag.ToString() == "SawtoothUp" || + TriggeringCheckBox.Tag.ToString() == "RampForce" || + TriggeringCheckBox.Tag.ToString() == "Triangle" || + TriggeringCheckBox.Tag.ToString() == "Square") + { + // Create and initialize periodic effect + if (!DIManager.EnableFFBEffect(DIManager.devices[ComboBoxDevices.SelectedIndex], TriggeringEffectType)) + { + Debug.WriteLine($"Failed to enable periodic effect"); + TriggeringCheckBox.Checked = false; + return; + } + + // Initialize with current magnitude + if (TriggeringCheckBox.Parent.Controls.Find("UD" + TriggeringEffectType.ToString() + "Magnitude", false).FirstOrDefault() as NumericUpDown != null) + { + UpdatePeriodicSimple( + DIManager.devices[ComboBoxDevices.SelectedIndex], + TriggeringEffectType, + (int)(TriggeringCheckBox.Parent.Controls.Find("UD" + TriggeringEffectType.ToString() + "Magnitude", false).FirstOrDefault() as NumericUpDown).Value, + TriggeringCheckBox.Parent.Controls.Find("UD" + TriggeringEffectType.ToString() + "Magnitude", false).FirstOrDefault() as NumericUpDown + ); + } + } + else + { + // Handle other effects normally + TriggeringCheckBox.Checked = DIManager.EnableFFBEffect( + DIManager.devices[ComboBoxDevices.SelectedIndex], + TriggeringEffectType + ); + } + } + else + { + // Special handling for periodic effects + if (TriggeringCheckBox.Tag.ToString() == "Sine" || + TriggeringCheckBox.Tag.ToString() == "SawtoothDown" || + TriggeringCheckBox.Tag.ToString() == "SawtoothUp" || + TriggeringCheckBox.Tag.ToString() == "RampForce" || + TriggeringCheckBox.Tag.ToString() == "Triangle" || + TriggeringCheckBox.Tag.ToString() == "Square") + { + // First stop the effect by setting magnitude to 0 + UpdatePeriodicSimple( + DIManager.devices[ComboBoxDevices.SelectedIndex], + (FFBEffects)Enum.Parse(typeof(FFBEffects), TriggeringCheckBox.Tag.ToString()), + 0, + TriggeringCheckBox.Parent.Controls.Find("UD" + TriggeringEffectType.ToString() + "Magnitude", false).FirstOrDefault() as NumericUpDown + ); + + // Then destroy the effect + TriggeringCheckBox.Checked = !DIManager.DestroyFFBEffect(DIManager.devices[ComboBoxDevices.SelectedIndex], (FFBEffects)Enum.Parse(typeof(FFBEffects), TriggeringCheckBox.Tag.ToString())); + } + else + { + // Handle other effects normally + TriggeringCheckBox.Checked = !DIManager.DestroyFFBEffect(DIManager.devices[ComboBoxDevices.SelectedIndex], TriggeringEffectType); + } + } + + // Update control states + foreach (Control element in TriggeringCheckBox.Parent.Controls) + { + if (element is CheckBox) continue; + element.Enabled = TriggeringCheckBox.Checked; + } + } - if (TriggeringCheckBox.Checked) { // Enable the effect - TriggeringCheckBox.Checked = DIManager.EnableFFBEffect(DIManager.devices[ComboBoxDevices.SelectedIndex], TriggeringEffectType); // If enable fails, checkbox will be unchecked - } else { // Disable the effect - TriggeringCheckBox.Checked = !DIManager.DestroyFFBEffect(DIManager.devices[ComboBoxDevices.SelectedIndex], TriggeringEffectType); - } + private void FFB_GroupBox_Click(object sender, EventArgs e) + { + CheckBox CB = ((GroupBox)sender).Controls.Find("CB" + ((GroupBox)sender).Tag, false).FirstOrDefault() as CheckBox; + CB.Checked = !CB.Checked; + } - foreach (Control element in TriggeringCheckBox.Parent.Controls) { // For each of the children in the parent GroupBox - if (element is CheckBox) continue; // Don't disable yourself - element.Enabled = TriggeringCheckBox.Checked; - } + private void FFB_Label_Click(object sender, EventArgs e) + { + Label TrigElement = (Label)sender; + TrackBar TB = TrigElement.Parent.Controls.Find("Slider" + TrigElement.Tag, false).FirstOrDefault() as TrackBar; + NumericUpDown UD = TrigElement.Parent.Controls.Find("UD" + TrigElement.Tag, false).FirstOrDefault() as NumericUpDown; + switch (TB.Tag) + { + case string a when a.Contains("Saturation"): // Center Saturation to 5000 + TB.Value = 5000; + UD.Value = 5000; + break; + default: + TB.Value = 0; + UD.Value = 0; + break; + } + } - } + private void FFB_Slider_Scroll(object sender, EventArgs e) + { + TrackBar TrigElement = (TrackBar)sender; + // Update UpDown + NumericUpDown UD = TrigElement.Parent.Controls.Find("UD" + TrigElement.Tag, false).FirstOrDefault() as NumericUpDown; + UD.Value = TrigElement.Value; + // FFB Effect has changed + } - private void FFB_GroupBox_Click(object sender, EventArgs e) { - CheckBox CB = ((GroupBox)sender).Controls.Find("CB" + ((GroupBox)sender).Tag, false).FirstOrDefault() as CheckBox; - CB.Checked = !CB.Checked; - } + private void FFB_UpDown_ValueChanged(object sender, EventArgs e) + { + DeviceInfo ActiveDevice = DIManager.devices[ComboBoxDevices.SelectedIndex]; + NumericUpDown TrigElement = (NumericUpDown)sender; + // Update slider(TrackBar) + TrackBar TB = TrigElement.Parent.Controls.Find("Slider" + TrigElement.Tag, false).FirstOrDefault() as TrackBar; + TB.Value = (int)TrigElement.Value; + // Update Effect + switch (TrigElement.Parent.Tag) + { + case "ConstantForce": + DIManager.UpdateConstantForceSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDConstantForceMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); + break; + case "Spring": + DIManager.UpdateSpringSimple(ActiveDevice, + (uint)((TrigElement.Parent.Controls.Find("UDSpringDeadband", false).FirstOrDefault() as NumericUpDown).Value), + (int)((TrigElement.Parent.Controls.Find("UDSpringOffset", false).FirstOrDefault() as NumericUpDown).Value), + (int)((TrigElement.Parent.Controls.Find("UDSpringCoefficient", false).FirstOrDefault() as NumericUpDown).Value), + (int)((TrigElement.Parent.Controls.Find("UDSpringCoefficient", false).FirstOrDefault() as NumericUpDown).Value), + (uint)((TrigElement.Parent.Controls.Find("UDSpringSaturation", false).FirstOrDefault() as NumericUpDown).Value), + (uint)((TrigElement.Parent.Controls.Find("UDSpringSaturation", false).FirstOrDefault() as NumericUpDown).Value) + ); + break; + case "Damper": + DIManager.UpdateDamperSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDDamperMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); + break; + case "Friction": + DIManager.UpdateFrictionSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDFrictionMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); + break; + case "Inertia": + DIManager.UpdateInertiaSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDInertiaMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); + break; + case "Sine": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.Sine, + (int)((TrigElement.Parent.Controls.Find("UDSineMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "RampForce": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.RampForce, + (int)((TrigElement.Parent.Controls.Find("UDRampForceMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "SawtoothDown": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.SawtoothDown, + (int)((TrigElement.Parent.Controls.Find("UDSawtoothDownMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "SawtoothUp": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.SawtoothUp, + (int)((TrigElement.Parent.Controls.Find("UDSawtoothUpMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "Square": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.Square, + (int)((TrigElement.Parent.Controls.Find("UDSquareMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "Triangle": + UpdatePeriodicSimple( + ActiveDevice, + FFBEffects.Triangle, + (int)((TrigElement.Parent.Controls.Find("UDTriangleMagnitude", false).FirstOrDefault() as NumericUpDown).Value), + TrigElement + ); + break; + case "CustomForce": + uint samplePeriod = (uint)((TrigElement.Parent.Controls.Find("UDCustomForceSamplePeriod", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude0 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude0", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude1 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude1", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude2 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude2", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude3 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude3", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude4 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude4", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude5 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude5", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude6 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude6", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude7 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude7", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude8 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude8", false).FirstOrDefault() as NumericUpDown).Value); + int magnitude9 = (int)((TrigElement.Parent.Controls.Find("UDCustomForceMagnitude9", false).FirstOrDefault() as NumericUpDown).Value); + int[] forceData = new int[] { magnitude0, + magnitude1, + magnitude2, + magnitude3, + magnitude4, + magnitude5, + magnitude6, + magnitude7, + magnitude8, + magnitude9, + }; + UpdateCustomForceSimple( + ActiveDevice, + forceData, + samplePeriod, + TrigElement + ); + break; + + default: + break; + + } + //System.Diagnostics.Debug.WriteLine("Changed: " + TrigElement.Parent.Tag); + } - private void FFB_Label_Click(object sender, EventArgs e) { - Label TrigElement = (Label)sender; - TrackBar TB = TrigElement.Parent.Controls.Find("Slider" + TrigElement.Tag, false).FirstOrDefault() as TrackBar; - NumericUpDown UD = TrigElement.Parent.Controls.Find("UD" + TrigElement.Tag, false).FirstOrDefault() as NumericUpDown; - switch (TB.Tag) { - case string a when a.Contains("Saturation"): // Center Saturation to 5000 - TB.Value = 5000; - UD.Value = 5000; - break; - default: - TB.Value = 0; - UD.Value = 0; - break; - } - } + private void UpdatePeriodicSimple(DeviceInfo activeDevice, FFBEffects effectType, int magnitude, NumericUpDown trigElement) + { + try + { + if (activeDevice.guidInstance == null || trigElement == null) + { + Debug.WriteLine("UpdatePeriodicSimple: Invalid input parameters"); + return; + } + + // Get the effect checkbox + CheckBox effectCheckBox = trigElement.Parent.Controls.Find("CB" + effectType.ToString(), false).FirstOrDefault() as CheckBox; + + // First destroy any existing periodic effect + foreach (FFBEffects effects in new FFBEffects[] { FFBEffects.SawtoothUp, FFBEffects.SawtoothDown, FFBEffects.Square, + FFBEffects.Triangle, FFBEffects.RampForce, FFBEffects.Sine}) + { + DIManager.DestroyFFBEffect(activeDevice, effectType); + } + // Then create new effect + if (!DIManager.EnableFFBEffect(activeDevice, effectType)) + { + Debug.WriteLine($"UpdatePeriodicSimple: Failed to create effect {effectType}"); + if (effectCheckBox != null) + { + effectCheckBox.Checked = false; + } + return; + } + + // Update the effect + DIManager.UpdatePeriodicSimple( + activeDevice, + effectType, + magnitude + ); + } + catch (Exception ex) + { + Debug.WriteLine($"UpdatePeriodicSimple: Exception occurred: {ex.Message}"); + Debug.WriteLine(ex.StackTrace); + } + } - private void FFB_Slider_Scroll(object sender, EventArgs e) { - TrackBar TrigElement = (TrackBar)sender; - // Update UpDown - NumericUpDown UD = TrigElement.Parent.Controls.Find("UD" + TrigElement.Tag, false).FirstOrDefault() as NumericUpDown; - UD.Value = TrigElement.Value; - // FFB Effect has changed - } + private void UpdateCustomForceSimple(DeviceInfo activeDevice, int[] forceData, uint samplePeriod, NumericUpDown trigElement) + { + try + { + if (activeDevice.guidInstance == null || trigElement == null) + { + Debug.WriteLine("UpdatePeriodicSimple: Invalid input parameters"); + return; + } + + // Get the effect checkbox + CheckBox effectCheckBox = trigElement.Parent.Controls.Find("CBCustomForce", false).FirstOrDefault() as CheckBox; + + DIManager.DestroyFFBEffect(activeDevice, FFBEffects.CustomForce); + // Then create new effect + if (!DIManager.EnableFFBEffect(activeDevice, FFBEffects.CustomForce)) + { + Debug.WriteLine($"UpdatePeriodicSimple: Failed to create effect \"CustomForce\""); + if (effectCheckBox != null) + { + effectCheckBox.Checked = false; + } + return; + } + + + DIManager.UpdateCustomForceEffect(activeDevice, forceData, samplePeriod); + } + catch (Exception ex) + { + Debug.WriteLine($"UpdateCustomForceSimple error: {ex.Message}"); + } + } - private void FFB_UpDown_ValueChanged(object sender, EventArgs e) { - DeviceInfo ActiveDevice = DIManager.devices[ComboBoxDevices.SelectedIndex]; - NumericUpDown TrigElement = (NumericUpDown)sender; - // Update slider(TrackBar) - TrackBar TB = TrigElement.Parent.Controls.Find("Slider" + TrigElement.Tag, false).FirstOrDefault() as TrackBar; - TB.Value = (int)TrigElement.Value; - // Update Effect - switch (TrigElement.Parent.Tag) { - case "ConstantForce": - DIManager.UpdateConstantForceSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDConstantForceMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); - break; - case "Spring": - DIManager.UpdateSpringSimple(ActiveDevice, - (uint)((TrigElement.Parent.Controls.Find("UDSpringDeadband" , false).FirstOrDefault() as NumericUpDown).Value), - (int) ((TrigElement.Parent.Controls.Find("UDSpringOffset" , false).FirstOrDefault() as NumericUpDown).Value), - (int) ((TrigElement.Parent.Controls.Find("UDSpringCoefficient", false).FirstOrDefault() as NumericUpDown).Value), - (int) ((TrigElement.Parent.Controls.Find("UDSpringCoefficient", false).FirstOrDefault() as NumericUpDown).Value), - (uint)((TrigElement.Parent.Controls.Find("UDSpringSaturation" , false).FirstOrDefault() as NumericUpDown).Value), - (uint)((TrigElement.Parent.Controls.Find("UDSpringSaturation" , false).FirstOrDefault() as NumericUpDown).Value) - ); - break; - case "Damper": - DIManager.UpdateDamperSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDDamperMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); - break; - case "Friction": - DIManager.UpdateFrictionSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDFrictionMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); - break; - case "Inertia": - DIManager.UpdateInertiaSimple(ActiveDevice, (int)((TrigElement.Parent.Controls.Find("UDInertiaMagnitude", false).FirstOrDefault() as NumericUpDown).Value)); - break; - default: - break; - - } - //System.Diagnostics.Debug.WriteLine("Changed: " + TrigElement.Parent.Tag); - } + ////////////////////////////////////////////////////////////// + // Device Events + ////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////// - // Device Events - ////////////////////////////////////////////////////////////// + public void DIDeviceAdded(DeviceInfo device) + { + string deviceName = $"{device.productName}:{device.guidInstance}"; + System.Diagnostics.Debug.WriteLine($"{deviceName} Added!"); + ButtonEnumerateDevices.PerformClick(); // Refresh device dropdown + } - public void DIDeviceAdded(DeviceInfo device) { - string deviceName = $"{device.productName}:{device.guidInstance}"; - System.Diagnostics.Debug.WriteLine($"{deviceName} Added!"); - ButtonEnumerateDevices.PerformClick(); // Refresh device dropdown - } - - public void DIDeviceRemoved(DeviceInfo device) { - string deviceName = $"{device.productName}:{device.guidInstance}"; - System.Diagnostics.Debug.WriteLine($"{deviceName} Removed!"); - ButtonEnumerateDevices.PerformClick(); // Refresh device dropdown - } + public void DIDeviceRemoved(DeviceInfo device) + { + string deviceName = $"{device.productName}:{device.guidInstance}"; + System.Diagnostics.Debug.WriteLine($"{deviceName} Removed!"); + ButtonEnumerateDevices.PerformClick(); // Refresh device dropdown + } - public void DeviceStateChanged(DeviceInfo device, FlatJoyState2 state) { - System.Diagnostics.Debug.WriteLine($"{device.productName} Event {state.lX}"); - if (device.guidInstance == DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance) { // If this device is selected show the state - LabelInput.Text = $"buttonsA: {Convert.ToString((long)state.buttonsA, 2).PadLeft(64, '0')}\nbuttonsB: {Convert.ToString((long)state.buttonsB, 2).PadLeft(64, '0')}\nlX: {state.lX}\nlY: {state.lY}\nlZ: {state.lZ}\nlU: {state.lU}\nlV: {state.lV}\nlRx: {state.lRx}\nlRy: {state.lRy}\nlRz: {state.lRz}\nlVX: {state.lVX}\nlVY: {state.lVY}\nlVZ: {state.lVZ}\nlVU: {state.lVU}\nlVV: {state.lVV}\nlVRx: {state.lVRx}\nlVRy: {state.lVRy}\nlVRz: {state.lVRz}\nlAX: {state.lAX}\nlAY: {state.lAY}\nlAZ: {state.lAZ}\nlAU: {state.lAU}\nlAV: {state.lAV}\nlARx: {state.lARx}\nlARy: {state.lARy}\nlARz: {state.lARz}\nlFX: {state.lFX}\nlFY: {state.lFY}\nlFZ: {state.lFZ}\nlFU: {state.lFU}\nlFV: {state.lFV}\nlFRx: {state.lFRx}\nlFRy: {state.lFRy}\nlFRz: {state.lFRz}\nrgdwPOV: {Convert.ToString((long)state.rgdwPOV, 2).PadLeft(16, '0')}\n"; - } - } + public void DeviceStateChanged(DeviceInfo device, FlatJoyState2 state) + { + System.Diagnostics.Debug.WriteLine($"{device.productName} Event {state.lX}"); + if (device.guidInstance == DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance) + { // If this device is selected show the state + LabelInput.Text = $"buttonsA: {Convert.ToString((long)state.buttonsA, 2).PadLeft(64, '0')}\nbuttonsB: {Convert.ToString((long)state.buttonsB, 2).PadLeft(64, '0')}\nlX: {state.lX}\nlY: {state.lY}\nlZ: {state.lZ}\nlU: {state.lU}\nlV: {state.lV}\nlRx: {state.lRx}\nlRy: {state.lRy}\nlRz: {state.lRz}\nlVX: {state.lVX}\nlVY: {state.lVY}\nlVZ: {state.lVZ}\nlVU: {state.lVU}\nlVV: {state.lVV}\nlVRx: {state.lVRx}\nlVRy: {state.lVRy}\nlVRz: {state.lVRz}\nlAX: {state.lAX}\nlAY: {state.lAY}\nlAZ: {state.lAZ}\nlAU: {state.lAU}\nlAV: {state.lAV}\nlARx: {state.lARx}\nlARy: {state.lARy}\nlARz: {state.lARz}\nlFX: {state.lFX}\nlFY: {state.lFY}\nlFZ: {state.lFZ}\nlFU: {state.lFU}\nlFV: {state.lFV}\nlFRx: {state.lFRx}\nlFRy: {state.lFRy}\nlFRz: {state.lFRz}\nrgdwPOV: {Convert.ToString((long)state.rgdwPOV, 2).PadLeft(16, '0')}\n"; + } + } - ////////////////////////////////////////////////////////////// - // Utility Functions - ////////////////////////////////////////////////////////////// - - private void UpdateReadoutsWithDeviceData(DeviceInfo Device) { - LabelDeviceInfo.Text = $"deviceType: {Device.deviceType}\nguidInstance: {Device.guidInstance}\nguidProduct: {Device.guidProduct}\ninstanceName: {Device.instanceName}\nFFBCapable: {Device.FFBCapable}"; - - if (DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) { // Currently selected device is attached - (TabController.TabPages["TabInput"] as TabPage).Enabled = true; // Enable the Input Tab as we're connected - DIDEVCAPS DeviceCaps = DIManager.GetDeviceCapabilities(Device); - LabelCapabilities.Text = $"dwSize: {DeviceCaps.dwSize}\ndwFlags: {DeviceCaps.dwFlags}\ndwDevType: {Convert.ToString(DeviceCaps.dwDevType, 2).PadLeft(32, '0')}\ndwAxes: {DeviceCaps.dwAxes}\ndwButtons: {DeviceCaps.dwButtons}\ndwPOVs: {DeviceCaps.dwPOVs}\ndwFFSamplePeriod: {DeviceCaps.dwFFSamplePeriod}\ndwFFMinTimeResolution: {DeviceCaps.dwFFMinTimeResolution}\ndwFirmwareRevision: {DeviceCaps.dwFirmwareRevision}\ndwHardwareRevision: {DeviceCaps.dwHardwareRevision}\ndwFFDriverVersion: {DeviceCaps.dwFFDriverVersion}"; - - - if (DIManager.FFBCapable(Device)) { - (TabController.TabPages["TabFFB"] as TabPage).Enabled = true; // If Device is FFB capable, enable the tab - LabelFFBCapabilities.Text = string.Join("\n", DIManager.GetDeviceFFBCapabilities(Device)); - } else { - (TabController.TabPages["TabFFB"] as TabPage).Enabled = false; - LabelFFBCapabilities.Text = "FFBCapabilities: FFB Unsupported"; - } - - } else { // Device isn't attached, default readouts - LabelInput.Text = "Input: Attach First"; - LabelCapabilities.Text = "Capabilities: Attach First"; - LabelFFBCapabilities.Text = "FFBCapabilities: Attach First"; - (TabController.TabPages["TabInput"] as TabPage).Enabled = false; - (TabController.TabPages["TabFFB"] as TabPage).Enabled = false; - } - } + ////////////////////////////////////////////////////////////// + // Utility Functions + ////////////////////////////////////////////////////////////// + + private void UpdateReadoutsWithDeviceData(DeviceInfo Device) + { + LabelDeviceInfo.Text = $"deviceType: {Device.deviceType}\nguidInstance: {Device.guidInstance}\nguidProduct: {Device.guidProduct}\ninstanceName: {Device.instanceName}\nFFBCapable: {Device.FFBCapable}"; + + if (DIManager.isDeviceActive(DIManager.devices[ComboBoxDevices.SelectedIndex])) + { // Currently selected device is attached + (TabController.TabPages["TabInput"] as TabPage).Enabled = true; // Enable the Input Tab as we're connected + DIDEVCAPS DeviceCaps = DIManager.GetDeviceCapabilities(Device); + LabelCapabilities.Text = $"dwSize: {DeviceCaps.dwSize}\ndwFlags: {DeviceCaps.dwFlags}\ndwDevType: {Convert.ToString(DeviceCaps.dwDevType, 2).PadLeft(32, '0')}\ndwAxes: {DeviceCaps.dwAxes}\ndwButtons: {DeviceCaps.dwButtons}\ndwPOVs: {DeviceCaps.dwPOVs}\ndwFFSamplePeriod: {DeviceCaps.dwFFSamplePeriod}\ndwFFMinTimeResolution: {DeviceCaps.dwFFMinTimeResolution}\ndwFirmwareRevision: {DeviceCaps.dwFirmwareRevision}\ndwHardwareRevision: {DeviceCaps.dwHardwareRevision}\ndwFFDriverVersion: {DeviceCaps.dwFFDriverVersion}"; + + + if (DIManager.FFBCapable(Device)) + { + (TabController.TabPages["TabFFB"] as TabPage).Enabled = true; // If Device is FFB capable, enable the tab + LabelFFBCapabilities.Text = string.Join("\n", DIManager.GetDeviceFFBCapabilities(Device)); + } + else + { + (TabController.TabPages["TabFFB"] as TabPage).Enabled = false; + LabelFFBCapabilities.Text = "FFBCapabilities: FFB Unsupported"; + } + + } + else + { // Device isn't attached, default readouts + LabelInput.Text = "Input: Attach First"; + LabelCapabilities.Text = "Capabilities: Attach First"; + LabelFFBCapabilities.Text = "FFBCapabilities: Attach First"; + (TabController.TabPages["TabInput"] as TabPage).Enabled = false; + (TabController.TabPages["TabFFB"] as TabPage).Enabled = false; + } + } - ////////////////////////////////////////////////////////////// - // Debug Functions - ////////////////////////////////////////////////////////////// - private void ButtonDebug_Click(object sender, EventArgs e) { - //DirectInputManager.Native.DEBUG1(DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance, out string[] DEBUGDATA); - //LabelDebug.Text = string.Join("\n", DEBUGDATA); + ////////////////////////////////////////////////////////////// + // Debug Functions + ////////////////////////////////////////////////////////////// + private void ButtonDebug_Click(object sender, EventArgs e) + { + DirectInputManager.Native.DEBUG1(DIManager.devices[ComboBoxDevices.SelectedIndex].guidInstance, out string[] DEBUGDATA); + LabelDebug.Text = string.Join("\n", DEBUGDATA); + } } - } } diff --git a/DirectInputExplorer~/DirectInputExplorer/Form1.resx b/DirectInputExplorer~/DirectInputExplorer/Form1.resx index c43bf42..1bf0567 100644 --- a/DirectInputExplorer~/DirectInputExplorer/Form1.resx +++ b/DirectInputExplorer~/DirectInputExplorer/Form1.resx @@ -1,4 +1,64 @@ -īģŋ +īģŋ + + diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.dll b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.dll index 797b767..54c136c 100644 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.dll and b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.dll differ diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.exe b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.exe index e39c1fe..9492934 100644 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.exe and b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.exe differ diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.runtimeconfig.dev.json b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.runtimeconfig.dev.json deleted file mode 100644 index 6c11489..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputExplorer.runtimeconfig.dev.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "runtimeOptions": { - "additionalProbingPaths": [ - "C:\\Users\\Ducky\\.dotnet\\store\\|arch|\\|tfm|", - "C:\\Users\\Ducky\\.nuget\\packages" - ] - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.deps.json b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.deps.json deleted file mode 100644 index db09ea9..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.deps.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v5.0": { - "DirectInputForceFeedbackDemoApp/1.0.0": { - "runtime": { - "DirectInputForceFeedbackDemoApp.dll": {} - } - } - } - }, - "libraries": { - "DirectInputForceFeedbackDemoApp/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll deleted file mode 100644 index 3a7d9c1..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.exe b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.exe deleted file mode 100644 index 44ec441..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.exe and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.dev.json b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.dev.json deleted file mode 100644 index 6c11489..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.dev.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "runtimeOptions": { - "additionalProbingPaths": [ - "C:\\Users\\Ducky\\.dotnet\\store\\|arch|\\|tfm|", - "C:\\Users\\Ducky\\.nuget\\packages" - ] - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.json b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.json deleted file mode 100644 index dae617c..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.runtimeconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net5.0", - "framework": { - "name": "Microsoft.WindowsDesktop.App", - "version": "5.0.0" - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputExplorer.dll b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputExplorer.dll deleted file mode 100644 index 672956d..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputExplorer.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll b/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll deleted file mode 100644 index 36b539c..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/bin/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs deleted file mode 100644 index 3b1554c..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -// -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = ".NET 5.0")] diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.AssemblyInfo.cs b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.AssemblyInfo.cs deleted file mode 100644 index c95c71c..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.AssemblyInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System; -using System.Reflection; - -[assembly: System.Reflection.AssemblyCompanyAttribute("DirectInputExplorer")] -[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] -[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] -[assembly: System.Reflection.AssemblyProductAttribute("DirectInputExplorer")] -[assembly: System.Reflection.AssemblyTitleAttribute("DirectInputExplorer")] -[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] -[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] -[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")] - -// Generated by the MSBuild WriteCodeFragment class. - diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.Form1.resources b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.Form1.resources deleted file mode 100644 index 6c05a97..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.Form1.resources and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig deleted file mode 100644 index 5f52e58..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -is_global = true -build_property.ApplicationManifest = -build_property.StartupObject = -build_property.ApplicationDefaultFont = -build_property.ApplicationHighDpiMode = -build_property.ApplicationUseCompatibleTextRendering = -build_property.ApplicationVisualStyles = -build_property.TargetFramework = net5.0-windows -build_property.TargetPlatformMinVersion = 7.0 -build_property.UsingMicrosoftNETSdkWeb = -build_property.ProjectTypeGuids = -build_property.InvariantGlobalization = -build_property.PlatformNeutralAssembly = -build_property.EnforceExtendedAnalyzerRules = -build_property._SupportedPlatformList = Linux,macOS,Windows -build_property.RootNamespace = DirectInputExplorer -build_property.ProjectDir = C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.csproj.BuildWithSkipAnalyzers b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.csproj.BuildWithSkipAnalyzers deleted file mode 100644 index e69de29..0000000 diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.csproj.FileListAbsolute.txt b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.csproj.FileListAbsolute.txt deleted file mode 100644 index 8b24315..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,54 +0,0 @@ -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.exe -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.deps.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.dev.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\ref\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.AssemblyReference.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.Form1.resources -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.GenerateResource.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfoInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfo.cs -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.CoreCompileInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\ref\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputExplorer\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.genruntimeconfig.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.AssemblyReference.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.Form1.resources -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.GenerateResource.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfoInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfo.cs -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.CoreCompileInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\ref\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.exe -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.deps.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.dev.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\ref\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.genruntimeconfig.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.exe -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.deps.json -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.json -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.runtimeconfig.dev.json -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\bin\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.AssemblyReference.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.Form1.resources -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.GenerateResource.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.GeneratedMSBuildEditorConfig.editorconfig -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfoInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.AssemblyInfo.cs -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.csproj.CoreCompileInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\refint\DirectInputExplorer.dll -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.pdb -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\DirectInputExplorer.genruntimeconfig.cache -C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputExplorer~\DirectInputExplorer\obj\Debug\net5.0-windows\ref\DirectInputExplorer.dll diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.deps.json b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.deps.json deleted file mode 100644 index 74b9003..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.deps.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v5.0": {} - }, - "libraries": {} -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.runtimeconfig.json b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.runtimeconfig.json deleted file mode 100644 index bfd2041..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.designer.runtimeconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net5.0", - "framework": { - "name": "Microsoft.WindowsDesktop.App", - "version": "5.0.0" - }, - "additionalProbingPaths": [ - "C:\\Users\\Ducky\\.dotnet\\store\\|arch|\\|tfm|", - "C:\\Users\\Ducky\\.nuget\\packages" - ], - "configProperties": { - "Microsoft.NETCore.DotNetHostPolicy.SetAppPaths": true - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.dll b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.dll deleted file mode 100644 index 797b767..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputExplorer.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.AssemblyInfo.cs b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.AssemblyInfo.cs deleted file mode 100644 index 9a1a369..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.AssemblyInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System; -using System.Reflection; - -[assembly: System.Reflection.AssemblyCompanyAttribute("DirectInputForceFeedbackDemoApp")] -[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] -[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] -[assembly: System.Reflection.AssemblyProductAttribute("DirectInputForceFeedbackDemoApp")] -[assembly: System.Reflection.AssemblyTitleAttribute("DirectInputForceFeedbackDemoApp")] -[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] -[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] -[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")] - -// Generated by the MSBuild WriteCodeFragment class. - diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.Form1.resources b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.Form1.resources deleted file mode 100644 index 6c05a97..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.Form1.resources and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.GeneratedMSBuildEditorConfig.editorconfig b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.GeneratedMSBuildEditorConfig.editorconfig deleted file mode 100644 index 7694274..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.GeneratedMSBuildEditorConfig.editorconfig +++ /dev/null @@ -1,8 +0,0 @@ -is_global = true -build_property.TargetFramework = net5.0-windows -build_property.TargetPlatformMinVersion = 7.0 -build_property.UsingMicrosoftNETSdkWeb = -build_property.ProjectTypeGuids = -build_property.PublishSingleFile = -build_property.IncludeAllContentForSelfExtract = -build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.csproj.FileListAbsolute.txt b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.csproj.FileListAbsolute.txt deleted file mode 100644 index f57f6c9..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,36 +0,0 @@ -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.exe -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.deps.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.runtimeconfig.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.runtimeconfig.dev.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\ref\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.AssemblyReference.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.Form1.resources -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.GenerateResource.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.GeneratedMSBuildEditorConfig.editorconfig -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.AssemblyInfoInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.AssemblyInfo.cs -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.CoreCompileInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\ref\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.genruntimeconfig.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.exe -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.deps.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.runtimeconfig.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.runtimeconfig.dev.json -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\ref\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\bin\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.AssemblyReference.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.Form1.resources -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.GenerateResource.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.GeneratedMSBuildEditorConfig.editorconfig -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.AssemblyInfoInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.AssemblyInfo.cs -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.csproj.CoreCompileInputs.cache -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\ref\DirectInputForceFeedbackDemoApp.dll -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.pdb -C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedbackDemoApp\DirectInputForceFeedbackDemoApp\obj\Debug\net5.0-windows\DirectInputForceFeedbackDemoApp.genruntimeconfig.cache diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.deps.json b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.deps.json deleted file mode 100644 index 74b9003..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.deps.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v5.0": {} - }, - "libraries": {} -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.runtimeconfig.json b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.runtimeconfig.json deleted file mode 100644 index bfd2041..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.designer.runtimeconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net5.0", - "framework": { - "name": "Microsoft.WindowsDesktop.App", - "version": "5.0.0" - }, - "additionalProbingPaths": [ - "C:\\Users\\Ducky\\.dotnet\\store\\|arch|\\|tfm|", - "C:\\Users\\Ducky\\.nuget\\packages" - ], - "configProperties": { - "Microsoft.NETCore.DotNetHostPolicy.SetAppPaths": true - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll deleted file mode 100644 index 3a7d9c1..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/DirectInputForceFeedbackDemoApp.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/apphost.exe b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/apphost.exe deleted file mode 100644 index e39c1fe..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/apphost.exe and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputExplorer.dll b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputExplorer.dll deleted file mode 100644 index aa73451..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputExplorer.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll deleted file mode 100644 index 36b539c..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/ref/DirectInputForceFeedbackDemoApp.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/refint/DirectInputExplorer.dll b/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/refint/DirectInputExplorer.dll deleted file mode 100644 index aa73451..0000000 Binary files a/DirectInputExplorer~/DirectInputExplorer/obj/Debug/net5.0-windows/refint/DirectInputExplorer.dll and /dev/null differ diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.dgspec.json b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.dgspec.json deleted file mode 100644 index 873059a..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.dgspec.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "format": 1, - "restore": { - "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj": {} - }, - "projects": { - "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj", - "projectName": "DirectInputExplorer", - "projectPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj", - "packagesPath": "C:\\Users\\Ducky\\.nuget\\packages\\", - "outputPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\obj\\", - "projectStyle": "PackageReference", - "configFilePaths": [ - "C:\\Users\\Ducky\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" - ], - "originalTargetFrameworks": [ - "net5.0-windows" - ], - "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "downloadDependencies": [ - { - "name": "Microsoft.NETCore.App.Host.win-x64", - "version": "[5.0.17, 5.0.17]" - } - ], - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - }, - "Microsoft.WindowsDesktop.App.WindowsForms": { - "privateAssets": "none" - } - }, - "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.100\\RuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.props b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.props deleted file mode 100644 index 405add7..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.props +++ /dev/null @@ -1,15 +0,0 @@ -īģŋ - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\Ducky\.nuget\packages\ - PackageReference - 6.4.0 - - - - - \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.targets b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.targets deleted file mode 100644 index 3dc06ef..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputExplorer.csproj.nuget.g.targets +++ /dev/null @@ -1,2 +0,0 @@ -īģŋ - \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.dgspec.json b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.dgspec.json deleted file mode 100644 index 259aa3e..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.dgspec.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "format": 1, - "restore": { - "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-ForceFeedback\\~DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp.csproj": {} - }, - "projects": { - "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-ForceFeedback\\~DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-ForceFeedback\\~DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp.csproj", - "projectName": "DirectInputForceFeedbackDemoApp", - "projectPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-ForceFeedback\\~DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp.csproj", - "packagesPath": "C:\\Users\\Ducky\\.nuget\\packages\\", - "outputPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-ForceFeedback\\~DirectInputForceFeedbackDemoApp\\DirectInputForceFeedbackDemoApp\\obj\\", - "projectStyle": "PackageReference", - "configFilePaths": [ - "C:\\Users\\Ducky\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" - ], - "originalTargetFrameworks": [ - "net5.0-windows7.0" - ], - "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - }, - "Microsoft.WindowsDesktop.App.WindowsForms": { - "privateAssets": "none" - } - }, - "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\5.0.301\\RuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.props b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.props deleted file mode 100644 index 8936ed3..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.props +++ /dev/null @@ -1,18 +0,0 @@ -īģŋ - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\Ducky\.nuget\packages\ - PackageReference - 5.10.0 - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.targets b/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.targets deleted file mode 100644 index 53cfaa1..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/DirectInputForceFeedbackDemoApp.csproj.nuget.g.targets +++ /dev/null @@ -1,6 +0,0 @@ -īģŋ - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - \ No newline at end of file diff --git a/DirectInputExplorer~/DirectInputExplorer/obj/project.assets.json b/DirectInputExplorer~/DirectInputExplorer/obj/project.assets.json deleted file mode 100644 index 7a4c022..0000000 --- a/DirectInputExplorer~/DirectInputExplorer/obj/project.assets.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "version": 3, - "targets": { - "net5.0-windows7.0": {} - }, - "libraries": {}, - "projectFileDependencyGroups": { - "net5.0-windows7.0": [] - }, - "packageFolders": { - "C:\\Users\\Ducky\\.nuget\\packages\\": {} - }, - "project": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj", - "projectName": "DirectInputExplorer", - "projectPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\DirectInputExplorer.csproj", - "packagesPath": "C:\\Users\\Ducky\\.nuget\\packages\\", - "outputPath": "C:\\Users\\Ducky\\Documents\\GitHub\\Unity-DirectInput\\DirectInputExplorer~\\DirectInputExplorer\\obj\\", - "projectStyle": "PackageReference", - "configFilePaths": [ - "C:\\Users\\Ducky\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" - ], - "originalTargetFrameworks": [ - "net5.0-windows" - ], - "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net5.0-windows7.0": { - "targetAlias": "net5.0-windows", - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "downloadDependencies": [ - { - "name": "Microsoft.NETCore.App.Host.win-x64", - "version": "[5.0.17, 5.0.17]" - } - ], - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - }, - "Microsoft.WindowsDesktop.App.WindowsForms": { - "privateAssets": "none" - } - }, - "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.100\\RuntimeIdentifierGraph.json" - } - } - } -} \ No newline at end of file diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/DirectInputForceFeedback.dll.recipe b/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/DirectInputForceFeedback.dll.recipe deleted file mode 100644 index 6d6e576..0000000 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/DirectInputForceFeedback.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ -īģŋ - - - - C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedback\Debug\DirectInputForceFeedback.dll - - - - - - \ No newline at end of file diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/vc142.idb b/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/vc142.idb deleted file mode 100644 index 4e3db29..0000000 Binary files a/DirectInputForceFeedback~/DirectInputForceFeedback/Debug/vc142.idb and /dev/null differ diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.cpp b/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.cpp index b1d88e7..b932a5a 100644 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.cpp +++ b/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.cpp @@ -1,5 +1,7 @@ // DirectInputForceFeedback.cpp : Defines the exported functions for the DLL. #include "pch.h" +#include // for std::clamp +#include // for UINT16_MAX #include "DirectInputForceFeedback.h" typedef std::string DeviceGUID; // Alias to make it clearer what maps below use as key @@ -21,427 +23,624 @@ std::vector DEBUGDATA; // Used for Debugging during development // Create the _DirectInput global HRESULT StartDirectInput() { - if (_DirectInput != NULL) { return S_OK; } // Already initialised - - // Setup Device Change Detection (Add/Remove Device Events) - SetWindowsHookExW(WH_CALLWNDPROC, (HOOKPROC)&_WindowsHookCallback, GetModuleHandleW(NULL), GetCurrentThreadId()); - - return DirectInput8Create( // Create DirectInput - GetModuleHandle(NULL), - DIRECTINPUT_VERSION, - IID_IDirectInput8, - (void**)&_DirectInput, // Place our DirectInput instance in _DirectInput - NULL - ); + if (_DirectInput != NULL) { return S_OK; } // Already initialised + + // Setup Device Change Detection (Add/Remove Device Events) + SetWindowsHookExW(WH_CALLWNDPROC, (HOOKPROC)&_WindowsHookCallback, GetModuleHandleW(NULL), GetCurrentThreadId()); + + return DirectInput8Create( // Create DirectInput + GetModuleHandle(NULL), + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&_DirectInput, // Place our DirectInput instance in _DirectInput + NULL + ); } // Stop _DirectInput HRESULT StopDirectInput() { - HRESULT hr = E_FAIL; - if (_DirectInput == NULL) { return hr = S_OK; } // No DirectInput Instance + HRESULT hr = E_FAIL; + if (_DirectInput == NULL) { return hr = S_OK; } // No DirectInput Instance - for (const auto& [GUIDString, Device] : _ActiveDevices) { // For each device - // TODO: Stop Effects? - if (FAILED(hr = Device->Unacquire())) { return hr; } - } + for (const auto& [GUIDString, Device] : _ActiveDevices) { // For each device + // TODO: Stop Effects? + if (FAILED(hr = Device->Unacquire())) { return hr; } + } - _DeviceInstances.clear(); - _ActiveDevices.clear(); - _DeviceEnumeratedEffects.clear(); - _DeviceFFBAxes.clear(); - _DeviceFFBEffectConfig.clear(); - _DeviceFFBEffectControl.clear(); + _DeviceInstances.clear(); + _ActiveDevices.clear(); + _DeviceEnumeratedEffects.clear(); + _DeviceFFBAxes.clear(); + _DeviceFFBEffectConfig.clear(); + _DeviceFFBEffectControl.clear(); - _DirectInput = NULL; + _DirectInput = NULL; - return hr; + return hr; } // Return a vector of all attached devices DeviceInfo* EnumerateDevices(/*[out]*/ int& deviceCount) { - HRESULT hr = E_FAIL; - if (_DirectInput == NULL) { return NULL; } // If DI not ready, return nothing - _DeviceInstances.clear(); // Clear devices - - // First fetch all devices - hr = _DirectInput->EnumDevices( // Invoke device enumeration to the _EnumDevicesCallback callback - DI8DEVCLASS_GAMECTRL, // List devices of type GameController - _EnumDevicesCallback, // Callback executed for each device found - NULL, // Passed to callback as optional arg - DIEDFL_ATTACHEDONLY //| DIEDFL_FORCEFEEDBACK - ); - - // Next update FFB devices (Important this happens after as it modifies existing entries) - hr = _DirectInput->EnumDevices( // Invoke device enumeration to the _EnumDevicesCallback callback - DI8DEVCLASS_GAMECTRL, // List devices of type GameController - _EnumDevicesCallbackFFB, // Callback executed for each device found - NULL, // Passed to callback as optional arg - DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK - ); - - if (_DeviceInstances.size() > 0) { - deviceCount = (int)_DeviceInstances.size(); - return &_DeviceInstances[0]; // Return 1st element, structure size & deviceCount are used to find next elements - } else { - deviceCount = 0; - } - return NULL; + HRESULT hr = E_FAIL; + if (_DirectInput == NULL) { return NULL; } // If DI not ready, return nothing + _DeviceInstances.clear(); // Clear devices + + // First fetch all devices + hr = _DirectInput->EnumDevices( // Invoke device enumeration to the _EnumDevicesCallback callback + DI8DEVCLASS_GAMECTRL, // List devices of type GameController + _EnumDevicesCallback, // Callback executed for each device found + NULL, // Passed to callback as optional arg + DIEDFL_ATTACHEDONLY //| DIEDFL_FORCEFEEDBACK + ); + + // Next update FFB devices (Important this happens after as it modifies existing entries) + hr = _DirectInput->EnumDevices( // Invoke device enumeration to the _EnumDevicesCallback callback + DI8DEVCLASS_GAMECTRL, // List devices of type GameController + _EnumDevicesCallbackFFB, // Callback executed for each device found + NULL, // Passed to callback as optional arg + DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK + ); + + if (_DeviceInstances.size() > 0) { + deviceCount = (int)_DeviceInstances.size(); + return &_DeviceInstances[0]; // Return 1st element, structure size & deviceCount are used to find next elements + } + else { + deviceCount = 0; + } + return NULL; } // Create the DirectInput Device and Acquire ready for State retreval & FFB Effects (Requires Cooperation level Exclusive) // Pass the GUID (as a string) of the Device you'd like to attach to, GUID obtained from the Enumerated Devices HRESULT CreateDevice(LPCSTR guidInstance) { - HRESULT hr; - DestroyDeviceIfExists(guidInstance); // If device exists, clear it first + HRESULT hr; + DestroyDeviceIfExists(guidInstance); // If device exists, clear it first - LPDIRECTINPUTDEVICE8 DIDevice; - if (FAILED(hr = _DirectInput->CreateDevice(LPCSTRGUIDtoGUID(guidInstance), &DIDevice, NULL))) { return hr; } - if (FAILED(hr = DIDevice->SetDataFormat(&c_dfDIJoystick2))) { return hr; } - if (FAILED(hr = DIDevice->SetCooperativeLevel(FindMainWindow(GetCurrentProcessId()), DISCL_EXCLUSIVE | DISCL_BACKGROUND))) { return hr; } - if (FAILED(hr = DIDevice->Acquire())) { return hr; } + LPDIRECTINPUTDEVICE8 DIDevice; + if (FAILED(hr = _DirectInput->CreateDevice(LPCSTRGUIDtoGUID(guidInstance), &DIDevice, NULL))) { return hr; } + if (FAILED(hr = DIDevice->SetDataFormat(&c_dfDIJoystick2))) { return hr; } + if (FAILED(hr = DIDevice->SetCooperativeLevel(FindMainWindow(GetCurrentProcessId()), DISCL_EXCLUSIVE | DISCL_BACKGROUND))) { return hr; } + if (FAILED(hr = DIDevice->Acquire())) { return hr; } - std::string GUIDString((LPCSTR)guidInstance); // Convert the LPCSTR to a STL String for use as key in map (String as GUID has no operater<) - _ActiveDevices[GUIDString] = DIDevice; // Store Device in _ActiveDevices Map to be referenced later + std::string GUIDString((LPCSTR)guidInstance); // Convert the LPCSTR to a STL String for use as key in map (String as GUID has no operater<) + _ActiveDevices[GUIDString] = DIDevice; // Store Device in _ActiveDevices Map to be referenced later - return hr; + return hr; } // Remove the DirectInput Device, Unacquire and remove from ActiveDevices HRESULT DestroyDevice(LPCSTR guidInstance) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - StopAllFFBEffects(guidInstance); - if (SUCCEEDED(hr = _ActiveDevices[GUIDString]->Unacquire())) { - _ActiveDevices.erase(GUIDString); - } + StopAllFFBEffects(guidInstance); + if (SUCCEEDED(hr = _ActiveDevices[GUIDString]->Unacquire())) { + _ActiveDevices.erase(GUIDString); + } - return hr; + return hr; } // Fetch the Device State, give GUID of the Device (Must already be created by CreateDevice) and out FlatJoyState2 HRESULT GetDeviceState(LPCSTR guidInstance, /*[out]*/ FlatJoyState2& deviceState) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - DIJOYSTATE2 DeviceStateRaw; - hr = _ActiveDevices[GUIDString]->GetDeviceState(sizeof(DIJOYSTATE2), &DeviceStateRaw); // Fetch the device State - deviceState = FlattenDIJOYSTATE2(DeviceStateRaw); // Convert to a friendlier format (Nested arrays are more difficult to check for change) + DIJOYSTATE2 DeviceStateRaw = {}; + hr = _ActiveDevices[GUIDString]->GetDeviceState(sizeof(DIJOYSTATE2), &DeviceStateRaw); // Fetch the device State + deviceState = FlattenDIJOYSTATE2(DeviceStateRaw); // Convert to a friendlier format (Nested arrays are more difficult to check for change) - return hr; + return hr; } // Fetch the Device State, give GUID of the Device (Must already be created by CreateDevice) and out DIJOYSTATE2 HRESULT GetDeviceStateRaw(LPCSTR guidInstance, /*[out]*/ DIJOYSTATE2& deviceState) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - hr = _ActiveDevices[GUIDString]->GetDeviceState(sizeof(DIJOYSTATE2), &deviceState); // Fetch the device State + hr = _ActiveDevices[GUIDString]->GetDeviceState(sizeof(DIJOYSTATE2), &deviceState); // Fetch the device State - return hr; + return hr; } // Fetch the capabilities of the device, returns DIDEVCAPS see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416607(v=vs.85) HRESULT GetDeviceCapabilities(LPCSTR guidInstance, /*[out]*/ DIDEVCAPS& deviceCapabilitiesOut) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - DIDEVCAPS DeviceCapabilities; - DeviceCapabilities.dwSize = sizeof(DIDEVCAPS); - hr = _ActiveDevices[GUIDString]->GetCapabilities(&DeviceCapabilities); - deviceCapabilitiesOut = DeviceCapabilities; + DIDEVCAPS DeviceCapabilities; + DeviceCapabilities.dwSize = sizeof(DIDEVCAPS); + hr = _ActiveDevices[GUIDString]->GetCapabilities(&DeviceCapabilities); + deviceCapabilitiesOut = DeviceCapabilities; - return hr; + return hr; } // Generate SAFEARRAY of ActiveDevice GUIDs -HRESULT GetActiveDevices(/*[out]*/ SAFEARRAY** activeGUIDs){ - HRESULT hr = E_FAIL; +HRESULT GetActiveDevices(/*[out]*/ SAFEARRAY** activeGUIDs) { + HRESULT hr = E_FAIL; - std::vector SAData; - for (const auto& [GUIDString, Device] : _ActiveDevices) { - SAData.push_back( string_to_wstring(GUIDString) ); - } + std::vector SAData; + for (const auto& [GUIDString, Device] : _ActiveDevices) { + SAData.push_back(string_to_wstring(GUIDString)); + } - hr = BuildSafeArray(SAData, activeGUIDs); - return hr; + hr = BuildSafeArray(SAData, activeGUIDs); + return hr; } // Set the Autocenter property for a DI device, pass device GUID and bool to enable or disable HRESULT SetAutocenter(LPCSTR guidInstance, bool AutocenterState) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - DIPROPDWORD DIPropAutoCenter; + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + DIPROPDWORD DIPropAutoCenter = {}; - DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); - DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER); - DIPropAutoCenter.diph.dwObj = 0; - DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; - DIPropAutoCenter.dwData = AutocenterState ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF; + DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); + DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER); + DIPropAutoCenter.diph.dwObj = 0; + DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; + DIPropAutoCenter.dwData = AutocenterState ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF; - hr = _ActiveDevices[GUIDString]->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); + hr = _ActiveDevices[GUIDString]->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); - return hr; + return hr; } // Generate SAFEARRAY of possible FFB Effects for this Device HRESULT EnumerateFFBEffects(LPCSTR guidInstance, /*[out]*/ SAFEARRAY** FFBEffects) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - _DeviceEnumeratedEffects[GUIDString].clear(); // Clear effects for this device - hr = _ActiveDevices[GUIDString]->EnumEffects(&_EnumFFBEffectsCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceEnumeratedEffects with key as device's GUID + _DeviceEnumeratedEffects[GUIDString].clear(); // Clear effects for this device + hr = _ActiveDevices[GUIDString]->EnumEffects(&_EnumFFBEffectsCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceEnumeratedEffects with key as device's GUID - // Generate SafeArray of supported effects - std::vector SAData; // Store what will be in the SafeArray - for (const auto& Effect : _DeviceEnumeratedEffects[GUIDString]) { - SAData.push_back(Effect.tszName); // Add each effect name - } - hr = BuildSafeArray(SAData, FFBEffects); + // Generate SafeArray of supported effects + std::vector SAData; // Store what will be in the SafeArray + for (const auto& Effect : _DeviceEnumeratedEffects[GUIDString]) { + SAData.push_back(Effect.tszName); // Add each effect name + } + hr = BuildSafeArray(SAData, FFBEffects); - return hr; + return hr; } // Generate SAFEARRAY of possible FFB Effects for this Device HRESULT EnumerateFFBAxes(LPCSTR guidInstance, /*[out]*/ SAFEARRAY** FFBAxes) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - - _DeviceFFBAxes[GUIDString].clear(); // Clear Axes info for this device - hr = _ActiveDevices[GUIDString]->EnumObjects(&_EnumFFBAxisCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceFFBAxes with key as device's GUID - - // Generate SafeArray of FFB Axes - std::vector SAData; // Store what will be in the SafeArray - SAData.push_back(L"FFB Axes: " + std::to_wstring(_DeviceFFBAxes.size())); - for (const auto& ObjectInst : _DeviceFFBAxes[GUIDString]) { - - wchar_t szGUID[64] = { 0 }; - (void)StringFromGUID2(ObjectInst.guidType, szGUID, 64); // Void cast ignores [[nodiscard]] warning - std::wstring guidType(szGUID); - - SAData.push_back(ObjectInst.tszName); // Add each effect name - SAData.push_back(L"dwSize: " + std::to_wstring(ObjectInst.dwSize)); - SAData.push_back(L"guidType: " + guidType); - SAData.push_back(L"dwOfs: " + std::to_wstring(ObjectInst.dwOfs)); - SAData.push_back(L"dwType: " + std::to_wstring(ObjectInst.dwType)); - SAData.push_back(L"dwFlags: " + std::to_wstring(ObjectInst.dwFlags)); - SAData.push_back(L"dwFFMaxForce: " + std::to_wstring(ObjectInst.dwFFMaxForce)); - SAData.push_back(L"dwFFForceResolution: " + std::to_wstring(ObjectInst.dwFFForceResolution)); - SAData.push_back(L"wCollectionNumber: " + std::to_wstring(ObjectInst.wCollectionNumber)); - SAData.push_back(L"wDesignatorIndex: " + std::to_wstring(ObjectInst.wDesignatorIndex)); - SAData.push_back(L"wUsagePage: " + std::to_wstring(ObjectInst.wUsagePage)); - SAData.push_back(L"wUsage: " + std::to_wstring(ObjectInst.wUsage)); - SAData.push_back(L"dwDimension: " + std::to_wstring(ObjectInst.dwDimension)); - SAData.push_back(L"wExponent: " + std::to_wstring(ObjectInst.wExponent)); - SAData.push_back(L"wReportId: " + std::to_wstring(ObjectInst.wReportId)); - } - hr = BuildSafeArray(SAData, FFBAxes); - - return hr; + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + + _DeviceFFBAxes[GUIDString].clear(); // Clear Axes info for this device + hr = _ActiveDevices[GUIDString]->EnumObjects(&_EnumFFBAxisCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceFFBAxes with key as device's GUID + + // Generate SafeArray of FFB Axes + std::vector SAData; // Store what will be in the SafeArray + SAData.push_back(L"FFB Axes: " + std::to_wstring(_DeviceFFBAxes.size())); + for (const auto& ObjectInst : _DeviceFFBAxes[GUIDString]) { + + wchar_t szGUID[64] = { 0 }; + (void)StringFromGUID2(ObjectInst.guidType, szGUID, 64); // Void cast ignores [[nodiscard]] warning + std::wstring guidType(szGUID); + + SAData.push_back(ObjectInst.tszName); // Add each effect name + SAData.push_back(L"dwSize: " + std::to_wstring(ObjectInst.dwSize)); + SAData.push_back(L"guidType: " + guidType); + SAData.push_back(L"dwOfs: " + std::to_wstring(ObjectInst.dwOfs)); + SAData.push_back(L"dwType: " + std::to_wstring(ObjectInst.dwType)); + SAData.push_back(L"dwFlags: " + std::to_wstring(ObjectInst.dwFlags)); + SAData.push_back(L"dwFFMaxForce: " + std::to_wstring(ObjectInst.dwFFMaxForce)); + SAData.push_back(L"dwFFForceResolution: " + std::to_wstring(ObjectInst.dwFFForceResolution)); + SAData.push_back(L"wCollectionNumber: " + std::to_wstring(ObjectInst.wCollectionNumber)); + SAData.push_back(L"wDesignatorIndex: " + std::to_wstring(ObjectInst.wDesignatorIndex)); + SAData.push_back(L"wUsagePage: " + std::to_wstring(ObjectInst.wUsagePage)); + SAData.push_back(L"wUsage: " + std::to_wstring(ObjectInst.wUsage)); + SAData.push_back(L"dwDimension: " + std::to_wstring(ObjectInst.dwDimension)); + SAData.push_back(L"wExponent: " + std::to_wstring(ObjectInst.wExponent)); + SAData.push_back(L"wReportId: " + std::to_wstring(ObjectInst.wReportId)); + } + hr = BuildSafeArray(SAData, FFBAxes); + + return hr; } // Creates/Enables the Effect on the device HRESULT CreateFFBEffect(LPCSTR guidInstance, Effects::Type effectType) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - - if (_DeviceFFBEffectControl[GUIDString].contains(effectType)) { return E_ABORT; } // Effect Already Exists on Device - - //Enumerate FFBAxes if not already - if (!_DeviceFFBAxes.contains(GUIDString)) { - _DeviceFFBAxes[GUIDString].clear(); // Clear Axes info for this device - hr = _ActiveDevices[GUIDString]->EnumObjects(&_EnumFFBAxisCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceFFBAxes with key as device's GUID - } - - - - int FFBAxesCount = (int)_DeviceFFBAxes[GUIDString].size(); - DWORD* FFBAxes = new DWORD[FFBAxesCount]; - LONG* FFBDirections = new LONG[FFBAxesCount]; - - for (int idx = 0; idx < FFBAxesCount; idx++) { - FFBAxes[idx] = AxisTypeToDIJOFS(_DeviceFFBAxes[GUIDString][idx].guidType); // FFB Axis GUID to DirectInput representation - FFBDirections[idx] = 0; // Init this axis - } - - // Create the Effect - - DICONSTANTFORCE* constantForce = NULL; - DICONDITION* conditions = NULL; - DIEFFECT effect = {}; // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416616(v=vs.85) - effect.dwSize = sizeof(DIEFFECT); - effect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - effect.dwDuration = INFINITE; - effect.dwSamplePeriod = 0; - effect.dwGain = DI_FFNOMINALMAX; - effect.dwTriggerButton = DIEB_NOTRIGGER; // Start effect without requiring a button press - effect.dwTriggerRepeatInterval = 0; - effect.cAxes = FFBAxesCount; // How many Axes will the effect be on (cannot be changed once it has been set) - effect.rgdwAxes = FFBAxes; // Identifies the axes to which the effects will be applied (cannot be changed once it has been set) - effect.rglDirection = FFBDirections; // Distribution of effect strength between Axes? - effect.lpEnvelope = 0; - effect.dwStartDelay = 0; - - - - switch (effectType) { - case Effects::Type::ConstantForce: - constantForce = new DICONSTANTFORCE(); - constantForce->lMagnitude = 0; - effect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - effect.lpvTypeSpecificParams = constantForce; - break; - - case Effects::Type::Spring: - conditions = new DICONDITION[FFBAxesCount]; - ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); - effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; - effect.lpvTypeSpecificParams = conditions; - break; - - case Effects::Type::Damper: - conditions = new DICONDITION[FFBAxesCount]; - ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); - effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; - effect.lpvTypeSpecificParams = conditions; - break; - - case Effects::Type::Friction: - conditions = new DICONDITION[FFBAxesCount]; - ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); - effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; - effect.lpvTypeSpecificParams = conditions; - break; - - case Effects::Type::Inertia: - conditions = new DICONDITION[FFBAxesCount]; - ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); - effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; - effect.lpvTypeSpecificParams = conditions; - break; - - default: - return E_FAIL; // Unsupported Effect - } - - LPDIRECTINPUTEFFECT effectControl; - if (FAILED(hr = _ActiveDevices[GUIDString]->CreateEffect(EffectTypeToGUID(effectType), &effect, &effectControl, nullptr))) { return hr; } - if (FAILED(hr = effectControl->Start(1, 0))) { return hr; } - _DeviceFFBEffectConfig[GUIDString][effectType] = effect; - _DeviceFFBEffectControl[GUIDString][effectType] = effectControl; - - return hr; + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + + if (_DeviceFFBEffectControl[GUIDString].contains(effectType)) { return E_ABORT; } // Effect Already Exists on Device + + //Enumerate FFBAxes if not already + if (!_DeviceFFBAxes.contains(GUIDString)) { + _DeviceFFBAxes[GUIDString].clear(); // Clear Axes info for this device + hr = _ActiveDevices[GUIDString]->EnumObjects(&_EnumFFBAxisCallback, &GUIDString, DIEFT_ALL); // Callback adds each effect to _DeviceFFBAxes with key as device's GUID + } + + + + int FFBAxesCount = (int)_DeviceFFBAxes[GUIDString].size(); + DWORD* FFBAxes = new DWORD[FFBAxesCount]; + LONG* FFBDirections = new LONG[FFBAxesCount]; + + for (int idx = 0; idx < FFBAxesCount; idx++) { + FFBAxes[idx] = AxisTypeToDIJOFS(_DeviceFFBAxes[GUIDString][idx].guidType); // FFB Axis GUID to DirectInput representation + FFBDirections[idx] = 0; // Init this axis + } + + // Create the Effect + + DICONSTANTFORCE* constantForce = NULL; + DICONDITION* conditions = NULL; + DIRAMPFORCE* rampForce = new DIRAMPFORCE(); + DIPERIODIC* periodicForce = new DIPERIODIC(); + DICUSTOMFORCE* customForce = new DICUSTOMFORCE(); + LPDIRECTINPUTEFFECT effectControl; + DIEFFECT effect = {}; // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416616(v=vs.85) + effect.dwSize = sizeof(DIEFFECT); + effect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + effect.dwDuration = INFINITE; + effect.dwSamplePeriod = 0; + effect.dwGain = DI_FFNOMINALMAX; + effect.dwTriggerButton = DIEB_NOTRIGGER; // Start effect without requiring a button press + effect.dwTriggerRepeatInterval = 0; + effect.cAxes = FFBAxesCount; // How many Axes will the effect be on (cannot be changed once it has been set) + effect.rgdwAxes = FFBAxes; // Identifies the axes to which the effects will be applied (cannot be changed once it has been set) + effect.rglDirection = FFBDirections; // Distribution of effect strength between Axes? + effect.lpEnvelope = 0; + effect.dwStartDelay = 0; + + + + switch (effectType) { + case Effects::Type::ConstantForce: + constantForce = new DICONSTANTFORCE(); + constantForce->lMagnitude = 0; + effect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + effect.lpvTypeSpecificParams = constantForce; + break; + + case Effects::Type::Spring: + conditions = new DICONDITION[FFBAxesCount]; + ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); + effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; + effect.lpvTypeSpecificParams = conditions; + break; + + case Effects::Type::Damper: + conditions = new DICONDITION[FFBAxesCount]; + ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); + effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; + effect.lpvTypeSpecificParams = conditions; + break; + + case Effects::Type::Friction: + conditions = new DICONDITION[FFBAxesCount]; + ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); + effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; + effect.lpvTypeSpecificParams = conditions; + break; + + case Effects::Type::Inertia: + conditions = new DICONDITION[FFBAxesCount]; + ZeroMemory(conditions, sizeof(DICONDITION) * FFBAxesCount); + effect.cbTypeSpecificParams = sizeof(DICONDITION) * FFBAxesCount; + effect.lpvTypeSpecificParams = conditions; + break; + case Effects::Type::Sine: + case Effects::Type::Square: + case Effects::Type::Triangle: + case Effects::Type::SawtoothUp: + case Effects::Type::SawtoothDown: + ZeroMemory(periodicForce, sizeof(DIPERIODIC)); + periodicForce->dwMagnitude = 0; + periodicForce->lOffset = 0; + periodicForce->dwPhase = 0; + periodicForce->dwPeriod = 30000; + effect.cbTypeSpecificParams = sizeof(DIPERIODIC); + effect.lpvTypeSpecificParams = periodicForce; + break; + case Effects::Type::RampForce: + ZeroMemory(rampForce, sizeof(DIRAMPFORCE)); + rampForce->lStart = 0; + rampForce->lEnd = 0; + effect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); + effect.lpvTypeSpecificParams = rampForce; + break; + case Effects::Type::CustomForce: { + FILE* debugFile; + fopen_s(&debugFile, "ffb_custom_debug.txt", "a"); + fprintf(debugFile, "\n=== Custom Force Creation Debug ===\n"); + fprintf(debugFile, "Time: %s\n", __TIMESTAMP__); + + // Get device capabilities + DIDEVCAPS deviceCaps = {}; + deviceCaps.dwSize = sizeof(DIDEVCAPS); + if (FAILED(_ActiveDevices[GUIDString]->GetCapabilities(&deviceCaps))) { + fprintf(debugFile, "Failed to get device capabilities\n"); + fclose(debugFile); + return E_FAIL; + } + + fprintf(debugFile, "Device Capabilities:\n"); + fprintf(debugFile, "- FFSamplePeriod: %lu microseconds\n", deviceCaps.dwFFSamplePeriod); + fprintf(debugFile, "- FFMinTimeResolution: %lu\n", deviceCaps.dwFFMinTimeResolution); + + // Initialize custom force with proper parameters + ZeroMemory(customForce, sizeof(DICUSTOMFORCE)); + customForce->cChannels = FFBAxesCount; // Match actual axes count + customForce->dwSamplePeriod = deviceCaps.dwFFSamplePeriod; + customForce->cSamples = 2; // At least two samples for interpolation + + // Allocate and initialize force data array + LONG* forceData = new LONG[customForce->cSamples]; + forceData[0] = 0; // Initial force + forceData[1] = 5000; // Final force + + customForce->rglForceData = forceData; + + // Initialize effect structure + ZeroMemory(&effect, sizeof(DIEFFECT)); + effect.dwSize = sizeof(DIEFFECT); + effect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + effect.dwDuration = INFINITE; + effect.dwSamplePeriod = customForce->dwSamplePeriod; + effect.dwGain = DI_FFNOMINALMAX; + effect.dwTriggerButton = DIEB_NOTRIGGER; + effect.dwTriggerRepeatInterval = 0; + effect.cAxes = FFBAxesCount; + effect.rgdwAxes = FFBAxes; + effect.rglDirection = FFBDirections; + effect.lpEnvelope = NULL; + effect.cbTypeSpecificParams = sizeof(DICUSTOMFORCE); + effect.lpvTypeSpecificParams = customForce; + + fprintf(debugFile, "\nCustom Force Parameters:\n"); + fprintf(debugFile, "- Channels: %lu\n", customForce->cChannels); + fprintf(debugFile, "- Sample Period: %lu microseconds\n", customForce->dwSamplePeriod); + fprintf(debugFile, "- Samples Count: %lu\n", customForce->cSamples); + fprintf(debugFile, "- Force Data[0]: %ld\n", customForce->rglForceData[0]); + fprintf(debugFile, "- Force Data[1]: %ld\n", customForce->rglForceData[1]); + + fprintf(debugFile, "\nEffect Configuration:\n"); + fprintf(debugFile, "- Effect Size: %lu\n", effect.dwSize); + fprintf(debugFile, "- Type Specific Params Size: %lu\n", effect.cbTypeSpecificParams); + fprintf(debugFile, "- Sample Period: %lu microseconds\n", effect.dwSamplePeriod); + fprintf(debugFile, "- Duration: %lu\n", effect.dwDuration); + fprintf(debugFile, "- Gain: %lu\n", effect.dwGain); + fprintf(debugFile, "- Flags: 0x%08X\n", effect.dwFlags); + + HRESULT createResult = _ActiveDevices[GUIDString]->CreateEffect( + EffectTypeToGUID(effectType), + &effect, + &effectControl, + nullptr + ); + + fprintf(debugFile, "\nEffect Creation Result: 0x%08X\n", createResult); + if (FAILED(createResult)) { + fprintf(debugFile, "Failed to create custom force effect\n"); + } + + fclose(debugFile); + return createResult; + break; + } + + default: + return E_FAIL; // Unsupported Effect + } + + + if (FAILED(hr = _ActiveDevices[GUIDString]->CreateEffect(EffectTypeToGUID(effectType), &effect, &effectControl, nullptr))) { return hr; } + if (FAILED(hr = effectControl->Start(1, 0))) { return hr; } + _DeviceFFBEffectConfig[GUIDString][effectType] = effect; + _DeviceFFBEffectControl[GUIDString][effectType] = effectControl; + + return hr; } HRESULT DestroyFFBEffect(LPCSTR guidInstance, Effects::Type effectType) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + if (!guidInstance) return E_INVALIDARG; - // Destroy Effect - if (!_DeviceFFBEffectControl[GUIDString].contains(effectType)) { return S_OK; } // Effect doesn't exist + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); + + // Validate device exists + if (!_ActiveDevices.contains(GUIDString)) { + return E_HANDLE; + } - hr = _DeviceFFBEffectControl[GUIDString][effectType]->Stop(); // Stop Effect - _DeviceFFBEffectControl[GUIDString].erase(effectType); // Remove Effect Control - _DeviceFFBEffectConfig[GUIDString].erase(effectType); // Remove Effect Config + // Validate effect control exists + if (!_DeviceFFBEffectControl[GUIDString].contains(effectType)) { + return S_OK; // Already destroyed + } + + // Get effect pointer + LPDIRECTINPUTEFFECT diEffect = _DeviceFFBEffectControl[GUIDString][effectType]; + if (!diEffect) { + // Cleanup invalid state + _DeviceFFBEffectControl[GUIDString].erase(effectType); + _DeviceFFBEffectConfig[GUIDString].erase(effectType); + return E_POINTER; + } - return hr; + try { + // Stop effect first + hr = diEffect->Stop(); + if (FAILED(hr)) { + // Log error but continue cleanup + char buffer[256]; + sprintf_s(buffer, "Failed to stop effect: 0x%08X\n", hr); + OutputDebugStringA(buffer); + } + + // Unload effect resources + hr = diEffect->Unload(); + if (FAILED(hr)) { + char buffer[256]; + sprintf_s(buffer, "Failed to unload effect: 0x%08X\n", hr); + OutputDebugStringA(buffer); + } + + // Release the effect interface + ULONG refCount = diEffect->Release(); + if (refCount > 0) { + char buffer[256]; + sprintf_s(buffer, "Warning: Effect released but refCount = %lu\n", refCount); + OutputDebugStringA(buffer); + } + + // Clean up maps + _DeviceFFBEffectControl[GUIDString].erase(effectType); + _DeviceFFBEffectConfig[GUIDString].erase(effectType); + + return S_OK; + } + catch (...) { + // Ensure maps are cleaned even on error + _DeviceFFBEffectControl[GUIDString].erase(effectType); + _DeviceFFBEffectConfig[GUIDString].erase(effectType); + return E_FAIL; + } } HRESULT UpdateFFBEffect(LPCSTR guidInstance, Effects::Type effectType, DICONDITION* conditions) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - if (!_DeviceFFBEffectControl[GUIDString].contains(effectType)) { return E_ABORT; } // Effect doesn't exist - - for (int idx = 0; idx < _DeviceFFBEffectConfig[GUIDString][effectType].cAxes; idx++) { // For each Axis in this effect - switch (effectType) { - case Effects::Type::ConstantForce: - DICONSTANTFORCE CF = *reinterpret_cast(_DeviceFFBEffectConfig[GUIDString][Effects::Type::ConstantForce].lpvTypeSpecificParams); - CF.lMagnitude = conditions[idx].lPositiveCoefficient; - _DeviceFFBEffectConfig[GUIDString][Effects::Type::ConstantForce].lpvTypeSpecificParams = &CF; - break; - default: - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].lOffset = conditions->lOffset; - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].lPositiveCoefficient = conditions[idx].lPositiveCoefficient; - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].lNegativeCoefficient = conditions[idx].lNegativeCoefficient; - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].dwPositiveSaturation = conditions[idx].dwPositiveSaturation; - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].dwNegativeSaturation = conditions[idx].dwNegativeSaturation; - ((DICONDITION*)_DeviceFFBEffectConfig[GUIDString][effectType].lpvTypeSpecificParams)[idx].lDeadBand = conditions[idx].lDeadBand; - break; - } - } - hr = _DeviceFFBEffectControl[GUIDString][effectType]->SetParameters(&_DeviceFFBEffectConfig[GUIDString][effectType], DIEP_TYPESPECIFICPARAMS); - return hr; + if (!guidInstance || !conditions) return E_INVALIDARG; + + HRESULT hr = E_FAIL; + std::string GUIDString(guidInstance); + + // Validate device and effect existence + if (!_ActiveDevices.contains(GUIDString)) return E_FAIL; + if (!_DeviceFFBEffectControl[GUIDString].contains(effectType)) return E_ABORT; + + // Get effect configuration + auto& effectConfig = _DeviceFFBEffectConfig[GUIDString][effectType]; + + for (DWORD idx = 0; idx < effectConfig.cAxes; idx++) { + switch (effectType) { + case Effects::Type::ConstantForce: { + auto* cf = static_cast(effectConfig.lpvTypeSpecificParams); + if (!cf) return E_POINTER; + cf->lMagnitude = conditions[idx].lPositiveCoefficient; + break; + } + + case Effects::Type::Sine: + case Effects::Type::Square: + case Effects::Type::Triangle: + case Effects::Type::SawtoothUp: + case Effects::Type::SawtoothDown: { + auto* pe = static_cast(effectConfig.lpvTypeSpecificParams); + if (!pe) return E_POINTER; + pe->dwMagnitude = conditions[idx].lPositiveCoefficient; + pe->lOffset = conditions[idx].lOffset; + pe->dwPeriod = conditions[idx].dwPositiveSaturation; + // Maintain existing phase values + break; + } + case Effects::Type::RampForce: { + auto* rf = static_cast(effectConfig.lpvTypeSpecificParams); + if (!rf) return E_POINTER; + rf->lStart = conditions[idx].lPositiveCoefficient; + rf->lEnd = conditions[idx].lNegativeCoefficient; + break; + } + default: { + auto* cond = static_cast(effectConfig.lpvTypeSpecificParams); + if (!cond) return E_POINTER; + cond[idx].lOffset = conditions[idx].lOffset; + cond[idx].lPositiveCoefficient = conditions[idx].lPositiveCoefficient; + cond[idx].lNegativeCoefficient = conditions[idx].lNegativeCoefficient; + cond[idx].dwPositiveSaturation = conditions[idx].dwPositiveSaturation; + cond[idx].dwNegativeSaturation = conditions[idx].dwNegativeSaturation; + cond[idx].lDeadBand = conditions[idx].lDeadBand; + break; + } + } + } + + // Update effect parameters + return _DeviceFFBEffectControl[GUIDString][effectType]->SetParameters( + &effectConfig, + DIEP_TYPESPECIFICPARAMS + ); } HRESULT StopAllFFBEffects(LPCSTR guidInstance) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - hr = S_OK; // Incase there are no active effects, act like we stopped them all - - //for (auto& [effectType, effectControl] : _DeviceFFBEffectControl[GUIDString]) { // For each effect - // if (FAILED(hr = effectControl->Stop())) { return hr; } // Stop Effect - // //_DeviceFFBEffectControl[GUIDString].erase(effectType); // Remove Effect Control // effectType isn't behaving like Effects::Type, "An unhandled exception of type 'System.AccessViolationException' occurred in DirectInputExplorer.dll" "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." - // //_DeviceFFBEffectConfig[GUIDString].erase(effectType); // Remove Effect Config - //} - - hr = DestroyFFBEffect(guidInstance, Effects::Type::ConstantForce); - hr = DestroyFFBEffect(guidInstance, Effects::Type::RampForce); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Square); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Sine); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Triangle); - hr = DestroyFFBEffect(guidInstance, Effects::Type::SawtoothUp); - hr = DestroyFFBEffect(guidInstance, Effects::Type::SawtoothDown); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Spring); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Damper); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Inertia); - hr = DestroyFFBEffect(guidInstance, Effects::Type::Friction); - hr = DestroyFFBEffect(guidInstance, Effects::Type::CustomForce); - - return hr; + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + hr = S_OK; // Incase there are no active effects, act like we stopped them all + + //for (auto& [effectType, effectControl] : _DeviceFFBEffectControl[GUIDString]) { // For each effect + // if (FAILED(hr = effectControl->Stop())) { return hr; } // Stop Effect + // //_DeviceFFBEffectControl[GUIDString].erase(effectType); // Remove Effect Control // effectType isn't behaving like Effects::Type, "An unhandled exception of type 'System.AccessViolationException' occurred in DirectInputExplorer.dll" "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." + // //_DeviceFFBEffectConfig[GUIDString].erase(effectType); // Remove Effect Config + //} + + hr = DestroyFFBEffect(guidInstance, Effects::Type::ConstantForce); + hr = DestroyFFBEffect(guidInstance, Effects::Type::RampForce); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Square); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Sine); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Triangle); + hr = DestroyFFBEffect(guidInstance, Effects::Type::SawtoothUp); + hr = DestroyFFBEffect(guidInstance, Effects::Type::SawtoothDown); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Spring); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Damper); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Inertia); + hr = DestroyFFBEffect(guidInstance, Effects::Type::Friction); + hr = DestroyFFBEffect(guidInstance, Effects::Type::CustomForce); + + return hr; } void SetDeviceChangeCallback(DeviceChangeCallback CB) { - _DeviceChangeCallback = CB; + _DeviceChangeCallback = CB; } // Generate SAFEARRAY of DEBUG data HRESULT DEBUG1(LPCSTR guidInstance, /*[out]*/ SAFEARRAY** DebugData) { - HRESULT hr = E_FAIL; - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail + HRESULT hr = E_FAIL; + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return hr; // Device not attached, fail - //std::vector SAData; + //std::vector SAData; - //SAData.push_back(L"Modifying Constant Force!"); - //DICONSTANTFORCE CF = { 1000 }; - //_DeviceFFBEffectConfig[GUIDString][Effects::ConstantForce].lpvTypeSpecificParams = &CF; - //_DeviceFFBEffectControl[GUIDString][Effects::ConstantForce]->SetParameters(&_DeviceFFBEffectConfig[GUIDString][Effects::ConstantForce], DIEP_TYPESPECIFICPARAMS); - //hr = BuildSafeArray(SAData, DebugData); + //SAData.push_back(L"Modifying Constant Force!"); + //DICONSTANTFORCE CF = { 1000 }; + //_DeviceFFBEffectConfig[GUIDString][Effects::ConstantForce].lpvTypeSpecificParams = &CF; + //_DeviceFFBEffectControl[GUIDString][Effects::ConstantForce]->SetParameters(&_DeviceFFBEffectConfig[GUIDString][Effects::ConstantForce], DIEP_TYPESPECIFICPARAMS); + //hr = BuildSafeArray(SAData, DebugData); - // Testing Fanatec Fix - LPDIRECTINPUTDEVICE8 DIDevice = nullptr; - if (FAILED(hr = _DirectInput->CreateDevice(LPCSTRGUIDtoGUID(guidInstance), &DIDevice, NULL))) { return true; } // L"CreateDevice failed! 0x%08x", hr + // Testing Fanatec Fix + LPDIRECTINPUTDEVICE8 DIDevice = nullptr; + if (FAILED(hr = _DirectInput->CreateDevice(LPCSTRGUIDtoGUID(guidInstance), &DIDevice, NULL))) { + return hr; + } // L"CreateDevice failed! 0x%08x", hr - DIPROPGUIDANDPATH GUIDPath; - GUIDPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); - GUIDPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); - GUIDPath.diph.dwObj = 0; - GUIDPath.diph.dwHow = DIPH_DEVICE; - if (FAILED(hr = DIDevice->GetProperty(DIPROP_GUIDANDPATH, &GUIDPath.diph))) { DIDevice->Release(); return true; } // L"GetProperty failed! Failed to get symbolic path for device 0x%08x", hr - DIDevice->Release(); + DIPROPGUIDANDPATH GUIDPath = {}; + GUIDPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); + GUIDPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); + GUIDPath.diph.dwObj = 0; + GUIDPath.diph.dwHow = static_cast(DIPH_DEVICE); // Explicit cast to DWORD + if (FAILED(hr = DIDevice->GetProperty(DIPROP_GUIDANDPATH, &GUIDPath.diph))) { + DIDevice->Release(); + return hr; + } // L"GetProperty failed! Failed to get symbolic path for device 0x%08x", hr + DIDevice->Release(); - //if (wcsstr(GUIDPath.wszPath, L"&col01") != 0) { // This is our primary device (HID Path contains "&col01") - // return false; - //} - //else { - // return true; // This is a duplicate device - //} - DEBUGDATA.push_back(GUIDPath.wszPath); + //if (wcsstr(GUIDPath.wszPath, L"&col01") != 0) { // This is our primary device (HID Path contains "&col01") + // return false; + //} + //else { + // return true; // This is a duplicate device + //} + DEBUGDATA.push_back(GUIDPath.wszPath); - hr = BuildSafeArray(DEBUGDATA, DebugData); - return hr; + hr = BuildSafeArray(DEBUGDATA, DebugData); + return hr; } @@ -451,84 +650,84 @@ HRESULT DEBUG1(LPCSTR guidInstance, /*[out]*/ SAFEARRAY** DebugData) { // Callback for each device enumerated, each device is added to the _DeviceInstances vector BOOL CALLBACK _EnumDevicesCallback(const DIDEVICEINSTANCE* DIDI, void* pContext) { - DeviceInfo di = { 0 }; // Store DeviceInfo - di.deviceType = DIDI->dwDevType; - std::string GIStr = (GUID_to_string( DIDI->guidInstance ).c_str()); - std::string GPStr = (GUID_to_string( DIDI->guidProduct ).c_str()); - std::string INStr = (wstring_to_string(DIDI->tszInstanceName).c_str()); - std::string PNStr = (wstring_to_string(DIDI->tszProductName ).c_str()); - di.guidInstance = new char[GIStr.length()+1]; - di.guidProduct = new char[GPStr.length()+1]; - di.instanceName = new char[INStr.length()+1]; - di.productName = new char[PNStr.length()+1]; - strcpy_s( di.guidInstance, GIStr.length()+1, GIStr.c_str() ); - strcpy_s( di.guidProduct, GPStr.length()+1, GPStr.c_str() ); - strcpy_s( di.instanceName, INStr.length()+1, INStr.c_str() ); - strcpy_s( di.productName, PNStr.length()+1, PNStr.c_str() ); - di.FFBCapable = false; // Default all devices to false, FFB devices are updated later - - // Fanatec Fix (Fanatec devices enumerate as 2) - if (LOWORD(DIDI->guidProduct.Data1) == 0x0EB7) // Fanatec manufacturer ID - if (IsDuplicateHID(DIDI)) { return DIENUM_CONTINUE; } // Skip if duplicate - - _DeviceInstances.push_back(di); - return DIENUM_CONTINUE; + DeviceInfo di = { 0 }; // Store DeviceInfo + di.deviceType = DIDI->dwDevType; + std::string GIStr = (GUID_to_string(DIDI->guidInstance).c_str()); + std::string GPStr = (GUID_to_string(DIDI->guidProduct).c_str()); + std::string INStr = (wstring_to_string(DIDI->tszInstanceName).c_str()); + std::string PNStr = (wstring_to_string(DIDI->tszProductName).c_str()); + di.guidInstance = new char[GIStr.length() + 1]; + di.guidProduct = new char[GPStr.length() + 1]; + di.instanceName = new char[INStr.length() + 1]; + di.productName = new char[PNStr.length() + 1]; + strcpy_s(di.guidInstance, GIStr.length() + 1, GIStr.c_str()); + strcpy_s(di.guidProduct, GPStr.length() + 1, GPStr.c_str()); + strcpy_s(di.instanceName, INStr.length() + 1, INStr.c_str()); + strcpy_s(di.productName, PNStr.length() + 1, PNStr.c_str()); + di.FFBCapable = false; // Default all devices to false, FFB devices are updated later + + // Fanatec Fix (Fanatec devices enumerate as 2) + if (LOWORD(DIDI->guidProduct.Data1) == 0x0EB7) // Fanatec manufacturer ID + if (IsDuplicateHID(DIDI)) { return DIENUM_CONTINUE; } // Skip if duplicate + + _DeviceInstances.push_back(di); + return DIENUM_CONTINUE; } // Callback for each device enumerated, each device is added to the _DeviceInstances vector BOOL CALLBACK _EnumDevicesCallbackFFB(const DIDEVICEINSTANCE* DIDI, void* pContext) { - std::string GUIDStr = (GUID_to_string(DIDI->guidInstance).c_str()); // Convert GUID to str to compare against - for (auto& di : _DeviceInstances) { - if (di.guidInstance == GUIDStr) { // Update existing entry - di.FFBCapable = true; - } - } - return DIENUM_CONTINUE; + std::string GUIDStr = (GUID_to_string(DIDI->guidInstance).c_str()); // Convert GUID to str to compare against + for (auto& di : _DeviceInstances) { + if (di.guidInstance == GUIDStr) { // Update existing entry + di.FFBCapable = true; + } + } + return DIENUM_CONTINUE; } BOOL CALLBACK _EnumFFBEffectsCallback(LPCDIEFFECTINFO EffectInfo, LPVOID pvRef) { - std::string GUIDString = *reinterpret_cast(pvRef); // Device GUID passed in as 2nd arg - _DeviceEnumeratedEffects[GUIDString].push_back(*EffectInfo); // Add the DIEffectInfo to the entry for this Device - return DIENUM_CONTINUE; // Continue to next effect + std::string GUIDString = *reinterpret_cast(pvRef); // Device GUID passed in as 2nd arg + _DeviceEnumeratedEffects[GUIDString].push_back(*EffectInfo); // Add the DIEffectInfo to the entry for this Device + return DIENUM_CONTINUE; // Continue to next effect } BOOL CALLBACK _EnumFFBAxisCallback(const DIDEVICEOBJECTINSTANCE* ObjectInst, LPVOID pvRef) { - std::string GUIDString = *reinterpret_cast(pvRef); // Device GUID passed in as 2nd arg + std::string GUIDString = *reinterpret_cast(pvRef); // Device GUID passed in as 2nd arg - if ((ObjectInst->dwFlags & DIDOI_FFACTUATOR) != 0) { // FFB Axis - _DeviceFFBAxes[GUIDString].push_back(*ObjectInst); // Add this ObjectIntance to the vector for this Device - } + if ((ObjectInst->dwFlags & DIDOI_FFACTUATOR) != 0) { // FFB Axis + _DeviceFFBAxes[GUIDString].push_back(*ObjectInst); // Add this ObjectIntance to the vector for this Device + } - return DIENUM_CONTINUE; + return DIENUM_CONTINUE; } LRESULT _WindowsHookCallback(int code, WPARAM wParam, LPARAM lParam) { - if (code < 0) return CallNextHookEx(NULL, code, wParam, lParam); // invalid code skip - - // check if device was added/removed - PCWPSTRUCT pMsg = PCWPSTRUCT(lParam); - if (pMsg->message == WM_DEVICECHANGE) { - if (_DeviceChangeCallback) { _DeviceChangeCallback((int)pMsg->wParam); } // If callback assigned, invoke it - //switch (pMsg->wParam) { - // case DBT_DEVNODES_CHANGED: - // DEBUGDATA.push_back(L"Changed!"); - // // TODO: Invoke Callback - // //if (_DeviceChangeCallback) { _DeviceChangeCallback(1); } - // break; - // case DBT_DEVICEARRIVAL: - // DEBUGDATA.push_back(L"Arrival!"); - // // TODO: Invoke Callback - // break; - // case DBT_DEVICEREMOVECOMPLETE: - // DEBUGDATA.push_back(L"Remove!"); - // // TODO: Invoke Callback - // break; - // default: - // DEBUGDATA.push_back(L"Other!"); - // break; - //} - } - return CallNextHookEx(NULL, code, wParam, lParam); // Continue to next hook + if (code < 0) return CallNextHookEx(NULL, code, wParam, lParam); // invalid code skip + + // check if device was added/removed + PCWPSTRUCT pMsg = PCWPSTRUCT(lParam); + if (pMsg->message == WM_DEVICECHANGE) { + if (_DeviceChangeCallback) { _DeviceChangeCallback((int)pMsg->wParam); } // If callback assigned, invoke it + //switch (pMsg->wParam) { + // case DBT_DEVNODES_CHANGED: + // DEBUGDATA.push_back(L"Changed!"); + // // TODO: Invoke Callback + // //if (_DeviceChangeCallback) { _DeviceChangeCallback(1); } + // break; + // case DBT_DEVICEARRIVAL: + // DEBUGDATA.push_back(L"Arrival!"); + // // TODO: Invoke Callback + // break; + // case DBT_DEVICEREMOVECOMPLETE: + // DEBUGDATA.push_back(L"Remove!"); + // // TODO: Invoke Callback + // break; + // default: + // DEBUGDATA.push_back(L"Other!"); + // break; + //} + } + return CallNextHookEx(NULL, code, wParam, lParam); // Continue to next hook } ////////////////////////////////////////////////////////////// @@ -537,254 +736,270 @@ LRESULT _WindowsHookCallback(int code, WPARAM wParam, LPARAM lParam) { // Generate SAFEARRAY from vector of wstrings, useful for exporing data across interop boundary HRESULT BuildSafeArray(std::vector sourceData, /*[out]*/ SAFEARRAY** SafeArrayData) { - HRESULT hr = E_FAIL; - try { - // Build the destination SAFEARRAY from the source data - const LONG dataEntries = static_cast(sourceData.size()); - CComSafeArray SAFEARRAY(dataEntries); - for (LONG i = 0; i < dataEntries; i++) { - CComBSTR bstr = ToBstr(sourceData[i]); // Create a BSTR from the std::wstring - if (FAILED(hr = SAFEARRAY.SetAt(i, bstr.Detach(), FALSE))) { AtlThrow(hr); } // Move the BSTR into the safe array - } - - // Return the safe array to the caller (transfer ownership) - *SafeArrayData = SAFEARRAY.Detach(); - } catch (const CAtlException& e) { - hr = e; - } catch (const std::exception&) { - hr = E_FAIL; - } - - return hr; + HRESULT hr = E_FAIL; + try { + // Build the destination SAFEARRAY from the source data + const LONG dataEntries = static_cast(sourceData.size()); + CComSafeArray SAFEARRAY(dataEntries); + for (LONG i = 0; i < dataEntries; i++) { + CComBSTR bstr = ToBstr(sourceData[i]); // Create a BSTR from the std::wstring + if (FAILED(hr = SAFEARRAY.SetAt(i, bstr.Detach(), FALSE))) { AtlThrow(hr); } // Move the BSTR into the safe array + } + + // Return the safe array to the caller (transfer ownership) + *SafeArrayData = SAFEARRAY.Detach(); + } + catch (const CAtlException& e) { + hr = e; + } + catch (const std::exception&) { + hr = E_FAIL; + } + + return hr; } // Utilities for converting string types ( https://stackoverflow.com/a/3999597/3055031 ) // Convert a wide Unicode string to an UTF8 string // Convert an UTF8 string to a wide Unicode String -std::wstring string_to_wstring(const std::string& str){ - if (str.empty()) return std::wstring(); - int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); - std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); - return wstrTo; +std::wstring string_to_wstring(const std::string& str) { + if (str.empty()) return std::wstring(); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); + return wstrTo; } -std::string wstring_to_string(const std::wstring& wstr){ - if (wstr.empty()) return std::string(); - int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); - std::string strTo(size_needed, 0); - WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); - return strTo; +std::string wstring_to_string(const std::wstring& wstr) { + if (wstr.empty()) return std::string(); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); + std::string strTo(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); + return strTo; } // Convert a GUID to a String std::string GUID_to_string(GUID guidInstance) { - OLECHAR* guidSTR; - (void)StringFromCLSID(guidInstance, &guidSTR); - return wstring_to_string(guidSTR); + OLECHAR* guidSTR; + (void)StringFromCLSID(guidInstance, &guidSTR); + return wstring_to_string(guidSTR); } // Return window handle for specified PID HWND FindMainWindow(unsigned long process_id) { - WindowData data; - data.process_id = process_id; - data.window_handle = 0; - EnumWindows(_EnumWindowsCallback, (LPARAM)&data); - return data.window_handle; + WindowData data = {}; + data.process_id = process_id; + data.window_handle = 0; + EnumWindows(_EnumWindowsCallback, (LPARAM)&data); + return data.window_handle; } // Callback to find the main window when Enumerating windows of PID BOOL CALLBACK _EnumWindowsCallback(HWND handle, LPARAM lParam) { - WindowData& data = *(WindowData*)lParam; // Pointer to our original WindowData data object - unsigned long process_id = 0; // Store PID - GetWindowThreadProcessId(handle, &process_id); // Get PID of our handle (Window in callback) - if (data.process_id != process_id || !IsMainWindow(handle)) - return TRUE; - data.window_handle = handle; // This is the main window, set the WindowData handle - return FALSE; + WindowData& data = *(WindowData*)lParam; // Pointer to our original WindowData data object + unsigned long process_id = 0; // Store PID + GetWindowThreadProcessId(handle, &process_id); // Get PID of our handle (Window in callback) + if (data.process_id != process_id || !IsMainWindow(handle)) + return TRUE; + data.window_handle = handle; // This is the main window, set the WindowData handle + return FALSE; } // True if the handle is for the main window BOOL IsMainWindow(HWND handle) { - return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle); + return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle); } GUID LPCSTRGUIDtoGUID(LPCSTR guidInstance) { - GUID deviceGuid; - int wcharCount = MultiByteToWideChar(CP_UTF8, 0, guidInstance, -1, NULL, 0); - WCHAR* wstrGuidInstance = new WCHAR[wcharCount]; - MultiByteToWideChar(CP_UTF8, 0, guidInstance, -1, wstrGuidInstance, wcharCount); - (void)CLSIDFromString(wstrGuidInstance, &deviceGuid); - delete[] wstrGuidInstance; - return deviceGuid; + GUID deviceGuid; + int wcharCount = MultiByteToWideChar(CP_UTF8, 0, guidInstance, -1, NULL, 0); + WCHAR* wstrGuidInstance = new WCHAR[wcharCount]; + MultiByteToWideChar(CP_UTF8, 0, guidInstance, -1, wstrGuidInstance, wcharCount); + (void)CLSIDFromString(wstrGuidInstance, &deviceGuid); + delete[] wstrGuidInstance; + return deviceGuid; } FlatJoyState2 FlattenDIJOYSTATE2(DIJOYSTATE2 DeviceState) { - FlatJoyState2 state = FlatJoyState2(); // Hold the flattend state - - // ButtonA - for (int i = 0; i < 64; i++) { // In banks of 64, shift in the sate of each button BankA 0-63 - if (DeviceState.rgbButtons[i] == 128) // 128 = Button pressed - state.buttonsA |= (unsigned long long)1 << i; // Shift in a 1 to the button at index i - } - // ButtonB - for (int i = 64; i < 128; i++) { // 2nd bank of buttons from 64-128 - if (DeviceState.rgbButtons[i] == 128) // 128 = Button pressed - state.buttonsB |= (unsigned long long)1 << i; // Shift in a 1 to the button at index i - } - - state.lX = DeviceState.lX; // X-axis - state.lY = DeviceState.lY; // Y-axis - state.lZ = DeviceState.lZ; // Z-axis - // rglSlider - state.lU = DeviceState.rglSlider[0]; // U-axis - state.lV = DeviceState.rglSlider[1]; // V-axis - - state.lRx = DeviceState.lRx; // X-axis rotation - state.lRy = DeviceState.lRy; // Y-axis rotation - state.lRz = DeviceState.lRz; // Z-axis rotation - - state.lVX = DeviceState.lVX; // X-axis velocity - state.lVY = DeviceState.lVY; // Y-axis velocity - state.lVZ = DeviceState.lVZ; // Z-axis velocity - // rglVSlider - state.lVU = DeviceState.rglVSlider[0]; // U-axis velocity - state.lVV = DeviceState.rglVSlider[1]; // V-axis velocity - - state.lVRx = DeviceState.lVRx; // X-axis angular velocity - state.lVRy = DeviceState.lVRy; // Y-axis angular velocity - state.lVRz = DeviceState.lVRz; // Z-axis angular velocity - - state.lAX = DeviceState.lAX; // X-axis acceleration - state.lAY = DeviceState.lAY; // Y-axis acceleration - state.lAZ = DeviceState.lAZ; // Z-axis acceleration - // rglASlider - state.lAU = DeviceState.rglASlider[0]; // U-axis acceleration - state.lAV = DeviceState.rglASlider[1]; // V-axis acceleration - - state.lARx = DeviceState.lARx; // X-axis angular acceleration - state.lARy = DeviceState.lARy; // Y-axis angular acceleration - state.lARz = DeviceState.lARz; // Z-axis angular acceleration - - state.lFX = DeviceState.lFX; // X-axis force - state.lFY = DeviceState.lFY; // Y-axis force - state.lFZ = DeviceState.lFZ; // Z-axis force - // rglFSlider - state.lFU = DeviceState.rglFSlider[0]; // U-axis force - state.lFV = DeviceState.rglFSlider[1]; // V-axis force - - state.lFRx = DeviceState.lFRx; // X-axis torque - state.lFRy = DeviceState.lFRy; // Y-axis torque - state.lFRz = DeviceState.lFRz; // Z-axis torque - - for (int i = 0; i < 4; i++) { // In banks of 4, shift in the sate of each DPAD 0-16 bits - switch (DeviceState.rgdwPOV[i]) { - case 0: state.rgdwPOV |= (byte)(1 << ((i + 1) * 0)); break; // dpad[i]/up, bit = 0 shift into value at stride (i+1) * DPADButton - case 18000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 1)); break; // dpad[i]/down, bit = 1 - case 27000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 2)); break; // dpad[i]/left, bit = 2 - case 9000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 3)); break; // dpad[i]/right, bit = 3 - } - } - - return state; + FlatJoyState2 state = FlatJoyState2(); // Hold the flattend state + + // ButtonA + for (int i = 0; i < 64; i++) { // In banks of 64, shift in the sate of each button BankA 0-63 + if (DeviceState.rgbButtons[i] == 128) // 128 = Button pressed + state.buttonsA |= (unsigned long long)1 << i; // Shift in a 1 to the button at index i + } + // ButtonB + for (int i = 64; i < 128; i++) { // 2nd bank of buttons from 64-128 + if (DeviceState.rgbButtons[i] == 128) // 128 = Button pressed + state.buttonsB |= (unsigned long long)1 << i; // Shift in a 1 to the button at index i + } + + // Properly cast and clamp values to uint16_t range + auto ClampToUInt16 = [](LONG value) -> uint16_t { + return static_cast(std::clamp(value, 0L, static_cast(UINT16_MAX))); + }; + + // Axis assignments with proper ClampToUInt16 + state.lX = ClampToUInt16(DeviceState.lX); + state.lY = ClampToUInt16(DeviceState.lY); + state.lZ = ClampToUInt16(DeviceState.lZ); + state.lU = ClampToUInt16(DeviceState.rglSlider[0]); + state.lV = ClampToUInt16(DeviceState.rglSlider[1]); + + // Rotation assignments + state.lRx = ClampToUInt16(DeviceState.lRx); + state.lRy = ClampToUInt16(DeviceState.lRy); + state.lRz = ClampToUInt16(DeviceState.lRz); + + // Velocity assignments + state.lVX = ClampToUInt16(DeviceState.lVX); + state.lVY = ClampToUInt16(DeviceState.lVY); + state.lVZ = ClampToUInt16(DeviceState.lVZ); + state.lVU = ClampToUInt16(DeviceState.rglVSlider[0]); + state.lVV = ClampToUInt16(DeviceState.rglVSlider[1]); + + // Angular velocity assignments + state.lVRx = ClampToUInt16(DeviceState.lVRx); + state.lVRy = ClampToUInt16(DeviceState.lVRy); + state.lVRz = ClampToUInt16(DeviceState.lVRz); + + // Acceleration assignments + state.lAX = ClampToUInt16(DeviceState.lAX); + state.lAY = ClampToUInt16(DeviceState.lAY); + state.lAZ = ClampToUInt16(DeviceState.lAZ); + state.lAU = ClampToUInt16(DeviceState.rglASlider[0]); + state.lAV = ClampToUInt16(DeviceState.rglASlider[1]); + + // Angular acceleration assignments + state.lARx = ClampToUInt16(DeviceState.lARx); + state.lARy = ClampToUInt16(DeviceState.lARy); + state.lARz = ClampToUInt16(DeviceState.lARz); + + // Force assignments + state.lFX = ClampToUInt16(DeviceState.lFX); + state.lFY = ClampToUInt16(DeviceState.lFY); + state.lFZ = ClampToUInt16(DeviceState.lFZ); + state.lFU = ClampToUInt16(DeviceState.rglFSlider[0]); + state.lFV = ClampToUInt16(DeviceState.rglFSlider[1]); + + // Torque assignments + state.lFRx = ClampToUInt16(DeviceState.lFRx); + state.lFRy = ClampToUInt16(DeviceState.lFRy); + state.lFRz = ClampToUInt16(DeviceState.lFRz); + + for (int i = 0; i < 4; i++) { // In banks of 4, shift in the sate of each DPAD 0-16 bits + switch (DeviceState.rgdwPOV[i]) { + case 0: state.rgdwPOV |= (byte)(1 << ((i + 1) * 0)); break; // dpad[i]/up, bit = 0 shift into value at stride (i+1) * DPADButton + case 18000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 1)); break; // dpad[i]/down, bit = 1 + case 27000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 2)); break; // dpad[i]/left, bit = 2 + case 9000: state.rgdwPOV |= (byte)(1 << ((i + 1) * 3)); break; // dpad[i]/right, bit = 3 + } + } + + return state; } bool GUIDMatch(LPCSTR guidInstance, LPDIRECTINPUTDEVICE8 Device) { - DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) }; - if (FAILED(Device->GetDeviceInfo(&deviceInfo))) { return false; } // Fetch device info - if (deviceInfo.guidInstance == LPCSTRGUIDtoGUID(guidInstance)) { // Check if GUID matches the device we want - return true; - } - return false; + DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) }; + if (FAILED(Device->GetDeviceInfo(&deviceInfo))) { return false; } // Fetch device info + if (deviceInfo.guidInstance == LPCSTRGUIDtoGUID(guidInstance)) { // Check if GUID matches the device we want + return true; + } + return false; } GUID Device2GUID(LPDIRECTINPUTDEVICE8 Device) { - DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) }; - if (FAILED(Device->GetDeviceInfo(&deviceInfo))) { /*return false;*/ } // Fetch device info - return deviceInfo.guidInstance; + DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) }; + if (FAILED(Device->GetDeviceInfo(&deviceInfo))) { /*return false;*/ } // Fetch device info + return deviceInfo.guidInstance; } // Helper function to convert a std::wstring to the ATL CComBSTR wrapper (Handy because it can be sized at runtime) inline CComBSTR ToBstr(const std::wstring& s) { - if (s.empty()) { return CComBSTR(); }// Special case of empty string - return CComBSTR(static_cast(s.size()), s.data()); + if (s.empty()) { return CComBSTR(); }// Special case of empty string + return CComBSTR(static_cast(s.size()), s.data()); } void DestroyDeviceIfExists(LPCSTR guidInstance) { - std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return; // Device not attached, fail - DestroyDevice(guidInstance); + std::string GUIDString((LPCSTR)guidInstance); if (!_ActiveDevices.contains(GUIDString)) return; // Device not attached, fail + DestroyDevice(guidInstance); } DWORD AxisTypeToDIJOFS(GUID axisType) { - if (axisType == GUID_XAxis) { - return DIJOFS_X; - } else if (axisType == GUID_YAxis) { - return DIJOFS_Y; - } else if (axisType == GUID_ZAxis) { - return DIJOFS_Z; - } else if (axisType == GUID_RxAxis) { - return DIJOFS_RX; - } else if (axisType == GUID_RyAxis) { - return DIJOFS_RY; - } else if (axisType == GUID_RzAxis) { - return DIJOFS_RZ; - } /*else if (axisType == GUID_Slider) { - return DIJOFS_SLIDER; - } else if (axisType == GUID_Button) { - return DIJOFS_BUTTON1; - } else if (axisType == GUID_Key) { - return DIJOFS_; - } else if (axisType == GUID_POV) { - return DIJOFS_POV; - } else if (AxesType == GUID_Unknown) { - return DIJOFS_; - }*/ - - return 0; // GUID Type not found, likely POV Hat, Slider or Button + if (axisType == GUID_XAxis) { + return DIJOFS_X; + } + else if (axisType == GUID_YAxis) { + return DIJOFS_Y; + } + else if (axisType == GUID_ZAxis) { + return DIJOFS_Z; + } + else if (axisType == GUID_RxAxis) { + return DIJOFS_RX; + } + else if (axisType == GUID_RyAxis) { + return DIJOFS_RY; + } + else if (axisType == GUID_RzAxis) { + return DIJOFS_RZ; + } /*else if (axisType == GUID_Slider) { + return DIJOFS_SLIDER; + } else if (axisType == GUID_Button) { + return DIJOFS_BUTTON1; + } else if (axisType == GUID_Key) { + return DIJOFS_; + } else if (axisType == GUID_POV) { + return DIJOFS_POV; + } else if (AxesType == GUID_Unknown) { + return DIJOFS_; + }*/ + + return 0; // GUID Type not found, likely POV Hat, Slider or Button } GUID EffectTypeToGUID(Effects::Type effectType) { - switch (effectType) { - case Effects::Type::ConstantForce: - return GUID_ConstantForce; - break; - case Effects::Type::RampForce: - return GUID_RampForce; - break; - case Effects::Type::Square: - return GUID_Square; - break; - case Effects::Type::Sine: - return GUID_Sine; - break; - case Effects::Type::Triangle: - return GUID_Triangle; - break; - case Effects::Type::SawtoothUp: - return GUID_SawtoothUp; - break; - case Effects::Type::SawtoothDown: - return GUID_SawtoothDown; - break; - case Effects::Type::Spring: - return GUID_Spring; - break; - case Effects::Type::Damper: - return GUID_Damper; - break; - case Effects::Type::Inertia: - return GUID_Inertia; - break; - case Effects::Type::Friction: - return GUID_Friction; - break; - case Effects::Type::CustomForce: - return GUID_CustomForce; - break; - default: - return GUID_Unknown; - } + switch (effectType) { + case Effects::Type::ConstantForce: + return GUID_ConstantForce; + break; + case Effects::Type::RampForce: + return GUID_RampForce; + break; + case Effects::Type::Square: + return GUID_Square; + break; + case Effects::Type::Sine: + return GUID_Sine; + break; + case Effects::Type::Triangle: + return GUID_Triangle; + break; + case Effects::Type::SawtoothUp: + return GUID_SawtoothUp; + break; + case Effects::Type::SawtoothDown: + return GUID_SawtoothDown; + break; + case Effects::Type::Spring: + return GUID_Spring; + break; + case Effects::Type::Damper: + return GUID_Damper; + break; + case Effects::Type::Inertia: + return GUID_Inertia; + break; + case Effects::Type::Friction: + return GUID_Friction; + break; + case Effects::Type::CustomForce: + return GUID_CustomForce; + break; + default: + return GUID_Unknown; + } } bool IsDuplicateHID(const DIDEVICEINSTANCE* DIDI) { @@ -792,7 +1007,7 @@ bool IsDuplicateHID(const DIDEVICEINSTANCE* DIDI) { LPDIRECTINPUTDEVICE8 DIDevice = nullptr; if (FAILED(hr = _DirectInput->CreateDevice(DIDI->guidInstance, &DIDevice, NULL))) { return true; } // L"CreateDevice failed! 0x%08x", hr - DIPROPGUIDANDPATH GUIDPath; + DIPROPGUIDANDPATH GUIDPath = {}; GUIDPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); GUIDPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); GUIDPath.diph.dwObj = 0; diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.vcxproj b/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.vcxproj index fece6dc..937e338 100644 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.vcxproj +++ b/DirectInputForceFeedback~/DirectInputForceFeedback/DirectInputForceFeedback.vcxproj @@ -72,15 +72,19 @@ true + true false + true true + true false + true diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/Release/DirectInputForceFeedback.dll.recipe b/DirectInputForceFeedback~/DirectInputForceFeedback/Release/DirectInputForceFeedback.dll.recipe deleted file mode 100644 index d00650a..0000000 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/Release/DirectInputForceFeedback.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ -īģŋ - - - - C:\Users\Ducky\Documents\GitHub\Unity-ForceFeedback\~DirectInputForceFeedback\Release\DirectInputForceFeedback.dll - - - - - - \ No newline at end of file diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/DirectInputForceFeedback.dll.recipe b/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/DirectInputForceFeedback.dll.recipe deleted file mode 100644 index 2444bba..0000000 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/DirectInputForceFeedback.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ -īģŋ - - - - C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputForceFeedback~\x64\Debug\DirectInputForceFeedback.dll - - - - - - \ No newline at end of file diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/vc143.idb b/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/vc143.idb deleted file mode 100644 index c9b5eb0..0000000 Binary files a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Debug/vc143.idb and /dev/null differ diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Release/DirectInputForceFeedback.dll.recipe b/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Release/DirectInputForceFeedback.dll.recipe deleted file mode 100644 index 5b94819..0000000 --- a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Release/DirectInputForceFeedback.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ -īģŋ - - - - C:\Users\Ducky\Documents\GitHub\Unity-DirectInput\DirectInputForceFeedback~\x64\Release\DirectInputForceFeedback.dll - - - - - - \ No newline at end of file diff --git a/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Release/DirectInputForceFeedback.vcxproj.FileListAbsolute.txt b/DirectInputForceFeedback~/DirectInputForceFeedback/x64/Release/DirectInputForceFeedback.vcxproj.FileListAbsolute.txt deleted file mode 100644 index e69de29..0000000 diff --git a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.dll b/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.dll deleted file mode 100644 index fb1fa5c..0000000 Binary files a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.dll and /dev/null differ diff --git a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.exp b/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.exp deleted file mode 100644 index a22a6d8..0000000 Binary files a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.exp and /dev/null differ diff --git a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.lib b/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.lib deleted file mode 100644 index 95dfcf3..0000000 Binary files a/DirectInputForceFeedback~/x64/Debug/DirectInputForceFeedback.lib and /dev/null differ diff --git a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.dll b/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.dll deleted file mode 100644 index 83bb721..0000000 Binary files a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.dll and /dev/null differ diff --git a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.exp b/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.exp deleted file mode 100644 index e0c208d..0000000 Binary files a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.exp and /dev/null differ diff --git a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.lib b/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.lib deleted file mode 100644 index c0e7a48..0000000 Binary files a/DirectInputForceFeedback~/x64/Release/DirectInputForceFeedback.lib and /dev/null differ diff --git a/Plugin/DLL/DirectInputForceFeedback.dll b/Plugin/DLL/DirectInputForceFeedback.dll index 83bb721..40d7e7d 100644 Binary files a/Plugin/DLL/DirectInputForceFeedback.dll and b/Plugin/DLL/DirectInputForceFeedback.dll differ diff --git a/Plugin/DirectInputManager.cs b/Plugin/DirectInputManager.cs index 738fc65..717e098 100644 --- a/Plugin/DirectInputManager.cs +++ b/Plugin/DirectInputManager.cs @@ -1,4 +1,4 @@ -īģŋ#pragma warning disable CS0618 // Disable Marshalling warnings +#pragma warning disable CS0618 // Disable Marshalling warnings using System; using System.Collections.Generic; @@ -8,857 +8,1044 @@ using System.Collections.Concurrent; using System.Linq; using System.Security.Cryptography; +using System.Diagnostics; #if UNITY_STANDALONE_WIN - using UnityEngine; +using UnityEngine; #endif -namespace DirectInputManager { - class Native { +namespace DirectInputManager +{ + class Native + { #if UNITY_STANDALONE_WIN - const string DLLFile = @"DirectInputForceFeedback.dll"; + const string DLLFile = @"DirectInputForceFeedback.dll"; #else - const string DLLFile = @"..\..\..\..\..\Plugin\DLL\DirectInputForceFeedback.dll"; + const string DLLFile = @"..\..\..\..\..\Plugin\DLL\DirectInputForceFeedback.dll"; #endif - [DllImport(DLLFile)] public static extern int StartDirectInput(); - [DllImport(DLLFile)] public static extern int StopDirectInput(); - [DllImport(DLLFile)] public static extern IntPtr EnumerateDevices(out int deviceCount); - [DllImport(DLLFile)] public static extern int CreateDevice(string guidInstance); - [DllImport(DLLFile)] public static extern int DestroyDevice(string guidInstance); - [DllImport(DLLFile)] public static extern int GetDeviceState(string guidInstance, out FlatJoyState2 DeviceState); - [DllImport(DLLFile)] public static extern int GetDeviceStateRaw(string guidInstance, out DIJOYSTATE2 DeviceState); - [DllImport(DLLFile)] public static extern int GetDeviceCapabilities(string guidInstance, out DIDEVCAPS DeviceCapabilitiesOut); - [DllImport(DLLFile)] public static extern int GetActiveDevices([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] ActiveGUIDs); - [DllImport(DLLFile)] public static extern int EnumerateFFBEffects(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] SupportedFFBEffects); - [DllImport(DLLFile)] public static extern int EnumerateFFBAxis(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] SupportedFFBAxis); - [DllImport(DLLFile)] public static extern int CreateFFBEffect(string guidInstance, FFBEffects effectType); - [DllImport(DLLFile)] public static extern int DestroyFFBEffect(string guidInstance, FFBEffects effectType); - [DllImport(DLLFile)] public static extern int UpdateFFBEffect(string guidInstance, FFBEffects effectType, DICondition[] conditions); - [DllImport(DLLFile)] public static extern int StopAllFFBEffects(string guidInstance); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void DeviceChangeCallback(DBTEvents DBTEvent); - [DllImport(DLLFile)] public static extern void SetDeviceChangeCallback([MarshalAs(UnmanagedType.FunctionPtr)] DeviceChangeCallback onDeviceChange); - - //[DllImport(DLLFile)] public static extern int DEBUG1(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] DEBUGDATA); - } - public class DIManager { - ////////////////////////////////////////////////////////////// - // Cross Platform "Macros" - Allows lib to work in Visual Studio & Unity - ////////////////////////////////////////////////////////////// + [DllImport(DLLFile)] public static extern int StartDirectInput(); + [DllImport(DLLFile)] public static extern int StopDirectInput(); + [DllImport(DLLFile)] public static extern IntPtr EnumerateDevices(out int deviceCount); + [DllImport(DLLFile)] public static extern int CreateDevice(string guidInstance); + [DllImport(DLLFile)] public static extern int DestroyDevice(string guidInstance); + [DllImport(DLLFile)] public static extern int GetDeviceState(string guidInstance, out FlatJoyState2 DeviceState); + [DllImport(DLLFile)] public static extern int GetDeviceStateRaw(string guidInstance, out DIJOYSTATE2 DeviceState); + [DllImport(DLLFile)] public static extern int GetDeviceCapabilities(string guidInstance, out DIDEVCAPS DeviceCapabilitiesOut); + [DllImport(DLLFile)] public static extern int GetActiveDevices([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] ActiveGUIDs); + [DllImport(DLLFile)] public static extern int EnumerateFFBEffects(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] SupportedFFBEffects); + [DllImport(DLLFile)] public static extern int EnumerateFFBAxis(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] SupportedFFBAxis); + [DllImport(DLLFile)] public static extern int CreateFFBEffect(string guidInstance, FFBEffects effectType); + [DllImport(DLLFile)] public static extern int DestroyFFBEffect(string guidInstance, FFBEffects effectType); + [DllImport(DLLFile)] public static extern int UpdateFFBEffect(string guidInstance, FFBEffects effectType, DICondition[] conditions); + + [DllImport(DLLFile)] public static extern int StopAllFFBEffects(string guidInstance); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void DeviceChangeCallback(DBTEvents DBTEvent); + [DllImport(DLLFile)] public static extern void SetDeviceChangeCallback([MarshalAs(UnmanagedType.FunctionPtr)] DeviceChangeCallback onDeviceChange); + + [DllImport(DLLFile)] public static extern int DEBUG1(string guidInstance, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] DEBUGDATA); + } + public class DIManager + { + ////////////////////////////////////////////////////////////// + // Cross Platform "Macros" - Allows lib to work in Visual Studio & Unity + ////////////////////////////////////////////////////////////// #if UNITY_STANDALONE_WIN - const string DLLFile = @"DirectInputForceFeedback.dll"; - private static uint ClampAgnostic(uint value, uint min, uint max) => (uint)Mathf.Clamp(value, min, max); - private static int ClampAgnostic(int value, int min, int max) => Mathf.Clamp(value, min, max); - private static void DebugLog(string message) => Debug.Log($"[DirectInputManager] {message}"); + const string DLLFile = @"DirectInputForceFeedback.dll"; + private static uint ClampAgnostic(uint value, uint min, uint max) => (uint)Mathf.Clamp(value, min, max); + private static int ClampAgnostic(int value, int min, int max) => Mathf.Clamp(value, min, max); + private static void DebugLog(string message) => UnityEngine.Debug.Log($"[DirectInputManager] {message}"); #else - const string DLLFile = @"..\..\..\..\..\Plugin\DLL\DirectInputForceFeedback.dll"; - private static uint ClampAgnostic(uint value, uint min, uint max) => Math.Clamp(value, min, max); - private static int ClampAgnostic(int value, int min, int max) => Math.Clamp(value, min, max); - private static void DebugLog(string message) => System.Diagnostics.Debug.WriteLine($"[DirectInputManager]{message}"); + const string DLLFile = @"..\..\..\..\..\Plugin\DLL\DirectInputForceFeedback.dll"; + private static uint ClampAgnostic(uint value, uint min, uint max) => Math.Clamp(value, min, max); + private static int ClampAgnostic(int value, int min, int max) => Math.Clamp(value, min, max); + private static void DebugLog(string message) => System.Diagnostics.Debug.WriteLine($"[DirectInputManager]{message}"); #endif - ////////////////////////////////////////////////////////////// - // Private Variables - For Internal use - ////////////////////////////////////////////////////////////// - - private static bool _isInitialized = false; // is DIManager ready - private static DeviceInfo[] _devices = new DeviceInfo[0]; // Hold data for devices plugged in - private static Dictionary _activeDevices = new Dictionary(); // Hold data for devices actively attached - - ////////////////////////////////////////////////////////////// - // Public Variables - ////////////////////////////////////////////////////////////// - public static bool isInitialized { get => _isInitialized; } - public static DeviceInfo[] devices { get => _devices; } - public static Dictionary activeDevices { get => _activeDevices; } - - ////////////////////////////////////////////////////////////// - // Methods - ////////////////////////////////////////////////////////////// - - /// - /// Initializes DirectInput

- ///
- /// - /// True if sucessful or DI already initialized
- /// False if failed - ///
- public static bool Initialize() { - if (_isInitialized) { return _isInitialized; } - if (Native.StartDirectInput() != 0) { return _isInitialized = false; } - Native.SetDeviceChangeCallback(OnDeviceChange); - return _isInitialized = true; - } - - /// - /// Fetch currently available devices and populate DIManager.devices
- ///
- public static void EnumerateDevices() { - int deviceCount = 0; - IntPtr ptrDevices = Native.EnumerateDevices(out deviceCount); // Returns pointer to list of devices and how many are available - - if (deviceCount > 0) { - _devices = new DeviceInfo[deviceCount]; - - int deviceSize = Marshal.SizeOf(typeof(DeviceInfo)); // Size of each Device entry - for (int i = 0; i < deviceCount; i++) { - IntPtr pCurrent = ptrDevices + i * deviceSize; // Ptr to the current device - _devices[i] = Marshal.PtrToStructure(pCurrent); // Transform the Ptr into a C# instance of DeviceInfo - } - }else{ - _devices = new DeviceInfo[0]; // empty _devices when no devices are present - } - return; - } - - public static async Task EnumerateDevicesAsync(){ - Task enumDevicesTask = Task.Run(EnumerateDevices); - Task warningTimeout = Task.Delay(1000); - - if (warningTimeout == await Task.WhenAny(enumDevicesTask, warningTimeout)) { - DebugLog($"Warning EnumerateDevices is taking longer than expected!"); - await enumDevicesTask; // Continue to wait for EnumerateDevices - } - } - - /// - /// Attach to Device, ready to get state/ForceFeedback

- ///
- /// - /// A boolean representing the if the Device was attached - /// - public static bool Attach(string guidInstance) { - if (_activeDevices.ContainsKey(guidInstance)) { return true; } // We're already attached to that device - int hresult = Native.CreateDevice(guidInstance); - if (hresult != 0) { DebugLog($"CreateDevice Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)} {guidInstance}"); return false; } - DeviceInfo device = _devices.Where(device => device.guidInstance == guidInstance).First(); - _activeDevices.Add(guidInstance, new ActiveDeviceInfo(){ deviceInfo = device }); // Add device to our C# active device tracker (Dictionary allows us to easily check if GUID already exists) - return true; - } + ////////////////////////////////////////////////////////////// + // Private Variables - For Internal use + ////////////////////////////////////////////////////////////// + + private static bool _isInitialized = false; // is DIManager ready + private static DeviceInfo[] _devices = new DeviceInfo[0]; // Hold data for devices plugged in + private static Dictionary _activeDevices = new Dictionary(); // Hold data for devices actively attached + + ////////////////////////////////////////////////////////////// + // Public Variables + ////////////////////////////////////////////////////////////// + public static bool isInitialized { get => _isInitialized; } + public static DeviceInfo[] devices { get => _devices; } + public static Dictionary activeDevices { get => _activeDevices; } + + ////////////////////////////////////////////////////////////// + // Methods + ////////////////////////////////////////////////////////////// + + /// + /// Initializes DirectInput

+ ///
+ /// + /// True if sucessful or DI already initialized
+ /// False if failed + ///
+ public static bool Initialize() + { + if (_isInitialized) { return _isInitialized; } + if (Native.StartDirectInput() != 0) { return _isInitialized = false; } + Native.SetDeviceChangeCallback(OnDeviceChange); + return _isInitialized = true; + } + /// + /// Fetch currently available devices and populate DIManager.devices
+ ///
+ public static void EnumerateDevices() + { + int deviceCount = 0; + IntPtr ptrDevices = Native.EnumerateDevices(out deviceCount); // Returns pointer to list of devices and how many are available + + if (deviceCount > 0) + { + _devices = new DeviceInfo[deviceCount]; + + int deviceSize = Marshal.SizeOf(typeof(DeviceInfo)); // Size of each Device entry + for (int i = 0; i < deviceCount; i++) + { + IntPtr pCurrent = ptrDevices + i * deviceSize; // Ptr to the current device + _devices[i] = Marshal.PtrToStructure(pCurrent); // Transform the Ptr into a C# instance of DeviceInfo + } + } + else + { + _devices = new DeviceInfo[0]; // empty _devices when no devices are present + } + return; + } - /// - /// Remove a specified Device - /// - /// - /// True upon sucessful destruction or device already didn't exist - /// - public static bool Destroy(string guidInstance) { - if (!_activeDevices.ContainsKey(guidInstance)) { return true; } // We don't think we're attached to that device, consider it removed - int hresult = Native.DestroyDevice(guidInstance); - _activeDevices.Remove(guidInstance); // remove from our C# active device tracker - if (hresult != 0) { DebugLog($"DestroyDevice Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + public static async Task EnumerateDevicesAsync() + { + Task enumDevicesTask = Task.Run(EnumerateDevices); + Task warningTimeout = Task.Delay(1000); - /// - /// Retrieve state of the Device, Flattened for easier comparison.
- ///
- /// - /// FlatJoyState2 - /// - public static FlatJoyState2 GetDeviceState(string guidInstance) { - FlatJoyState2 DeviceState = new FlatJoyState2(); - int hresult = Native.GetDeviceState(guidInstance, out DeviceState); - if (hresult != 0) { DebugLog($"GetDeviceState Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - return DeviceState; - } + if (warningTimeout == await Task.WhenAny(enumDevicesTask, warningTimeout)) + { + DebugLog($"Warning EnumerateDevices is taking longer than expected!"); + await enumDevicesTask; // Continue to wait for EnumerateDevices + } + } - // public static async Task GetDeviceStateAsync(string guidInstance){ - // return await Task.Run(()=>{return GetDeviceState(guidInstance);}); - // } - - /// - /// Retrieve state of the Device
- /// *Warning* DIJOYSTATE2 contains arrays making it difficult to compare, concider using GetDeviceState - ///
- /// - /// DIJOYSTATE2 - /// - public static DIJOYSTATE2 GetDeviceStateRaw(string guidInstance) { - DIJOYSTATE2 DeviceState = new DIJOYSTATE2(); - int hresult = Native.GetDeviceStateRaw(guidInstance, out DeviceState); - if (hresult != 0) { DebugLog($"GetDeviceStateRaw Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - return DeviceState; - } + /// + /// Attach to Device, ready to get state/ForceFeedback

+ ///
+ /// + /// A boolean representing the if the Device was attached + /// + public static bool Attach(string guidInstance) + { + if (_activeDevices.ContainsKey(guidInstance)) { return true; } // We're already attached to that device + int hresult = Native.CreateDevice(guidInstance); + if (hresult != 0) { DebugLog($"CreateDevice Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)} {guidInstance}"); return false; } + DeviceInfo device = _devices.Where(device => device.guidInstance == guidInstance).First(); + _activeDevices.Add(guidInstance, new ActiveDeviceInfo() { deviceInfo = device }); // Add device to our C# active device tracker (Dictionary allows us to easily check if GUID already exists) + return true; + } - /// - /// Lists all attached device GUIDs - /// - /// - /// string[] of attached GUIDs - /// - public static string[] GetActiveDevices() { - string[] ActiveGUIDs = null; - int hresult = Native.GetActiveDevices(out ActiveGUIDs); - //if (hresult != 0) { Debug.LogError($"[DirectInputManager] GetActiveDevices Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - if (hresult != 0) { DebugLog($"GetActiveDevices Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - - if (ActiveGUIDs.Length != _activeDevices.Count) { DebugLog($"Active Device mismatch! DLL:{ActiveGUIDs.Length}, DIManager:{_activeDevices.Count}"); } - - return ActiveGUIDs; - } - /// - /// Retrieve the capabilities of the device. E.g. # Buttons, # Axes, Driver Version
- /// Device must be attached first
- ///
- /// - /// DIDEVCAPS https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416607(v=vs.85) - /// - public static DIDEVCAPS GetDeviceCapabilities(string guidInstance) { - DIDEVCAPS DeviceCapabilities = new DIDEVCAPS(); - int hresult = Native.GetDeviceCapabilities(guidInstance, out DeviceCapabilities); - if (hresult != 0) { DebugLog($"GetDeviceCapabilities Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - return DeviceCapabilities; - } + /// + /// Remove a specified Device + /// + /// + /// True upon sucessful destruction or device already didn't exist + /// + public static bool Destroy(string guidInstance) + { + if (!_activeDevices.ContainsKey(guidInstance)) { return true; } // We don't think we're attached to that device, consider it removed + int hresult = Native.DestroyDevice(guidInstance); + _activeDevices.Remove(guidInstance); // remove from our C# active device tracker + if (hresult != 0) { DebugLog($"DestroyDevice Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Returns if the device has the ForceFeedback Flag
- ///
- /// - /// True if device can provide ForceFeedback
- ///
- public static bool FFBCapable(string guidInstance) { - return GetDeviceCapabilities(guidInstance).dwFlags.HasFlag(dwFlags.DIDC_FORCEFEEDBACK); - } + /// + /// Retrieve state of the Device, Flattened for easier comparison.
+ ///
+ /// + /// FlatJoyState2 + /// + public static FlatJoyState2 GetDeviceState(string guidInstance) + { + FlatJoyState2 DeviceState = new FlatJoyState2(); + int hresult = Native.GetDeviceState(guidInstance, out DeviceState); + if (hresult != 0) { DebugLog($"GetDeviceState Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + return DeviceState; + } - /// - /// Returns the attached status of the device
- ///
- /// - /// True if device is attached - /// - public static bool isDeviceActive(string guidInstance) { - return _activeDevices.ContainsKey(guidInstance); - } + // public static async Task GetDeviceStateAsync(string guidInstance){ + // return await Task.Run(()=>{return GetDeviceState(guidInstance);}); + // } + + /// + /// Retrieve state of the Device
+ /// *Warning* DIJOYSTATE2 contains arrays making it difficult to compare, concider using GetDeviceState + ///
+ /// + /// DIJOYSTATE2 + /// + public static DIJOYSTATE2 GetDeviceStateRaw(string guidInstance) + { + DIJOYSTATE2 DeviceState = new DIJOYSTATE2(); + int hresult = Native.GetDeviceStateRaw(guidInstance, out DeviceState); + if (hresult != 0) { DebugLog($"GetDeviceStateRaw Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + return DeviceState; + } - /// - /// Enables an FFB Effect on the device.
- /// E.g. FFBEffects.ConstantForce
- /// Refer to FFBEffects enum for all effect types - ///
- /// - /// True if effect was added sucessfully - /// - public static bool EnableFFBEffect(string guidInstance, FFBEffects effectType) { - int hresult = Native.CreateFFBEffect(guidInstance, effectType); - if (hresult != 0) { DebugLog($"CreateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + /// + /// Lists all attached device GUIDs + /// + /// + /// string[] of attached GUIDs + /// + public static string[] GetActiveDevices() + { + string[] ActiveGUIDs = null; + int hresult = Native.GetActiveDevices(out ActiveGUIDs); + //if (hresult != 0) { Debug.LogError($"[DirectInputManager] GetActiveDevices Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + if (hresult != 0) { DebugLog($"GetActiveDevices Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + + if (ActiveGUIDs.Length != _activeDevices.Count) { DebugLog($"Active Device mismatch! DLL:{ActiveGUIDs.Length}, DIManager:{_activeDevices.Count}"); } + + return ActiveGUIDs; + } - /// - /// Removes an FFB Effect from the device
- /// Refer to FFBEffects enum for all effect types - ///
- /// - /// True if effect was removed sucessfully - /// - public static bool DestroyFFBEffect(string guidInstance, FFBEffects effectType) { - int hresult = Native.DestroyFFBEffect(guidInstance, effectType); - if (hresult != 0) { DebugLog($"DestroyFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + /// + /// Retrieve the capabilities of the device. E.g. # Buttons, # Axes, Driver Version
+ /// Device must be attached first
+ ///
+ /// + /// DIDEVCAPS https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416607(v=vs.85) + /// + public static DIDEVCAPS GetDeviceCapabilities(string guidInstance) + { + DIDEVCAPS DeviceCapabilities = new DIDEVCAPS(); + int hresult = Native.GetDeviceCapabilities(guidInstance, out DeviceCapabilities); + if (hresult != 0) { DebugLog($"GetDeviceCapabilities Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + return DeviceCapabilities; + } - /// - /// Fetches supported FFB Effects by specified Device
- ///
- /// - /// string[] of effect names supported - /// - public static string[] GetDeviceFFBCapabilities(string guidInstance) { - string[] SupportedFFBEffects = null; - int hresult = Native.EnumerateFFBEffects(guidInstance, out SupportedFFBEffects); - if (hresult != 0) { DebugLog($"GetDeviceFFBCapabilities Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - return SupportedFFBEffects; - } + /// + /// Returns if the device has the ForceFeedback Flag
+ ///
+ /// + /// True if device can provide ForceFeedback
+ ///
+ public static bool FFBCapable(string guidInstance) + { + return GetDeviceCapabilities(guidInstance).dwFlags.HasFlag(dwFlags.DIDC_FORCEFEEDBACK); + } - /// - /// Stops and removes all active effects on a device
- /// *Warning* Effects will have to be enabled again before use
- ///
- /// - /// True if effects stopped successfully - /// - public static bool StopAllFFBEffects(string guidInstance) { - int hresult = Native.StopAllFFBEffects(guidInstance); - if (hresult != 0) { DebugLog($"StopAllFFBEffects Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + /// + /// Returns the attached status of the device
+ ///
+ /// + /// True if device is attached + /// + public static bool isDeviceActive(string guidInstance) + { + return _activeDevices.ContainsKey(guidInstance); + } - /// - /// Stops DirectInput
- ///
- /// - /// True if DirectInput was stopped successfully - /// - public static bool StopDirectInput() { - int hresult = Native.StopDirectInput(); - if (hresult != 0) { DebugLog($"StopDirectInput Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + /// + /// Enables an FFB Effect on the device.
+ /// E.g. FFBEffects.ConstantForce
+ /// Refer to FFBEffects enum for all effect types + ///
+ /// + /// True if effect was added sucessfully + /// + public static bool EnableFFBEffect(string guidInstance, FFBEffects effectType) + { + int hresult = Native.CreateFFBEffect(guidInstance, effectType); + if (hresult != 0) { DebugLog($"CreateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Returns byte[] of state
- ///
- /// - /// byte[] - /// - public static byte[] FlatStateToBytes(FlatJoyState2 state) { - int size = Marshal.SizeOf(state); - byte[] StateRawBytes = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); - Marshal.StructureToPtr(state, ptr, true); - Marshal.Copy(ptr, StateRawBytes, 0, size); - Marshal.FreeHGlobal(ptr); - return StateRawBytes; - } + /// + /// Removes an FFB Effect from the device
+ /// Refer to FFBEffects enum for all effect types + ///
+ /// + /// True if effect was removed sucessfully + /// + public static bool DestroyFFBEffect(string guidInstance, FFBEffects effectType) + { + int hresult = Native.DestroyFFBEffect(guidInstance, effectType); + if (hresult != 0) { DebugLog($"DestroyFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Computes MD5 for FlatState
- ///
- /// - /// byte[] MD5 Hash - /// - public static byte[] FlatStateMD5(FlatJoyState2 state) { - MD5 md5 = new MD5CryptoServiceProvider(); - var StateRawBytes = FlatStateToBytes(state); - return md5.ComputeHash(StateRawBytes); - } + /// + /// Fetches supported FFB Effects by specified Device
+ ///
+ /// + /// string[] of effect names supported + /// + public static string[] GetDeviceFFBCapabilities(string guidInstance) + { + string[] SupportedFFBEffects = null; + int hresult = Native.EnumerateFFBEffects(guidInstance, out SupportedFFBEffects); + if (hresult != 0) { DebugLog($"GetDeviceFFBCapabilities Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + return SupportedFFBEffects; + } - /// - /// Fetches device state and triggers events if state changed
- ///
- public static void Poll(string guidInstance) { - ActiveDeviceInfo ADI; - if (_activeDevices.TryGetValue(guidInstance, out ADI)) { // Check if device active - Int32 oldHash = ADI.stateHash; - var state = GetDeviceState(guidInstance); - ADI.stateHash = state.GetHashCode(); + /// + /// Stops and removes all active effects on a device
+ /// *Warning* Effects will have to be enabled again before use
+ ///
+ /// + /// True if effects stopped successfully + /// + public static bool StopAllFFBEffects(string guidInstance) + { + int hresult = Native.StopAllFFBEffects(guidInstance); + if (hresult != 0) { DebugLog($"StopAllFFBEffects Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - if (oldHash != ADI.stateHash) { - ADI.DeviceStateChange(ADI.deviceInfo, state); // Invoke all event listeners for this device - //DebugLog($"{ADI.deviceInfo.productName} State Changed!"); + /// + /// Stops DirectInput
+ ///
+ /// + /// True if DirectInput was stopped successfully + /// + public static bool StopDirectInput() + { + int hresult = Native.StopDirectInput(); + if (hresult != 0) { DebugLog($"StopDirectInput Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; } - } else { - // Device isn't attached - } - } + /// + /// Returns byte[] of state
+ ///
+ /// + /// byte[] + /// + public static byte[] FlatStateToBytes(FlatJoyState2 state) + { + int size = Marshal.SizeOf(state); + byte[] StateRawBytes = new byte[size]; + IntPtr ptr = Marshal.AllocHGlobal(size); + Marshal.StructureToPtr(state, ptr, true); + Marshal.Copy(ptr, StateRawBytes, 0, size); + Marshal.FreeHGlobal(ptr); + return StateRawBytes; + } - /// - /// Fetches device state for all devices and queues events
- ///
- public static void PollAll() { - foreach(ActiveDeviceInfo ADI in _activeDevices.Values) { - Poll(ADI.deviceInfo); - } - } + /// + /// Computes MD5 for FlatState
+ ///
+ /// + /// byte[] MD5 Hash + /// + public static byte[] FlatStateMD5(FlatJoyState2 state) + { + MD5 md5 = new MD5CryptoServiceProvider(); + var StateRawBytes = FlatStateToBytes(state); + return md5.ComputeHash(StateRawBytes); + } - /// - /// Obtains ActiveDeviceInfo for specified GUID
- ///
- /// - /// Bool if GUID was found
- /// OUT ADI of device if found - ///
- public static bool GetADI(string guidInstance, out ActiveDeviceInfo ADI) { - return _activeDevices.TryGetValue(guidInstance, out ADI); - } + /// + /// Fetches device state and triggers events if state changed
+ ///
+ public static void Poll(string guidInstance) + { + ActiveDeviceInfo ADI; + if (_activeDevices.TryGetValue(guidInstance, out ADI)) + { // Check if device active + Int32 oldHash = ADI.stateHash; + var state = GetDeviceState(guidInstance); + ADI.stateHash = state.GetHashCode(); + + if (oldHash != ADI.stateHash) + { + ADI.DeviceStateChange(ADI.deviceInfo, state); // Invoke all event listeners for this device + //DebugLog($"{ADI.deviceInfo.productName} State Changed!"); + } + } + else + { + // Device isn't attached + } - /// - /// *Internal use only* - /// Used to test C++ code in the DLL during devlopment - /// - // public static string[] DEBUG1() { - // string[] DEBUGDATA = null; - // DEBUGDATA = new string[1] { "Test" }; - // int hresult = Native.DEBUG1(out DEBUGDATA); - // if (hresult != 0) { DebugLog($"DEBUG1 Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } + } - // return DEBUGDATA; - // } + /// + /// Fetches device state for all devices and queues events
+ ///
+ public static void PollAll() + { + foreach (ActiveDeviceInfo ADI in _activeDevices.Values) + { + Poll(ADI.deviceInfo); + } + } + /// + /// Obtains ActiveDeviceInfo for specified GUID
+ ///
+ /// + /// Bool if GUID was found
+ /// OUT ADI of device if found + ///
+ public static bool GetADI(string guidInstance, out ActiveDeviceInfo ADI) + { + return _activeDevices.TryGetValue(guidInstance, out ADI); + } - ////////////////////////////////////////////////////////////// - // Device Events - ////////////////////////////////////////////////////////////// + /// + /// *Internal use only* + /// Used to test C++ code in the DLL during devlopment + /// + // public static string[] DEBUG1() { + // string[] DEBUGDATA = null; + // DEBUGDATA = new string[1] { "Test" }; + // int hresult = Native.DEBUG1(out DEBUGDATA); + // if (hresult != 0) { DebugLog($"DEBUG1 Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); /*return false;*/ } - // Events to add listners too E.g. DIManager.OnDeviceAdded += MyFunctionWhenDeviceAdded; - public static event deviceInfoEvent OnDeviceAdded; - public static event deviceInfoEvent OnDeviceRemoved; + // return DEBUGDATA; + // } - // Functions to invoke event listeners - public static void DeviceAdded (DeviceInfo device){ OnDeviceAdded ?.Invoke(device); } - public static void DeviceRemoved(DeviceInfo device){ OnDeviceRemoved?.Invoke(device); } - // static Action InvokeDebounce; + ////////////////////////////////////////////////////////////// + // Device Events + ////////////////////////////////////////////////////////////// - private static Debouncer ODCDebouncer = new Debouncer(150); // 150ms (OnDeviceChangeDebouncer) + // Events to add listners too E.g. DIManager.OnDeviceAdded += MyFunctionWhenDeviceAdded; + public static event deviceInfoEvent OnDeviceAdded; + public static event deviceInfoEvent OnDeviceRemoved; - /// - /// *Internal use only* - /// Called from the DLL when a windows WM_DEVICECHANGE event is captured - /// This function invokes the necessary events - /// - private static void OnDeviceChange(DBTEvents DBTEvent) { - //DebugLog($"DeviceChange {DBTEvent.ToString()}"); + // Functions to invoke event listeners + public static void DeviceAdded(DeviceInfo device) { OnDeviceAdded?.Invoke(device); } + public static void DeviceRemoved(DeviceInfo device) { OnDeviceRemoved?.Invoke(device); } - ODCDebouncer.Debounce(() => { ScanDevicesForChanges(); }); - } + // static Action InvokeDebounce; - private static async void ScanDevicesForChanges(){ - DeviceInfo[] oldDevices = _devices; // Store currently known devices - await EnumerateDevicesAsync(); // Fetch what devices are available now + private static Debouncer ODCDebouncer = new Debouncer(150); // 150ms (OnDeviceChangeDebouncer) - var removedDevices = oldDevices.Except(_devices); - var addedDevices = _devices.Except(oldDevices); + /// + /// *Internal use only* + /// Called from the DLL when a windows WM_DEVICECHANGE event is captured + /// This function invokes the necessary events + /// + private static void OnDeviceChange(DBTEvents DBTEvent) + { + //DebugLog($"DeviceChange {DBTEvent.ToString()}"); - foreach (DeviceInfo device in removedDevices) { // Process removed devices - ActiveDeviceInfo ADI; - if(_activeDevices.TryGetValue(device.guidInstance, out ADI)){ - ADI.DeviceRemoved(device); // Invoke event listeners for this device + ODCDebouncer.Debounce(() => { ScanDevicesForChanges(); }); } - DeviceRemoved(device); // Invoke all event listeners all devices - Destroy(device); // If device was connceted remove it gracefully - // DebugLog($"{device.productName} Removed!"); - } - - foreach (DeviceInfo device in addedDevices) { // Process newly added devices - DeviceAdded(device); // Invoke event to broadcast a new device is available - } - } - - ////////////////////////////////////////////////////////////// - // Effect Specific Methods - ////////////////////////////////////////////////////////////// - - /// - /// Update existing effect with new DICONDITION array

- /// - /// DICondition[DeviceFFBEffectAxesCount]:

- /// deadband: Inacive Zone [-10,000 - 10,000]
- /// offset: Move Effect Center[-10,000 - 10,000]
- /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
- /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
- /// negativeSaturation: Negative of center saturation [0 - 10,000]
- /// positiveSaturation: Positive of center saturation [0 - 10,000]
- ///
- /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateEffect(string guidInstance, DICondition[] conditions) { - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = ClampAgnostic(conditions[i].deadband, 0, 10000); - conditions[i].offset = ClampAgnostic(conditions[i].offset, -10000, 10000); - conditions[i].negativeCoefficient = ClampAgnostic(conditions[i].negativeCoefficient, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(conditions[i].positiveCoefficient, -10000, 10000); - conditions[i].negativeSaturation = ClampAgnostic(conditions[i].negativeSaturation, 0, 10000); - conditions[i].positiveSaturation = ClampAgnostic(conditions[i].positiveSaturation, 0, 10000); - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Spring, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateConstantForceSimple(string guidInstance, int Magnitude) { - DICondition[] conditions = new DICondition[1]; - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = 0; - conditions[i].offset = 0; - conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].negativeSaturation = 0; - conditions[i].positiveSaturation = 0; - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.ConstantForce, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } - - /// - /// deadband: Inacive Zone [-10,000 - 10,000]
- /// offset: Move Effect Center[-10,000 - 10,000]
- /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
- /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
- /// negativeSaturation: Negative of center saturation [0 - 10,000]
- /// positiveSaturation: Positive of center saturation [0 - 10,000]
- ///
- /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateSpringSimple(string guidInstance, uint deadband, int offset, int negativeCoefficient, int positiveCoefficient, uint negativeSaturation, uint positiveSaturation) { - DICondition[] conditions = new DICondition[1]; - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = ClampAgnostic(deadband, 0, 10000); - conditions[i].offset = ClampAgnostic(offset, -10000, 10000); - conditions[i].negativeCoefficient = ClampAgnostic(negativeCoefficient, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(positiveCoefficient, -10000, 10000); - conditions[i].negativeSaturation = ClampAgnostic(negativeSaturation, 0, 10000); - conditions[i].positiveSaturation = ClampAgnostic(positiveSaturation, 0, 10000); - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Spring, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateDamperSimple(string guidInstance, int Magnitude) { - DICondition[] conditions = new DICondition[1]; - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = 0; - conditions[i].offset = 0; - conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].negativeSaturation = 0; - conditions[i].positiveSaturation = 0; - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Damper, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateFrictionSimple(string guidInstance, int Magnitude) { - DICondition[] conditions = new DICondition[1]; - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = 0; - conditions[i].offset = 0; - conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].negativeSaturation = 0; - conditions[i].positiveSaturation = 0; - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Friction, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateInertiaSimple(string guidInstance, int Magnitude) { - DICondition[] conditions = new DICondition[1]; - for (int i = 0; i < conditions.Length; i++) { - conditions[i] = new DICondition(); - conditions[i].deadband = 0; - conditions[i].offset = 0; - conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); - conditions[i].negativeSaturation = 0; - conditions[i].positiveSaturation = 0; - } - - int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Inertia, conditions); - if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } - return true; - } + private static async void ScanDevicesForChanges() + { + DeviceInfo[] oldDevices = _devices; // Store currently known devices + await EnumerateDevicesAsync(); // Fetch what devices are available now + + var removedDevices = oldDevices.Except(_devices); + var addedDevices = _devices.Except(oldDevices); + + foreach (DeviceInfo device in removedDevices) + { // Process removed devices + ActiveDeviceInfo ADI; + if (_activeDevices.TryGetValue(device.guidInstance, out ADI)) + { + ADI.DeviceRemoved(device); // Invoke event listeners for this device + } + DeviceRemoved(device); // Invoke all event listeners all devices + Destroy(device); // If device was connceted remove it gracefully + // DebugLog($"{device.productName} Removed!"); + } + + foreach (DeviceInfo device in addedDevices) + { // Process newly added devices + DeviceAdded(device); // Invoke event to broadcast a new device is available + } + } - ////////////////////////////////////////////////////////////// - // Overloads - Unfortunately summaries don't propagate to overloads - ////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////// + // Effect Specific Methods + ////////////////////////////////////////////////////////////// + + /// + /// Update existing effect with new DICONDITION array

+ /// + /// DICondition[DeviceFFBEffectAxesCount]:

+ /// deadband: Inacive Zone [-10,000 - 10,000]
+ /// offset: Move Effect Center[-10,000 - 10,000]
+ /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
+ /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
+ /// negativeSaturation: Negative of center saturation [0 - 10,000]
+ /// positiveSaturation: Positive of center saturation [0 - 10,000]
+ ///
+ /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateEffect(string guidInstance, FFBEffects fFBEffects, DICondition[] conditions) + { + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = ClampAgnostic(conditions[i].deadband, 0, 10000); + conditions[i].offset = ClampAgnostic(conditions[i].offset, -10000, 10000); + conditions[i].negativeCoefficient = ClampAgnostic(conditions[i].negativeCoefficient, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(conditions[i].positiveCoefficient, -10000, 10000); + conditions[i].negativeSaturation = ClampAgnostic(conditions[i].negativeSaturation, 0, 10000); + conditions[i].positiveSaturation = ClampAgnostic(conditions[i].positiveSaturation, 0, 10000); + } + + int hresult = Native.UpdateFFBEffect(guidInstance, fFBEffects, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Attach to Device, ready to get state/ForceFeedback

- ///
- /// - /// A boolean representing the if the Device was attached - /// - public static bool Attach(DeviceInfo device) => Attach(device.guidInstance); + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateConstantForceSimple(string guidInstance, int Magnitude) + { + DICondition[] conditions = new DICondition[1]; + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = 0; + conditions[i].offset = 0; + conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].negativeSaturation = 0; + conditions[i].positiveSaturation = 0; + } + + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.ConstantForce, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Remove a specified Device - /// - /// - /// True upon sucessful destruction - /// - public static bool Destroy(DeviceInfo device) => Destroy(device.guidInstance); + /// + /// deadband: Inacive Zone [-10,000 - 10,000]
+ /// offset: Move Effect Center[-10,000 - 10,000]
+ /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
+ /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
+ /// negativeSaturation: Negative of center saturation [0 - 10,000]
+ /// positiveSaturation: Positive of center saturation [0 - 10,000]
+ ///
+ /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateSpringSimple(string guidInstance, uint deadband, int offset, int negativeCoefficient, int positiveCoefficient, uint negativeSaturation, uint positiveSaturation) + { + DICondition[] conditions = new DICondition[1]; + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = ClampAgnostic(deadband, 0, 10000); + conditions[i].offset = ClampAgnostic(offset, -10000, 10000); + conditions[i].negativeCoefficient = ClampAgnostic(negativeCoefficient, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(positiveCoefficient, -10000, 10000); + conditions[i].negativeSaturation = ClampAgnostic(negativeSaturation, 0, 10000); + conditions[i].positiveSaturation = ClampAgnostic(positiveSaturation, 0, 10000); + } + + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Spring, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Retrieve state of the Device, Flattened for easier comparison.
- ///
- /// - /// FlatJoyState2 - /// - public static FlatJoyState2 GetDeviceState(DeviceInfo device) => GetDeviceState(device.guidInstance); + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateDamperSimple(string guidInstance, int Magnitude) + { + DICondition[] conditions = new DICondition[1]; + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = 0; + conditions[i].offset = 0; + conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].negativeSaturation = 0; + conditions[i].positiveSaturation = 0; + } + + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Damper, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Retrieve state of the Device
- /// *Warning* DIJOYSTATE2 contains arrays making it difficult to compare, concider using GetDeviceState - ///
- /// - /// DIJOYSTATE2 - /// - public static DIJOYSTATE2 GetDeviceStateRaw(DeviceInfo device) => GetDeviceStateRaw(device.guidInstance); - /// - /// Retrieve the capabilities of the device. E.g. # Buttons, # Axes, Driver Version
- /// Device must be attached first
- ///
- /// - /// DIDEVCAPS https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416607(v=vs.85) - /// - public static DIDEVCAPS GetDeviceCapabilities(DeviceInfo device) => GetDeviceCapabilities(device.guidInstance); + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateFrictionSimple(string guidInstance, int Magnitude) + { + DICondition[] conditions = new DICondition[1]; + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = 0; + conditions[i].offset = 0; + conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].negativeSaturation = 0; + conditions[i].positiveSaturation = 0; + } + + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Friction, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Returns if the device has the ForceFeedback Flag
- ///
- /// - /// True if device can provide ForceFeedback
- ///
- public static bool FFBCapable(DeviceInfo device) => FFBCapable(device.guidInstance); + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateInertiaSimple(string guidInstance, int Magnitude) + { + DICondition[] conditions = new DICondition[1]; + for (int i = 0; i < conditions.Length; i++) + { + conditions[i] = new DICondition(); + conditions[i].deadband = 0; + conditions[i].offset = 0; + conditions[i].negativeCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].positiveCoefficient = ClampAgnostic(Magnitude, -10000, 10000); + conditions[i].negativeSaturation = 0; + conditions[i].positiveSaturation = 0; + } + + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.Inertia, conditions); + if (hresult != 0) { DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); return false; } + return true; + } - /// - /// Returns the attached status of the device
- ///
- /// - /// True if device is attached - /// - public static bool isDeviceActive(DeviceInfo device) => isDeviceActive(device.guidInstance); + public static bool UpdatePeriodicSimple(string guidInstance, FFBEffects effectType, int magnitude, uint period = 30000, int rampStart = 0, int rampEnd = 0) + { + DICondition[] conditions = new DICondition[1]; + conditions[0] = new DICondition(); + conditions[0].deadband = 0; + conditions[0].offset = 0; + if (effectType != FFBEffects.RampForce) + { + conditions[0].negativeCoefficient = ClampAgnostic(magnitude, -10000, 10000); + conditions[0].positiveCoefficient = ClampAgnostic(magnitude, -10000, 10000); + + conditions[0].positiveSaturation = period; + } + else + { + conditions[0].positiveCoefficient = ClampAgnostic(rampStart, -10000, 10000); + conditions[0].negativeCoefficient = ClampAgnostic(rampEnd, -10000, 10000); + + conditions[0].positiveSaturation = 0; + } + conditions[0].negativeSaturation = 0; + + // Try updating first + int hresult = Native.UpdateFFBEffect(guidInstance, effectType, conditions); + if (hresult != 0) + { + // If effect doesn't exist (0x80004004 is HRESULT for E_ABORT) + if (hresult == unchecked((int)0x80004004)) + { + hresult = Native.CreateFFBEffect(guidInstance, effectType); + if (hresult != 0) + { + DebugLog($"CreateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + // Try updating again after creation + hresult = Native.UpdateFFBEffect(guidInstance, effectType, conditions); + if (hresult != 0) + { + DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + } + else + { + DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + } + return true; + } - /// - /// Enables an FFB Effect on the device.
- /// E.g. FFBEffects.ConstantForce
- /// Refer to FFBEffects enum for all effect types - ///
- /// - /// True if effect was added sucessfully - /// - public static bool EnableFFBEffect(DeviceInfo device, FFBEffects effectType) => EnableFFBEffect(device.guidInstance, effectType); + public static bool UpdateCustomForceSimple(string guidInstance, int[] forceData, uint samplePeriod, int offset = 0, uint deadband = 0) + { + if (forceData == null) + { + System.Diagnostics.Debug.WriteLine("UpdateCustomForceSimple: Invalid input parameters"); + return false; + } + + // Create conditions array matching the number of force samples + DICondition[] conditions = new DICondition[forceData.Length]; + + // Set up conditions for each force sample + for (int i = 0; i < forceData.Length; i++) + { + conditions[i] = new DICondition + { + positiveCoefficient = forceData[i], // Force value for this sample + negativeCoefficient = i == 0 ? (int)samplePeriod : 0, // Sample period in first condition only + offset = offset, + deadband = deadband, + positiveSaturation = 10000, // Full range + negativeSaturation = 10000 // Full range + }; + } + + // Try updating first + int hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.CustomForce, conditions); + if (hresult != 0) + { + // If effect doesn't exist (0x80004004 is HRESULT for E_ABORT) + if (hresult == unchecked((int)0x80004004)) + { + hresult = Native.CreateFFBEffect(guidInstance, FFBEffects.CustomForce); + if (hresult != 0) + { + DebugLog($"CreateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + // Try updating again after creation + hresult = Native.UpdateFFBEffect(guidInstance, FFBEffects.CustomForce, conditions); + if (hresult != 0) + { + DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + } + else + { + DebugLog($"UpdateFFBEffect Failed: 0x{hresult.ToString("x")} {WinErrors.GetSystemMessage(hresult)}"); + return false; + } + } + return true; + } - /// - /// Removes an FFB Effect from the device
- /// Refer to FFBEffects enum for all effect types - ///
- /// - /// True if effect was removed sucessfully - /// - public static bool DestroyFFBEffect(DeviceInfo device, FFBEffects effectType) => DestroyFFBEffect(device.guidInstance, effectType); - /// - /// Fetches supported FFB Effects by specified Device
- ///
- /// - /// string[] of effect names supported - /// - public static string[] GetDeviceFFBCapabilities(DeviceInfo device) => GetDeviceFFBCapabilities(device.guidInstance); - /// - /// Stops and removes all active effects on a device
- /// *Warning* Effects will have to be enabled again before use
- ///
- /// - /// True if effects stopped successfully - /// - public static bool StopAllFFBEffects(DeviceInfo device) => StopAllFFBEffects(device.guidInstance); + ////////////////////////////////////////////////////////////// + // Overloads - Unfortunately summaries don't propagate to overloads + ////////////////////////////////////////////////////////////// + + /// + /// Attach to Device, ready to get state/ForceFeedback

+ ///
+ /// + /// A boolean representing the if the Device was attached + /// + public static bool Attach(DeviceInfo device) => Attach(device.guidInstance); + + /// + /// Remove a specified Device + /// + /// + /// True upon sucessful destruction + /// + public static bool Destroy(DeviceInfo device) => Destroy(device.guidInstance); + + /// + /// Retrieve state of the Device, Flattened for easier comparison.
+ ///
+ /// + /// FlatJoyState2 + /// + public static FlatJoyState2 GetDeviceState(DeviceInfo device) => GetDeviceState(device.guidInstance); + + /// + /// Retrieve state of the Device
+ /// *Warning* DIJOYSTATE2 contains arrays making it difficult to compare, concider using GetDeviceState + ///
+ /// + /// DIJOYSTATE2 + /// + public static DIJOYSTATE2 GetDeviceStateRaw(DeviceInfo device) => GetDeviceStateRaw(device.guidInstance); + + /// + /// Retrieve the capabilities of the device. E.g. # Buttons, # Axes, Driver Version
+ /// Device must be attached first
+ ///
+ /// + /// DIDEVCAPS https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416607(v=vs.85) + /// + public static DIDEVCAPS GetDeviceCapabilities(DeviceInfo device) => GetDeviceCapabilities(device.guidInstance); + + /// + /// Returns if the device has the ForceFeedback Flag
+ ///
+ /// + /// True if device can provide ForceFeedback
+ ///
+ public static bool FFBCapable(DeviceInfo device) => FFBCapable(device.guidInstance); + + /// + /// Returns the attached status of the device
+ ///
+ /// + /// True if device is attached + /// + public static bool isDeviceActive(DeviceInfo device) => isDeviceActive(device.guidInstance); + + /// + /// Enables an FFB Effect on the device.
+ /// E.g. FFBEffects.ConstantForce
+ /// Refer to FFBEffects enum for all effect types + ///
+ /// + /// True if effect was added sucessfully + /// + public static bool EnableFFBEffect(DeviceInfo device, FFBEffects effectType) => EnableFFBEffect(device.guidInstance, effectType); + + /// + /// Removes an FFB Effect from the device
+ /// Refer to FFBEffects enum for all effect types + ///
+ /// + /// True if effect was removed sucessfully + /// + public static bool DestroyFFBEffect(DeviceInfo device, FFBEffects effectType) => DestroyFFBEffect(device.guidInstance, effectType); + + /// + /// Fetches supported FFB Effects by specified Device
+ ///
+ /// + /// string[] of effect names supported + /// + public static string[] GetDeviceFFBCapabilities(DeviceInfo device) => GetDeviceFFBCapabilities(device.guidInstance); + + /// + /// Stops and removes all active effects on a device
+ /// *Warning* Effects will have to be enabled again before use
+ ///
+ /// + /// True if effects stopped successfully + /// + public static bool StopAllFFBEffects(DeviceInfo device) => StopAllFFBEffects(device.guidInstance); + + /// + /// Fetches device state and triggers events if state changed
+ ///
+ public static void Poll(DeviceInfo device) => Poll(device.guidInstance); + + /// + /// Obtains ActiveDeviceInfo for specified GUID
+ ///
+ /// + /// Bool if GUID was found
+ /// OUT ADI of device if found + ///
+ public static bool GetADI(DeviceInfo device, out ActiveDeviceInfo ADI) => GetADI(device.guidInstance, out ADI); + + ////////////////////////////////////////////////////////////// + // Effect Specific Methods Overloads + ////////////////////////////////////////////////////////////// + + /// + /// Update existing effect with new DICONDITION array

+ /// + /// DICondition[DeviceFFBEffectAxesCount]:

+ /// deadband: Inacive Zone [-10,000 - 10,000]
+ /// offset: Move Effect Center[-10,000 - 10,000]
+ /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
+ /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
+ /// negativeSaturation: Negative of center saturation [0 - 10,000]
+ /// positiveSaturation: Positive of center saturation [0 - 10,000]
+ ///
+ /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateEffect(DeviceInfo device, FFBEffects effect, DICondition[] conditions) => UpdateEffect(device.guidInstance, effect, conditions); + + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateConstantForceSimple(DeviceInfo device, int Magnitude) => UpdateConstantForceSimple(device.guidInstance, Magnitude); + + /// + /// deadband: Inacive Zone [-10,000 - 10,000]
+ /// offset: Move Effect Center[-10,000 - 10,000]
+ /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
+ /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
+ /// negativeSaturation: Negative of center saturation [0 - 10,000]
+ /// positiveSaturation: Positive of center saturation [0 - 10,000]
+ ///
+ /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateSpringSimple(DeviceInfo device, uint deadband, int offset, int negativeCoefficient, int positiveCoefficient, uint negativeSaturation, uint positiveSaturation) => UpdateSpringSimple(device.guidInstance, deadband, offset, negativeCoefficient, positiveCoefficient, negativeSaturation, positiveSaturation); + + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateDamperSimple(DeviceInfo device, int Magnitude) => UpdateDamperSimple(device.guidInstance, Magnitude); + + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateFrictionSimple(DeviceInfo device, int Magnitude) => UpdateFrictionSimple(device.guidInstance, Magnitude); + + /// + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing the if the Effect updated successfully + /// + public static bool UpdateInertiaSimple(DeviceInfo device, int Magnitude) => UpdateInertiaSimple(device.guidInstance, Magnitude); + + /// + /// Updates a periodic force feedback effect with specified magnitude + /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// + /// + /// A boolean representing if the Effect updated successfully + /// + public static bool UpdatePeriodicSimple(DeviceInfo device, FFBEffects effectType, int Magnitude, uint period = 30000, int rampStart = 0, int rampEnd = 0) => UpdatePeriodicSimple(device.guidInstance, effectType, Magnitude, period, rampStart, rampEnd); + + public static bool UpdateCustomForceEffect(DeviceInfo device, int[] forceData, uint samplePeriod) => UpdateCustomForceSimple(device.guidInstance, forceData, samplePeriod); + + } // End of DIManager - /// - /// Fetches device state and triggers events if state changed
- ///
- public static void Poll(DeviceInfo device) => Poll(device.guidInstance); - /// - /// Obtains ActiveDeviceInfo for specified GUID
- ///
- /// - /// Bool if GUID was found
- /// OUT ADI of device if found - ///
- public static bool GetADI(DeviceInfo device, out ActiveDeviceInfo ADI) => GetADI(device.guidInstance, out ADI); ////////////////////////////////////////////////////////////// - // Effect Specific Methods Overloads + // Utilities ////////////////////////////////////////////////////////////// /// - /// Update existing effect with new DICONDITION array

- /// - /// DICondition[DeviceFFBEffectAxesCount]:

- /// deadband: Inacive Zone [-10,000 - 10,000]
- /// offset: Move Effect Center[-10,000 - 10,000]
- /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
- /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
- /// negativeSaturation: Negative of center saturation [0 - 10,000]
- /// positiveSaturation: Positive of center saturation [0 - 10,000]
- ///
- /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateEffect(DeviceInfo device, DICondition[] conditions) => UpdateEffect(device.guidInstance, conditions); - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateConstantForceSimple(DeviceInfo device, int Magnitude) => UpdateConstantForceSimple(device.guidInstance, Magnitude); - - /// - /// deadband: Inacive Zone [-10,000 - 10,000]
- /// offset: Move Effect Center[-10,000 - 10,000]
- /// negativeCoefficient: Negative of center coefficient [-10,000 - 10,000]
- /// positiveCoefficient: Positive of center Coefficient [-10,000 - 10,000]
- /// negativeSaturation: Negative of center saturation [0 - 10,000]
- /// positiveSaturation: Positive of center saturation [0 - 10,000]
- ///
- /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateSpringSimple(DeviceInfo device, uint deadband, int offset, int negativeCoefficient, int positiveCoefficient, uint negativeSaturation, uint positiveSaturation) => UpdateSpringSimple(device.guidInstance, deadband, offset, negativeCoefficient, positiveCoefficient, negativeSaturation, positiveSaturation); - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateDamperSimple(DeviceInfo device, int Magnitude) => UpdateDamperSimple(device.guidInstance, Magnitude); - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] - /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateFrictionSimple(DeviceInfo device, int Magnitude) => UpdateFrictionSimple(device.guidInstance, Magnitude); - - /// - /// Magnitude: Strength of Force [-10,000 - 10,0000] + /// Helper class to print out user friendly system error codes. + /// Taken from: https://stackoverflow.com/a/21174331/9053848 /// - /// - /// A boolean representing the if the Effect updated successfully - /// - public static bool UpdateInertiaSimple(DeviceInfo device, int Magnitude) => UpdateInertiaSimple(device.guidInstance, Magnitude); - - } // End of DIManager - - - - ////////////////////////////////////////////////////////////// - // Utilities - ////////////////////////////////////////////////////////////// - - /// - /// Helper class to print out user friendly system error codes. - /// Taken from: https://stackoverflow.com/a/21174331/9053848 - /// - public static class WinErrors { -#region definitions - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr LocalFree(IntPtr hMem); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern int FormatMessage(FormatMessageFlags dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer, uint nSize, IntPtr Arguments); - - [Flags] - private enum FormatMessageFlags : uint { - FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100, - FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200, - FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000, - FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000, - FORMAT_MESSAGE_FROM_HMODULE = 0x00000800, - FORMAT_MESSAGE_FROM_STRING = 0x00000400, + public static class WinErrors + { + #region definitions + [DllImport("kernel32.dll", SetLastError = true)] + static extern IntPtr LocalFree(IntPtr hMem); + + [DllImport("kernel32.dll", SetLastError = true)] + static extern int FormatMessage(FormatMessageFlags dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer, uint nSize, IntPtr Arguments); + + [Flags] + private enum FormatMessageFlags : uint + { + FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100, + FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200, + FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000, + FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000, + FORMAT_MESSAGE_FROM_HMODULE = 0x00000800, + FORMAT_MESSAGE_FROM_STRING = 0x00000400, + } + #endregion + + /// + /// Gets a user friendly string message for a system error code + /// + /// System error code + /// Error string + public static string GetSystemMessage(int errorCode) + { + try + { + IntPtr lpMsgBuf = IntPtr.Zero; + + int dwChars = FormatMessage( + FormatMessageFlags.FORMAT_MESSAGE_ALLOCATE_BUFFER | FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM | FormatMessageFlags.FORMAT_MESSAGE_IGNORE_INSERTS, + IntPtr.Zero, + (uint)errorCode, + 0, // Default language + ref lpMsgBuf, + 0, + IntPtr.Zero); + if (dwChars == 0) + { + // Handle the error. + int le = Marshal.GetLastWin32Error(); + return "Unable to get error code string from System - Error " + le.ToString(); + } + + string sRet = Marshal.PtrToStringAnsi(lpMsgBuf); + + // Free the buffer. + lpMsgBuf = LocalFree(lpMsgBuf); + return sRet; + } + catch (Exception e) + { + return "Unable to get error code string from System -> " + e.ToString(); + } + } } -#endregion /// - /// Gets a user friendly string message for a system error code + /// Only execute an Action after it hasn't been called for a timeout period
+ /// Setup: private static Debouncer DebouncerName = new Debouncer(300); // 300ms
+ /// Invocation: DebouncerName.Debounce(() => { Console.WriteLine("Executed"); });
+ /// Source: https://stackoverflow.com/a/47933557/3055031 (Modifed) ///
- /// System error code - /// Error string - public static string GetSystemMessage(int errorCode) { - try { - IntPtr lpMsgBuf = IntPtr.Zero; - - int dwChars = FormatMessage( - FormatMessageFlags.FORMAT_MESSAGE_ALLOCATE_BUFFER | FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM | FormatMessageFlags.FORMAT_MESSAGE_IGNORE_INSERTS, - IntPtr.Zero, - (uint)errorCode, - 0, // Default language - ref lpMsgBuf, - 0, - IntPtr.Zero); - if (dwChars == 0) { - // Handle the error. - int le = Marshal.GetLastWin32Error(); - return "Unable to get error code string from System - Error " + le.ToString(); - } - - string sRet = Marshal.PtrToStringAnsi(lpMsgBuf); - - // Free the buffer. - lpMsgBuf = LocalFree(lpMsgBuf); - return sRet; - } catch (Exception e) { - return "Unable to get error code string from System -> " + e.ToString(); - } - } - } - - /// - /// Only execute an Action after it hasn't been called for a timeout period
- /// Setup: private static Debouncer DebouncerName = new Debouncer(300); // 300ms
- /// Invocation: DebouncerName.Debounce(() => { Console.WriteLine("Executed"); });
- /// Source: https://stackoverflow.com/a/47933557/3055031 (Modifed) - ///
- public class Debouncer { - private List CancelTokens = new List(); - private int TimeoutMs; - private readonly object _lockThis = new object(); // Use a locking object to prevent the debouncer to trigger again while the func is still running - - public Debouncer(int timeoutMs = 300) { - this.TimeoutMs = timeoutMs; - } + public class Debouncer + { + private List CancelTokens = new List(); + private int TimeoutMs; + private readonly object _lockThis = new object(); // Use a locking object to prevent the debouncer to trigger again while the func is still running + + public Debouncer(int timeoutMs = 300) + { + this.TimeoutMs = timeoutMs; + } - public void Debounce(Action TargetAction) { - CancelAllTokens(); // Cancel existing Tokens Each invocation - var tokenSource = new CancellationTokenSource(); // Token for this invocation - lock (_lockThis) { CancelTokens.Add(tokenSource); } // Safely add this Token to the list - Task.Delay(TimeoutMs, tokenSource.Token).ContinueWith(task => { // (Note: All Tasks continue) - if (!tokenSource.IsCancellationRequested) { // if this is the task that hasn't been canceled - CancelAllTokens(); // Clear - CancelTokens = new List(); // Empty List - lock (_lockThis) { TargetAction(); } // Excute Action - } - }, TaskScheduler.FromCurrentSynchronizationContext()); // Perform on current thread - } + public void Debounce(Action TargetAction) + { + CancelAllTokens(); // Cancel existing Tokens Each invocation + var tokenSource = new CancellationTokenSource(); // Token for this invocation + lock (_lockThis) { CancelTokens.Add(tokenSource); } // Safely add this Token to the list + Task.Delay(TimeoutMs, tokenSource.Token).ContinueWith(task => + { // (Note: All Tasks continue) + if (!tokenSource.IsCancellationRequested) + { // if this is the task that hasn't been canceled + CancelAllTokens(); // Clear + CancelTokens = new List(); // Empty List + lock (_lockThis) { TargetAction(); } // Excute Action + } + }, TaskScheduler.FromCurrentSynchronizationContext()); // Perform on current thread + } - private void CancelAllTokens() { - foreach (var token in CancelTokens) { - if (!token.IsCancellationRequested) { token.Cancel(); } - } + private void CancelAllTokens() + { + foreach (var token in CancelTokens) + { + if (!token.IsCancellationRequested) { token.Cancel(); } + } + } } - } -} \ No newline at end of file +} diff --git a/Plugin/DirectInputTypes.cs b/Plugin/DirectInputTypes.cs index 36600ba..3f0258c 100644 --- a/Plugin/DirectInputTypes.cs +++ b/Plugin/DirectInputTypes.cs @@ -18,13 +18,20 @@ public enum FFBEffects { Inertia = 9, Friction = 10, CustomForce = 11 - } + } - /// - /// Types of OnDeviceChange DBTEvents
- /// More info: https://docs.microsoft.com/en-us/windows/win32/devio/wm-devicechange - ///
- public enum DBTEvents { + public struct CustomForceData + { + public int[] ForceData; // Array of force values + public uint SamplePeriod; // Time in microseconds between samples + public uint Channels; // Number of channels (typically 1) + } + + /// + /// Types of OnDeviceChange DBTEvents
+ /// More info: https://docs.microsoft.com/en-us/windows/win32/devio/wm-devicechange + ///
+ public enum DBTEvents { DBT_DEVNODES_CHANGED = 0x0007, DBT_QUERYCHANGECONFIG = 0x0017, DBT_CONFIGCHANGED = 0x0018, diff --git a/Plugin/Samples.meta b/Plugin/Samples.meta new file mode 100644 index 0000000..44f9499 --- /dev/null +++ b/Plugin/Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 61cbd610307b1224db5fae436d536cd5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugin/Samples/InputSystem.meta b/Plugin/Samples/InputSystem.meta new file mode 100644 index 0000000..19dc853 --- /dev/null +++ b/Plugin/Samples/InputSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7152b53e561ca041ad8289fba729282 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugin/Samples~/InputSystem/ControlScheme.inputactions b/Plugin/Samples/InputSystem/ControlScheme.inputactions similarity index 100% rename from Plugin/Samples~/InputSystem/ControlScheme.inputactions rename to Plugin/Samples/InputSystem/ControlScheme.inputactions diff --git a/Plugin/Samples/InputSystem/ControlScheme.inputactions.meta b/Plugin/Samples/InputSystem/ControlScheme.inputactions.meta new file mode 100644 index 0000000..1eb1051 --- /dev/null +++ b/Plugin/Samples/InputSystem/ControlScheme.inputactions.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 85a13ad7935e3af44bf556791baaebf5 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3} + generateWrapperCode: 0 + wrapperCodePath: + wrapperClassName: + wrapperCodeNamespace: diff --git a/Plugin/Samples/InputSystem/FFBInspectorDemo.cs b/Plugin/Samples/InputSystem/FFBInspectorDemo.cs new file mode 100644 index 0000000..d9b66a0 --- /dev/null +++ b/Plugin/Samples/InputSystem/FFBInspectorDemo.cs @@ -0,0 +1,302 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.InputSystem; +using DirectInputManager; +using UnityEditor.Experimental.GraphView; + +public class FFBInspectorDemo : MonoBehaviour +{ + public InputActionAsset ControlScheme; // Input System control scheme + DirectInputDevice ISDevice; + InputActionMap Actions; + + public bool EnableFFB = true; + public string FFBDeviceName = "Waiting for Play Mode"; + [Range(0, 1)] public float FFBAxisValue = 0; + + [Header("FFB Constant Force")] + public bool ConstantForceEnabled = false; + [Range(-10000f, 10000f)] public int ConstantForceMagnitude; + + [Header("FFB Damper")] + public bool DamperForceEnabled = false; + [Range(-10000f, 10000f)] public int DamperMagnitude; + + [Header("FFB Friction")] + public bool FrictionForceEnabled = false; + [Range(-10000f, 10000f)] public int FrictionMagnitude; + + [Header("FFB Inertia")] + public bool InertiaForceEnabled = false; + [Range(-10000f, 10000f)] public int InertiaMagnitude; + + [Header("FFB Spring")] + public bool SpringForceEnabled = false; + [Range(0, 10000f)] public uint SpringDeadband; + [Range(-10000f, 10000f)] public int SpringOffset; + [Range(0, 10000f)] public int SpringCoefficient; + [Range(0, 10000f)] public uint SpringSaturation; + + + [Header("Periodic & Custom Effects \nPlease note that negative values may result unexpected FFB! \n\nFFB Sine")] + public bool SineForceEnabled = false; + [Range(-10000f, 10000f)] public int SineMagnitude; + [Range(0, 100000)] public uint SinePeriod = 30000; // Default to 30000 microseconds + + [Header("FFB Square")] + public bool SquareForceEnabled = false; + [Range(-10000f, 10000f)] public int SquareMagnitude; + [Range(0, 100000)] public uint SquarePeriod = 30000; // Default to 30000 microseconds + + [Header("FFB Triangle")] + public bool TriangleForceEnabled = false; + [Range(-10000f, 10000f)] public int TriangleMagnitude; + [Range(0, 100000)] public uint TrianglePeriod = 30000; // Default to 30000 microseconds + + [Header("FFB SawtoothUp")] + public bool SawtoothUpForceEnabled = false; + [Range(-10000f, 10000f)] public int SawtoothUpMagnitude; + [Range(0, 100000)] public uint SawtoothUpPeriod = 30000; // Default to 30000 microseconds + + [Header("FFB SawtoothDown")] + public bool SawtoothDownForceEnabled = false; + [Range(-10000f, 10000f)] public int SawtoothDownMagnitude; + [Range(0, 100000)] public uint SawtoothDownPeriod = 30000; // Default to 30000 microseconds + + [Header("FFB Ramp")] + public bool RampForceEnabled = false; + [Range(-10000f, 10000f)] public int RampStart; + [Range(-10000f, 10000f)] public int RampEnd; + + bool ConstantForceWasEnabled { get; set; } + bool DamperForceWasEnabled { get; set; } + bool FrictionForceWasEnabled { get; set; } + bool InertiaForceWasEnabled { get; set; } + bool SpringForceWasEnabled { get; set; } + bool SineForceWasEnabled { get; set; } + bool SquareForceWasEnabled { get; set; } + bool TriangleForceWasEnabled { get; set; } + bool SawtoothUpForceWasEnabled { get; set; } + bool SawtoothDownForceWasEnabled { get; set; } + bool RampForceWasEnabled { get; set; } + ////////////////bool CustomForceEnabled { get; set; } + + ////////////////[Header("FFB Custom Force - LOOKS TO BE IMCOMPLETE (HAS UNKNOWN ISSUE), Fanatec CSL DD was used fyi.")] + ////////////////public bool CustomForceEnabled = false; + ////////////////[Range(-10000f, 10000f)] public int[] CustomForceMagnitudes = new int[10]; + ////////////////[Range(1000, 10000)] public uint CustomForceSamplePeriod = 1000; + + void Start() + { + Actions = ControlScheme.FindActionMap("DirectInputDemo"); // Find the correct action map + Actions.Enable(); + } + + void Update() + { + if (!EnableFFB) { return; } + if (ISDevice == null) + { + FFBDeviceName = "Waiting for Steering Device"; // Reset device name status + ISDevice = Actions.FindAction("FFBAxis").controls // Select the control intended to have FFB + .Select(x => x.device) // Select the "device" child element + .OfType() // Filter to our DirectInput Type + .Where(d => d.description.capabilities.Contains("\"FFBCapable\":true")) // Ensure the Device is FFBCapable + .Where(d => DIManager.Attach(d.description.serial)) // Attempt to attach to device + .FirstOrDefault(); // Return the first successful or null if none found + if (ISDevice == null) { return; } + FFBDeviceName = ISDevice.name + " : " + ISDevice.description.serial; + Debug.Log($"FFB Device: {ISDevice.description.serial}, Acquired: {DIManager.Attach(ISDevice.description.serial)}"); + } + + if (ISDevice is not null) + { + FFBAxisValue = Actions.FindAction("FFBAxis").ReadValue(); // Poll state of input axis + + // Update all enabled effects + if (ConstantForceEnabled) + { + if (ConstantForceWasEnabled) + DIManager.UpdateConstantForceSimple(ISDevice.description.serial, ConstantForceMagnitude); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.ConstantForce); + + ConstantForceWasEnabled = true; + } + else if (ConstantForceWasEnabled) + { + ConstantForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.ConstantForce); + } + + if (DamperForceEnabled) + { + if (DamperForceWasEnabled) + DIManager.UpdateDamperSimple(ISDevice.description.serial, DamperMagnitude); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Damper); + + DamperForceWasEnabled = true; + } + else if (DamperForceWasEnabled) + { + DamperForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Damper); + } + + if (FrictionForceEnabled) + { + if (FrictionForceWasEnabled) + DIManager.UpdateFrictionSimple(ISDevice.description.serial, FrictionMagnitude); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Friction); + + FrictionForceWasEnabled = true; + } + else if (FrictionForceWasEnabled) + { + FrictionForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Friction); + } + + if (InertiaForceEnabled) + { + if (InertiaForceWasEnabled) + DIManager.UpdateInertiaSimple(ISDevice.description.serial, InertiaMagnitude); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Inertia); + + InertiaForceWasEnabled = true; + } + else if (InertiaForceWasEnabled) + { + InertiaForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Inertia); + } + + if (SpringForceEnabled) + { + if (SpringForceWasEnabled) + DIManager.UpdateSpringSimple(ISDevice.description.serial, SpringDeadband, SpringOffset, + SpringCoefficient, SpringCoefficient, SpringSaturation, SpringSaturation); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Spring); + + SpringForceWasEnabled = true; + } + else if (SpringForceWasEnabled) + { + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Spring); + SpringForceWasEnabled = false; + } + + if (SineForceEnabled) + { + if (SineForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.Sine, SineMagnitude, SinePeriod); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Sine); + + SineForceWasEnabled = true; + } + else if (SineForceWasEnabled) + { + SineForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Sine); + } + + if (SquareForceEnabled) + { + if (SquareForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.Square, SquareMagnitude, SquarePeriod); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Square); + + SquareForceWasEnabled = true; + } + else if (SquareForceWasEnabled) + { + SquareForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Square); + } + + if (TriangleForceEnabled) + { + if (TriangleForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.Triangle, TriangleMagnitude, TrianglePeriod); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Triangle); + + TriangleForceWasEnabled = true; + } + else if (TriangleForceWasEnabled) + { + TriangleForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.Triangle); + } + + if (SawtoothUpForceEnabled) + { + if (SawtoothUpForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.SawtoothUp, SawtoothUpMagnitude, SawtoothUpPeriod); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.SawtoothUp); + + SawtoothUpForceWasEnabled = true; + } + else if (SawtoothUpForceWasEnabled) + { + SawtoothUpForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.SawtoothUp); + } + + if (SawtoothDownForceEnabled) + { + if (SawtoothUpForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.SawtoothDown, SawtoothDownMagnitude, SawtoothDownPeriod); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.SawtoothDown); + + SawtoothDownForceWasEnabled = true; + + } + else if (SawtoothDownForceWasEnabled) + { + SawtoothDownForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.SawtoothDown); + } + + if (RampForceEnabled) + { + if (RampForceWasEnabled) + DIManager.UpdatePeriodicSimple(ISDevice.description.serial, FFBEffects.RampForce, 0, 0, RampStart, RampEnd); + else + DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.RampForce); + + RampForceWasEnabled = true; + } + else if (RampForceWasEnabled) + { + RampForceWasEnabled = false; + DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.RampForce); + } + + + //////////////////if (CustomForceEnabled) + ////////////////// { if (CustomForceWasEnabled) DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.CustomForce); + ////////////////// else DIManager.UpdateCustomForceEffect(ISDevice.description.serial, CustomForceMagnitudes, CustomForceSamplePeriod); CustomForceEnabled = true;} + //////////////////else if (CustomForceEnabled) { + ////////////////// DIManager.DestroyFFBEffect(ISDevice.description.serial, FFBEffects.CustomForce); CustomForceEnabled = false;} + } + } + + void OnDestroy() + { + if (ISDevice != null) + { + DIManager.Destroy(ISDevice.description.serial); + } + } +} diff --git a/Plugin/Samples/InputSystem/FFBInspectorDemo.cs.meta b/Plugin/Samples/InputSystem/FFBInspectorDemo.cs.meta new file mode 100644 index 0000000..4fd5a5d --- /dev/null +++ b/Plugin/Samples/InputSystem/FFBInspectorDemo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d90a5111f30bed4d82386d1e50cce5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugin/Samples/InputSystem/Sample.unity b/Plugin/Samples/InputSystem/Sample.unity new file mode 100644 index 0000000..db50e13 --- /dev/null +++ b/Plugin/Samples/InputSystem/Sample.unity @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + - component: {fileID: 519420029} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &519420029 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1561323689 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1561323691} + - component: {fileID: 1561323690} + m_Layer: 0 + m_Name: Sample + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1561323690 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1561323689} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7d90a5111f30bed4d82386d1e50cce5d, type: 3} + m_Name: + m_EditorClassIdentifier: + ControlScheme: {fileID: -944628639613478452, guid: 85a13ad7935e3af44bf556791baaebf5, type: 3} + EnableFFB: 1 + FFBDeviceName: Waiting for Play Mode + FFBAxisValue: 0 + ConstantForceEnabled: 0 + ConstantForceMagnitude: 0 + DamperForceEnabled: 0 + DamperMagnitude: 0 + FrictionForceEnabled: 0 + FrictionMagnitude: 0 + InertiaForceEnabled: 0 + InertiaMagnitude: 0 + SpringForceEnabled: 0 + SpringDeadband: 0 + SpringOffset: 0 + SpringCoefficient: 0 + SpringSaturation: 0 + SineForceEnabled: 0 + SineMagnitude: 0 + SquareForceEnabled: 0 + SquareMagnitude: 0 + TriangleForceEnabled: 0 + TriangleMagnitude: 0 + SawtoothUpForceEnabled: 0 + SawtoothUpMagnitude: 0 + SawtoothDownForceEnabled: 0 + SawtoothDownMagnitude: 0 + RampForceEnabled: 0 + RampMagnitude: 0 +--- !u!4 &1561323691 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1561323689} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 519420032} + - {fileID: 1561323691} diff --git a/Plugin/Samples/InputSystem/Sample.unity.meta b/Plugin/Samples/InputSystem/Sample.unity.meta new file mode 100644 index 0000000..9657fb2 --- /dev/null +++ b/Plugin/Samples/InputSystem/Sample.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 72217aa5adedb2f4daaee59f32e1d652 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugin/Samples~/InputSystem/FFBInspectorDemo.cs b/Plugin/Samples~/InputSystem/FFBInspectorDemo.cs deleted file mode 100644 index 325ee3c..0000000 --- a/Plugin/Samples~/InputSystem/FFBInspectorDemo.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.InputSystem; -using DirectInputManager; - -public class FFBInspectorDemo : MonoBehaviour { - public InputActionAsset ControlScheme; // Input System control scheme - DirectInputDevice ISDevice; - InputActionMap Actions; - - public bool EnableFFB = true; - public string FFBDeviceName = "Waiting for Play Mode"; - [Range(0,1)] public float FFBAxisValue = 0; - - [Header("FFB Constant Force")] - public bool ConstantForceEnabled = false; - [Range(-10000f, 10000f)]public int ConstantForceMagnitude; - - [Header("FFB Damper")] - public bool DamperForceEnabled = false; - [Range(-10000f, 10000f)] public int DamperMagnitude; - - [Header("FFB Friction")] - public bool FrictionForceEnabled = false; - [Range(-10000f, 10000f)] public int FrictionMagnitude; - - [Header("FFB Inertia")] - public bool InertiaForceEnabled = false; - [Range(-10000f, 10000f)] public int InertiaMagnitude; - - [Header("FFB Spring")] - public bool SpringForceEnabled = false; - [Range(0, 10000f)] public uint SpringDeadband; - [Range(-10000f, 10000f)] public int SpringOffset; - [Range(0, 10000f)] public int SpringCoefficient; - [Range(0, 10000f)] public uint SpringSaturation; - - void Start() { - Actions = ControlScheme.FindActionMap("DirectInputDemo"); // Find the correct action map - Actions.Enable(); - } - - void Update(){ - if(!EnableFFB){ return; } - if (ISDevice == null) { - FFBDeviceName = "Waiting for Steering Device"; // Reset device name status - ISDevice = Actions.FindAction("FFBAxis").controls // Select the control intended to have FFB - .Select(x => x.device) // Select the "device" child element - .OfType() // Filter to our DirectInput Type - .Where(d => d.description.capabilities.Contains("\"FFBCapable\":true")) // Ensure the Device is FFBCapable - .Where(d => DIManager.Attach(d.description.serial)) // Attempt to attach to device - .FirstOrDefault(); // Return the first successful or null if none found - if (ISDevice == null) { return; } - FFBDeviceName = ISDevice.name + " : " + ISDevice.description.serial; - Debug.Log($"FFB Device: {ISDevice.description.serial}, Acquired: {DIManager.Attach(ISDevice.description.serial)}"); - DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.ConstantForce); - DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Damper); - DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Friction); - DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Inertia); - DIManager.EnableFFBEffect(ISDevice.description.serial, FFBEffects.Spring); - } - - if (ISDevice is not null) { - FFBAxisValue = Actions.FindAction("FFBAxis").ReadValue(); // Poll state of input axis - if (ConstantForceEnabled) { DIManager.UpdateConstantForceSimple(ISDevice.description.serial, ConstantForceMagnitude); } - if (DamperForceEnabled) { DIManager.UpdateDamperSimple(ISDevice.description.serial, DamperMagnitude); } - if (FrictionForceEnabled) { DIManager.UpdateFrictionSimple(ISDevice.description.serial, FrictionMagnitude); } - if (InertiaForceEnabled) { DIManager.UpdateInertiaSimple(ISDevice.description.serial, InertiaMagnitude); } - if (SpringForceEnabled) { DIManager.UpdateSpringSimple(ISDevice.description.serial, SpringDeadband, SpringOffset, SpringCoefficient, SpringCoefficient, SpringSaturation, SpringSaturation); } - } - } - - void OnDestroy(){ - if(ISDevice != null){ - DIManager.StopAllFFBEffects(ISDevice.description.serial); - } - } -} diff --git a/README.md b/README.md index c124673..0d830c7 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ This package allows you to easily integrate both the input and ForceFeedback fea The package will create a virtual device inside Unity's Input System. This device can then be used like any other device inside the Input System, allowing for easy rebinding. ForceFeedback capabilites can be accessed via the DIManager class. The [DirectInputExplorer](../../tree/main/DirectInputExplorer~) is a windows forms application built in parallel with the C++ library to enable quick development by avoiding the need to reload Unity after every change. It also functions as an easy way to examine DirectInput devices. # Quick Start +![image](https://github.com/user-attachments/assets/5398f792-d075-41fc-a292-1a7a585dbdc8) ### Installation @@ -20,9 +21,7 @@ This package requires use of Unity's new Input System, ensure [com.unity.inputsy `Window -> Package Manager => Input System` -Next, install this package: - -`Package Manager => + => "Add package from git URL..." => ` `https://github.com/MrTimcakes/Unity-DirectInput.git` +Next, install (copy and paste) the Plugin folder of this repo into the Assets folder of your Unity project. You can copy and paste the whole content, and Unity will automatically exclude the unrelated contents as their folder names have "~" characters. Those unrelated folders have the source code of the native Direct Input FFB DLL that Unity uses. Open the Sample Scene there and play the scene to start working with this asset. ## Supported ForceFeedback Effects @@ -30,51 +29,61 @@ Next, install this package: | Effect | Supported | |---------------|-----------| | ConstantForce | ✅ | -| CustomForce | 🔲 | +| CustomForce | â„šī¸ | | Damper | ✅ | | Friction | ✅ | | Inertia | ✅ | -| RampForce | 🔲 | -| SawtoothDown | 🔲 | -| SawtoothUp | 🔲 | -| Sine | 🔲 | +| RampForce | ✅ | +| SawtoothDown | ✅ | +| SawtoothUp | ✅ | +| Sine | ✅ | | Spring | ✅ | -| Square | 🔲 | -| Triangle | 🔲 | +| Square | ✅ | +| Triangle | ✅ | -[comment]: <> (✅ 🔲) +[comment]: <> (✅ â„šī¸ 🔲) + +Note that everything is adjustable in the native DLL, And the Custom Force effect exists but has not been fully done. ## Compatible Devices +### Note that all the devices that use Direct Input (from the old Logitech G wheels to the advanced Simcube ones) should work +The community has tested and verified these devices do indeed work. Albeit not all devices support all the FFB effects! | Peripheral | Test Status | |------------------------------------|----------------| +| [Fanatec CSL DD (Both PC & Comp mode + 8NM Kit)](https://fanatec.com/eu-en/csl-dd-8-nm) | ✅ Verified | | [Fanatec CSL Elite](https://fanatec.com/eu-en/racing-wheels-wheel-bases/wheel-bases/csl-elite-wheel-base-officially-licensed-for-playstation) | ✅ Verified | | [Fanatec CSW V2.0](https://fanatec.com/eu-en/racing-wheels-wheel-bases/wheel-bases/clubsport-wheel-base-v2-servo) | ✅ Verified | | [Fanatec WRC Wheel Rim](https://fanatec.com/eu-en/steering-wheels/csl-elite-steering-wheel-wrc) | ✅ Verified | | [Fanatec Formula V2 Wheel Rim](https://fanatec.com/eu-en/steering-wheels/clubsport-steering-wheel-formula-v2) & [APM](https://fanatec.com/eu-en/shifters-others/podium-advanced-paddle-module) | ✅ Verified | | [Fanatec CSL LC Pedals](https://fanatec.com/eu-en/pedals/csl-elite-pedals) | ✅ Verified | +| [Fanatec ClubSport Pedals V1](https://www.youtube.com/watch?v=jw52Dq3SZaA) | ✅ Verified | | [Fanatec ClubSport Pedals V3](https://fanatec.com/eu-en/pedals/clubsport-pedals-v3) | ✅ Verified | | [Fanatec ClubSport Shifter SQ V 1.5](https://fanatec.com/eu-en/shifters-others/clubsport-shifter-sq-v-1.5) | ✅ Verified | | [Logitech G29 / G920](https://www.logitechg.com/en-gb/products/driving/driving-force-racing-wheel.html) | ✅ Verified | -| [PRO Racing Wheel](https://www.logitechg.com/en-gb/products/driving/pro-racing-wheel.html) | 🔲 Untested | +| [Moza R9](https://mozaracing.com/wheel-base-r9/) | ✅ Verified | +| [PRO Racing Wheel](https://www.logitechg.com/en-gb/products/driving/pro-racing-wheel.html) | ✅ Verified | +| [Simagic Alpha-Mini](https://us.sim-motion.com/products/simagic-alpha-mini-wheel-base) | ✅ Verified | +| [Thrustmaster TX](https://eshop.thrustmaster.com/en_us/tx-racing-wheel-leather-edition.html) | ✅ Verified | + [comment]: <> (✅ 🔲) +Note for pedals, only input readings were guaranteed to *likely* work fine. ## Environment -This plugin only works on Windows 64 bit. +This plugin only works on Windows 8+ 64-bit. Latest verified Unity version: 2022.2.1f1 # Notice - -Occasionally calls to EnumerateDevices will take orders of magnitude longer than usual to execute (up to 60 seconds), this is caused by a Windows bug attempting to load an absent hardware device. USB Audio DACs & Corsair keyboards are known the cause this issue, try disconnecting and reconnecting offending USB devices. For more information see [this](https://stackoverflow.com/questions/10967795/directinput8-enumdevices-sometimes-painfully-slow) StackOverflow post about the issue from 2012. See issue [#1](/../../issues/1) for more info. +Occasionally calls to EnumerateDevices will take orders of magnitude longer than usual to execute (up to 60 seconds), this is caused by a Windows bug attempting to load an absent hardware device. USB Audio DACs & Corsair keyboards are known the cause this issue, try disconnecting and reconnecting offending USB devices. For more information see [this](https://stackoverflow.com/questions/10967795/directinput8-enumdevices-sometimes-painfully-slow) StackOverflow post about the issue from 2012. See issue [#1](https://github.com/MrTimcakes/Unity-DirectInput/issues/1) for more info. # Support -If you're having any problem, please [raise an issue](https://github.com/MrTimcakes/Unity-DirectInput/issues/new) on GitHub. +If you have problems, please [raise an issue](https://github.com/MrTimcakes/Unity-DirectInput/issues/new) on GitHub. # License -This project is free Open-Source software, and is released under the LGPL-3.0 License, further information can be found under the terms specified in the [license](/../../blob/main/LICENSE). +This project is free Open-Source software released under the LGPL-3.0 License. Further information can be found under the terms specified in the [license](/../../blob/main/LICENSE).