diff --git a/AppSettings.cs b/AppSettings.cs index 66116bc..9ed3a9f 100644 --- a/AppSettings.cs +++ b/AppSettings.cs @@ -91,7 +91,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "False" )] // false + [DefaultSettingValueAttribute( "False" )] public Boolean BlendUnmapped // Joystick (back compatibility) { get { return ( Boolean )this["BlendUnmapped"]; } @@ -99,18 +99,50 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "False" )] // false + [DefaultSettingValueAttribute( "False" )] public Boolean BlendUnmappedGP { get { return ( Boolean )this["BlendUnmappedGP"]; } set { this["BlendUnmappedGP"] = value; } } + [UserScopedSettingAttribute( )] + [DefaultSettingValueAttribute( "True" )] + public Boolean ShowJoystick + { + get { return ( Boolean )this["ShowJoystick"]; } + set { this["ShowJoystick"] = value; } + } + + [UserScopedSettingAttribute( )] + [DefaultSettingValueAttribute( "True" )] + public Boolean ShowGamepad + { + get { return ( Boolean )this["ShowGamepad"]; } + set { this["ShowGamepad"] = value; } + } + + [UserScopedSettingAttribute( )] + [DefaultSettingValueAttribute( "True" )] + public Boolean ShowKeyboard + { + get { return ( Boolean )this["ShowKeyboard"]; } + set { this["ShowKeyboard"] = value; } + } + + [UserScopedSettingAttribute( )] + [DefaultSettingValueAttribute( "False" )] + public Boolean ShowMapped + { + get { return ( Boolean )this["ShowMapped"]; } + set { this["ShowMapped"] = value; } + } + // Seetings Window [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS1 { get { return ( String )this["IgnoreJS1"]; } @@ -118,7 +150,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS2 { get { return ( String )this["IgnoreJS2"]; } @@ -126,7 +158,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS3 { get { return ( String )this["IgnoreJS3"]; } @@ -134,7 +166,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS4 { get { return ( String )this["IgnoreJS4"]; } @@ -142,7 +174,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS5 { get { return ( String )this["IgnoreJS5"]; } @@ -150,7 +182,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS6 { get { return ( String )this["IgnoreJS6"]; } @@ -158,7 +190,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS7 { get { return ( String )this["IgnoreJS7"]; } @@ -166,7 +198,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String IgnoreJS8 { get { return ( String )this["IgnoreJS8"]; } @@ -174,7 +206,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "" )] // empty + [DefaultSettingValueAttribute( "" )] public String UserSCPath { get { return ( String )this["UserSCPath"]; } @@ -182,7 +214,7 @@ namespace SCJMapper_V2 } [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "False" )] // false + [DefaultSettingValueAttribute( "False" )] public Boolean UserSCPathUsed { get { return ( Boolean )this["UserSCPathUsed"]; } @@ -199,7 +231,7 @@ namespace SCJMapper_V2 [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "False" )] // false + [DefaultSettingValueAttribute( "False" )] public Boolean ForceIgnoreversion { get { return ( Boolean )this["ForceIgnoreversion"]; } @@ -208,7 +240,7 @@ namespace SCJMapper_V2 [UserScopedSettingAttribute( )] - [DefaultSettingValueAttribute( "False" )] // false + [DefaultSettingValueAttribute( "False" )] public Boolean DetectGamepad { get { return ( Boolean )this["DetectGamepad"]; } diff --git a/DeviceCls.cs b/DeviceCls.cs index bb57abd..75b7507 100644 --- a/DeviceCls.cs +++ b/DeviceCls.cs @@ -15,21 +15,13 @@ namespace SCJMapper_V2 public const String BlendedInput = " "; static public Boolean IsDeviceClass( String deviceClass ) { return false; } - public enum InputKind - { - Other, - Kbd, - Joystick, - Gamepad, - } - public abstract String DevClass { get; } public abstract String DevName { get; } public abstract System.Drawing.Color MapColor { get; } public abstract Boolean Activated { get; set; } - public virtual void FinishDX( ) {} - public virtual void ApplySettings( ){} + public virtual void FinishDX( ) { } + public virtual void ApplySettings( ) { } public abstract String GetLastChange( ); public abstract void GetCmdData( String cmd, out int data ); diff --git a/Form1.Designer.cs b/Form1.Designer.cs index b466c4c..7e939fe 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -47,7 +47,6 @@ this.btGrab = new System.Windows.Forms.Button(); this.btDump = new System.Windows.Forms.Button(); this.panel2 = new System.Windows.Forms.Panel(); - this.cbxInvert = new System.Windows.Forms.CheckBox(); this.btJsKbd = new System.Windows.Forms.Button(); this.IL = new System.Windows.Forms.ImageList(this.components); this.btBlend = new System.Windows.Forms.Button(); @@ -76,8 +75,6 @@ this.tlpanel = new System.Windows.Forms.TableLayoutPanel(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.txFilter = new System.Windows.Forms.TextBox(); - this.btClearFilter = new System.Windows.Forms.Button(); this.btJSTuning = new System.Windows.Forms.Button(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.btSettings = new System.Windows.Forms.Button(); @@ -92,6 +89,9 @@ this.cbxShowGamepad = new System.Windows.Forms.CheckBox(); this.cbxShowKeyboard = new System.Windows.Forms.CheckBox(); this.cbxShowMappedOnly = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txFilter = new System.Windows.Forms.TextBox(); + this.btClearFilter = new System.Windows.Forms.Button(); this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); this.tsDDbtProfiles = new System.Windows.Forms.ToolStripDropDownButton(); this.tsBtReset = new System.Windows.Forms.ToolStripDropDownButton(); @@ -107,8 +107,10 @@ this.loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.cmAddDel = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tsiAddBinding = new System.Windows.Forms.ToolStripMenuItem(); + this.tdiDelBinding = new System.Windows.Forms.ToolStripMenuItem(); this.UC_JoyPanel = new SCJMapper_V2.UC_JoyPanel(); - this.label2 = new System.Windows.Forms.Label(); this.cmCopyPaste.SuspendLayout(); this.panel2.SuspendLayout(); this.tc1.SuspendLayout(); @@ -121,6 +123,7 @@ this.tableLayoutPanel3.SuspendLayout(); this.flowLayoutPanel2.SuspendLayout(); this.statusStrip1.SuspendLayout(); + this.cmAddDel.SuspendLayout(); this.SuspendLayout(); // // btDumpList @@ -232,7 +235,6 @@ // panel2 // this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panel2.Controls.Add(this.cbxInvert); this.panel2.Controls.Add(this.btJsKbd); this.panel2.Controls.Add(this.btBlend); this.panel2.Controls.Add(this.lblLastJ); @@ -248,16 +250,6 @@ this.panel2.Size = new System.Drawing.Size(289, 142); this.panel2.TabIndex = 17; // - // cbxInvert - // - this.cbxInvert.AutoSize = true; - this.cbxInvert.Location = new System.Drawing.Point(89, 86); - this.cbxInvert.Name = "cbxInvert"; - this.cbxInvert.Size = new System.Drawing.Size(55, 17); - this.cbxInvert.TabIndex = 17; - this.cbxInvert.Text = "Invert"; - this.cbxInvert.UseVisualStyleBackColor = true; - // // btJsKbd // this.btJsKbd.FlatStyle = System.Windows.Forms.FlatStyle.Flat; @@ -283,6 +275,7 @@ this.IL.Images.SetKeyName(4, "X"); this.IL.Images.SetKeyName(5, "P"); this.IL.Images.SetKeyName(6, "Z"); + this.IL.Images.SetKeyName(7, "Add"); // // btBlend // @@ -308,7 +301,7 @@ // cbxThrottle // this.cbxThrottle.AutoSize = true; - this.cbxThrottle.Location = new System.Drawing.Point(89, 67); + this.cbxThrottle.Location = new System.Drawing.Point(89, 72); this.cbxThrottle.Name = "cbxThrottle"; this.cbxThrottle.Size = new System.Drawing.Size(66, 17); this.cbxThrottle.TabIndex = 13; @@ -375,6 +368,7 @@ // // treeView1 // + this.treeView1.ContextMenuStrip = this.cmAddDel; this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill; this.treeView1.HotTracking = true; this.treeView1.ImageKey = "Map"; @@ -572,26 +566,6 @@ this.tableLayoutPanel1.Size = new System.Drawing.Size(294, 131); this.tableLayoutPanel1.TabIndex = 23; // - // txFilter - // - this.txFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.txFilter.Location = new System.Drawing.Point(92, 28); - this.txFilter.Name = "txFilter"; - this.txFilter.Size = new System.Drawing.Size(120, 22); - this.txFilter.TabIndex = 25; - this.txFilter.WordWrap = false; - this.txFilter.TextChanged += new System.EventHandler(this.txFilter_TextChanged); - // - // btClearFilter - // - this.btClearFilter.Location = new System.Drawing.Point(218, 26); - this.btClearFilter.Name = "btClearFilter"; - this.btClearFilter.Size = new System.Drawing.Size(120, 24); - this.btClearFilter.TabIndex = 26; - this.btClearFilter.Text = "Clear Filter"; - this.btClearFilter.UseVisualStyleBackColor = true; - this.btClearFilter.Click += new System.EventHandler(this.btClearFilter_Click); - // // btJSTuning // this.btJSTuning.Location = new System.Drawing.Point(3, 93); @@ -767,6 +741,36 @@ this.cbxShowMappedOnly.UseVisualStyleBackColor = true; this.cbxShowMappedOnly.CheckedChanged += new System.EventHandler(this.cbxShowTreeOptions_CheckedChanged); // + // label2 + // + this.label2.Location = new System.Drawing.Point(3, 26); + this.label2.Margin = new System.Windows.Forms.Padding(3); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(83, 24); + this.label2.TabIndex = 27; + this.label2.Text = "Action Filter:"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // txFilter + // + this.txFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txFilter.Location = new System.Drawing.Point(92, 28); + this.txFilter.Name = "txFilter"; + this.txFilter.Size = new System.Drawing.Size(120, 22); + this.txFilter.TabIndex = 25; + this.txFilter.WordWrap = false; + this.txFilter.TextChanged += new System.EventHandler(this.txFilter_TextChanged); + // + // btClearFilter + // + this.btClearFilter.Location = new System.Drawing.Point(218, 26); + this.btClearFilter.Name = "btClearFilter"; + this.btClearFilter.Size = new System.Drawing.Size(120, 24); + this.btClearFilter.TabIndex = 26; + this.btClearFilter.Text = "Clear Filter"; + this.btClearFilter.UseVisualStyleBackColor = true; + this.btClearFilter.Click += new System.EventHandler(this.btClearFilter_Click); + // // toolStripStatusLabel2 // this.toolStripStatusLabel2.BackColor = System.Drawing.Color.DarkKhaki; @@ -912,6 +916,29 @@ this.statusStrip1.TabIndex = 26; this.statusStrip1.Text = "statusStrip1"; // + // cmAddDel + // + this.cmAddDel.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsiAddBinding, + this.tdiDelBinding}); + this.cmAddDel.Name = "cmAddDel"; + this.cmAddDel.Size = new System.Drawing.Size(159, 48); + this.cmAddDel.Opening += new System.ComponentModel.CancelEventHandler(this.cmAddDel_Opening); + // + // tsiAddBinding + // + this.tsiAddBinding.Name = "tsiAddBinding"; + this.tsiAddBinding.Size = new System.Drawing.Size(158, 22); + this.tsiAddBinding.Text = "Add Mapping"; + this.tsiAddBinding.Click += new System.EventHandler(this.tsiAddBinding_Click); + // + // tdiDelBinding + // + this.tdiDelBinding.Name = "tdiDelBinding"; + this.tdiDelBinding.Size = new System.Drawing.Size(158, 22); + this.tdiDelBinding.Text = "Delete Mapping"; + this.tdiDelBinding.Click += new System.EventHandler(this.tdiDelBinding_Click); + // // UC_JoyPanel // this.UC_JoyPanel.Dock = System.Windows.Forms.DockStyle.Fill; @@ -921,16 +948,6 @@ this.UC_JoyPanel.Size = new System.Drawing.Size(275, 315); this.UC_JoyPanel.TabIndex = 0; // - // label2 - // - this.label2.Location = new System.Drawing.Point(3, 26); - this.label2.Margin = new System.Windows.Forms.Padding(3); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(83, 24); - this.label2.TabIndex = 27; - this.label2.Text = "Action Filter:"; - this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -964,6 +981,7 @@ this.flowLayoutPanel2.PerformLayout(); this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); + this.cmAddDel.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -1039,13 +1057,15 @@ private System.Windows.Forms.Button btJsKbd; private System.Windows.Forms.Button btBlend; private System.Windows.Forms.Button btClip; - private System.Windows.Forms.CheckBox cbxInvert; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.CheckBox cbxShowJoystick; private System.Windows.Forms.CheckBox cbxShowGamepad; private System.Windows.Forms.CheckBox cbxShowKeyboard; private System.Windows.Forms.CheckBox cbxShowMappedOnly; private System.Windows.Forms.Label label2; + private System.Windows.Forms.ContextMenuStrip cmAddDel; + private System.Windows.Forms.ToolStripMenuItem tsiAddBinding; + private System.Windows.Forms.ToolStripMenuItem tdiDelBinding; } } diff --git a/Form1.cs b/Form1.cs index a9ae453..a8bd654 100644 --- a/Form1.cs +++ b/Form1.cs @@ -20,6 +20,8 @@ namespace SCJMapper_V2 private const String c_GithubLink = @"https://github.com/SCToolsfactory/SCJMapper-V2/releases"; private AppSettings m_AppSettings = new AppSettings( ); + private Boolean m_appLoading = true; // used to detect if we are loading (or running) + /// /// Holds the DXInput Joystick List @@ -77,19 +79,19 @@ namespace SCJMapper_V2 /// /// Detects and returns the current Input device /// - private DeviceCls.InputKind InputMode + private ActionCls.ActionDevice InputMode { get { if ( m_keyIn ) { - return DeviceCls.InputKind.Kbd; + return ActionCls.ActionDevice.AD_Keyboard; } else { if ( IsGamepadTab( tc1.SelectedTab ) ) { - return DeviceCls.InputKind.Gamepad; + return ActionCls.ActionDevice.AD_Gamepad; } else { - return DeviceCls.InputKind.Joystick; + return ActionCls.ActionDevice.AD_Joystick; } } } @@ -240,9 +242,17 @@ namespace SCJMapper_V2 txMappingName.BackColor = MyColors.ErrorColor; } + // load show checkboxes + cbxShowJoystick.Checked = m_AppSettings.ShowJoystick; + cbxShowGamepad.Checked = m_AppSettings.ShowGamepad; + cbxShowKeyboard.Checked = m_AppSettings.ShowKeyboard; + cbxShowMappedOnly.Checked = m_AppSettings.ShowMapped; + // poll the XInput log.Debug( "Start XInput polling" ); timer1.Start( ); // this one polls the joysticks to show the props + + m_appLoading = false; // no longer } @@ -336,7 +346,7 @@ namespace SCJMapper_V2 m_AT.Ctrl = treeView1; // the ActionTree owns the TreeView control m_AT.IgnoreMaps = m_AppSettings.IgnoreActionmaps; m_AT.DefineShowOptions( cbxShowJoystick.Checked, cbxShowGamepad.Checked, cbxShowKeyboard.Checked, cbxShowMappedOnly.Checked ); - m_AT.LoadTree( m_AppSettings.DefProfileName, addDefaultBinding ); // Init with default profile filepath + m_AT.LoadProfileTree( m_AppSettings.DefProfileName, addDefaultBinding ); // Init with default profile filepath // apply a default JS to Joystick mapping - can be changed and reloaded from XML mappings // must take care of Gamepads if there are (but we take care of one only...) @@ -575,6 +585,7 @@ namespace SCJMapper_V2 private void timer1_Tick( object sender, System.EventArgs e ) { if ( m_keyIn ) return; // allow keyboard / mouse input + if ( tc1.SelectedTab.Tag == null ) return; String ctrl = ""; int jsIndex = ( int )tc1.SelectedTab.Tag; // gets the index into the JS list @@ -592,14 +603,9 @@ namespace SCJMapper_V2 lblLastJ.Text = ctrl; if ( JoystickCls.CanThrottle( ctrl ) ) { cbxThrottle.Enabled = true; - cbxInvert.Enabled = true; - } - else if ( GamepadCls.CanInvert( ctrl ) ) { - cbxInvert.Enabled = true; } else { cbxThrottle.Checked = false; cbxThrottle.Enabled = false; - cbxInvert.Checked = false; cbxInvert.Enabled = false; } } @@ -608,15 +614,8 @@ namespace SCJMapper_V2 private void treeView1_AfterSelect( object sender, TreeViewEventArgs e ) { - if ( e.Node.Level == 1 ) { - // actions cannot have a blank - if there is one it's mapped - if ( e.Node.Text.IndexOf( " ", 0 ) > 0 ) { - lblAction.Text = e.Node.Text.Substring( 0, e.Node.Text.IndexOf( " ", 0 ) ); // get only the action part as Cmd. - } - else { - lblAction.Text = e.Node.Text; - } - } + String atx = m_AT.SelectedAction; + if ( !String.IsNullOrEmpty( atx ) ) lblAction.Text = atx; } @@ -624,8 +623,13 @@ namespace SCJMapper_V2 private void cbxShowTreeOptions_CheckedChanged( object sender, EventArgs e ) { + if (m_AT==null) return; // on init m_AT.DefineShowOptions( cbxShowJoystick.Checked, cbxShowGamepad.Checked, cbxShowKeyboard.Checked, cbxShowMappedOnly.Checked ); m_AT.ReloadTreeView( ); + + if ( m_appLoading ) return; // don't assign while loading defaults + m_AppSettings.ShowJoystick = cbxShowJoystick.Checked; m_AppSettings.ShowGamepad = cbxShowGamepad.Checked; + m_AppSettings.ShowKeyboard = cbxShowKeyboard.Checked; m_AppSettings.ShowMapped = cbxShowMappedOnly.Checked; } @@ -639,20 +643,33 @@ namespace SCJMapper_V2 private void btAssign_Click( object sender, EventArgs e ) { - m_AT.UpdateSelectedItem( JoystickCls.MakeThrottle( lblLastJ.Text, cbxThrottle.Checked ), cbxInvert.Checked, InputMode ); - if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + if ( m_AT.UpdateSelectedItem( JoystickCls.MakeThrottle( lblLastJ.Text, cbxThrottle.Checked ), InputMode ) ) { + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + } + else MySounds.PlayNotfound( ); } - - // General Area Items + private void btBlend_Click( object sender, EventArgs e ) + { + if ( m_AT.CanBlendBinding ) { + m_AT.UpdateSelectedItem( DeviceCls.BlendedInput, InputMode ); + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + } + else MySounds.PlayCannot( ); + } private void btClear_Click( object sender, EventArgs e ) { - - m_AT.UpdateSelectedItem( "", false, InputMode ); - if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + if ( m_AT.CanClearBinding ) { + m_AT.UpdateSelectedItem( "", InputMode ); + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + } + else MySounds.PlayCannot( ); } + + // General Area Items + private void btDump_Click( object sender, EventArgs e ) { Dump( ); @@ -766,6 +783,7 @@ namespace SCJMapper_V2 // Context Menu Items + // RTB Menu private void tsiCopy_Click( object sender, EventArgs e ) { rtb.Focus( ); @@ -808,6 +826,28 @@ namespace SCJMapper_V2 } } + // Node Menu + private void cmAddDel_Opening( object sender, CancelEventArgs e ) + { + ContextMenuStrip cts = ( sender as ContextMenuStrip ); + Boolean any=false; + cts.Items[0].Visible = m_AT.CanAddBinding; any = any || m_AT.CanAddBinding; + cts.Items[1].Visible = m_AT.CanDelBinding; any = any || m_AT.CanDelBinding; + e.Cancel = !any; + } + + private void tsiAddBinding_Click( object sender, EventArgs e ) + { + m_AT.AddBinding( ); + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + } + + private void tdiDelBinding_Click( object sender, EventArgs e ) + { + m_AT.DelBinding( ); + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + } + // rtb drop xml file @@ -961,14 +1001,6 @@ namespace SCJMapper_V2 } - // Blend - - private void btBlend_Click( object sender, EventArgs e ) - { - m_AT.UpdateSelectedItem( DeviceCls.BlendedInput, false, InputMode ); - if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; - } - // Joystick Tuning private void btJSTuning_Click( object sender, EventArgs e ) @@ -983,22 +1015,15 @@ namespace SCJMapper_V2 DeviceCls dev = null; String find = ""; - find = ActionTreeNode.ComposeNodeText( "v_yaw", ActionTreeNode.REG_MOD, "js" ); + // find action item for yaw + find = ActionTreeNode.ComposeNodeText( "v_yaw", "js" ); nodeText = m_AT.FindText( "spaceship_movement", find ); // returns "" or a complete text ("action - command") - if ( String.IsNullOrWhiteSpace( nodeText ) ) { - find = ActionTreeNode.ComposeNodeText( "v_yaw", ActionTreeNode.INV_MOD, "js" ); - nodeText = m_AT.FindText( "spaceship_movement", find ); // find inverted ones too - } if ( !String.IsNullOrWhiteSpace( nodeText ) ) { dev = m_Joystick.Find_jsN( JoystickCls.JSNum( ActionTreeNode.CommandFromNodeText( nodeText ) ) ); } else { - find = ActionTreeNode.ComposeNodeText( "v_yaw", ActionTreeNode.REG_MOD, "xi" ); + find = ActionTreeNode.ComposeNodeText( "v_yaw", "xi" ); nodeText = m_AT.FindText( "spaceship_movement", find ); - if ( String.IsNullOrWhiteSpace( nodeText ) ) { - find = ActionTreeNode.ComposeNodeText( "v_yaw", ActionTreeNode.INV_MOD, "xi" ); - nodeText = m_AT.FindText( "spaceship_movement", find ); // find inverted ones too - } if ( !String.IsNullOrWhiteSpace( nodeText ) ) { dev = m_Gamepad; } @@ -1008,21 +1033,21 @@ namespace SCJMapper_V2 // JS commands that are supported if ( nodeText.ToLowerInvariant( ).EndsWith( "_x" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotx" ) ) { m_AT.ActionMaps.TuningY.GameDevice = dev; - m_AT.ActionMaps.TuningY.ActionCommand = nodeText; + m_AT.ActionMaps.TuningY.Action = nodeText; m_AT.ActionMaps.DeadzoneX.GameDevice = dev; m_AT.ActionMaps.TuningY.Deadzone = m_AT.ActionMaps.DeadzoneX; JSCAL.YawTuning = m_AT.ActionMaps.TuningY; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_y" ) || nodeText.ToLowerInvariant( ).EndsWith( "_roty" ) ) { m_AT.ActionMaps.TuningY.GameDevice = dev; - m_AT.ActionMaps.TuningY.ActionCommand = nodeText; + m_AT.ActionMaps.TuningY.Action = nodeText; m_AT.ActionMaps.DeadzoneY.GameDevice = dev; m_AT.ActionMaps.TuningY.Deadzone = m_AT.ActionMaps.DeadzoneY; JSCAL.YawTuning = m_AT.ActionMaps.TuningY; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_z" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotz" ) ) { m_AT.ActionMaps.TuningY.GameDevice = dev; - m_AT.ActionMaps.TuningY.ActionCommand = nodeText; + m_AT.ActionMaps.TuningY.Action = nodeText; m_AT.ActionMaps.DeadzoneZ.GameDevice = dev; m_AT.ActionMaps.TuningY.Deadzone = m_AT.ActionMaps.DeadzoneZ; JSCAL.YawTuning = m_AT.ActionMaps.TuningY; @@ -1030,7 +1055,7 @@ namespace SCJMapper_V2 // GP commands that are supported - X else if ( nodeText.ToLowerInvariant( ).Contains( "_thumblx" ) || nodeText.ToLowerInvariant( ).Contains( "_thumbrx" ) ) { m_AT.ActionMaps.TuningY.GameDevice = dev; - m_AT.ActionMaps.TuningY.ActionCommand = nodeText; + m_AT.ActionMaps.TuningY.Action = nodeText; m_AT.ActionMaps.DeadzoneX.GameDevice = dev; m_AT.ActionMaps.TuningY.Deadzone = m_AT.ActionMaps.DeadzoneX; JSCAL.YawTuning = m_AT.ActionMaps.TuningY; @@ -1039,22 +1064,14 @@ namespace SCJMapper_V2 // attach Pitch command dev = null; - find = ActionTreeNode.ComposeNodeText( "v_pitch", ActionTreeNode.REG_MOD, "js" ); + find = ActionTreeNode.ComposeNodeText( "v_pitch", "js" ); nodeText = m_AT.FindText( "spaceship_movement", find ); // returns "" or a complete text ("action - command") - if ( String.IsNullOrWhiteSpace( nodeText ) ) { - find = ActionTreeNode.ComposeNodeText( "v_pitch", ActionTreeNode.INV_MOD, "js" ); - nodeText = m_AT.FindText( "spaceship_movement", find ); // find inverted ones too - } if ( !String.IsNullOrWhiteSpace( nodeText ) ) { dev = m_Joystick.Find_jsN( JoystickCls.JSNum( ActionTreeNode.CommandFromNodeText( nodeText ) ) ); } else { - find = ActionTreeNode.ComposeNodeText( "v_pitch", ActionTreeNode.REG_MOD, "xi" ); + find = ActionTreeNode.ComposeNodeText( "v_pitch", "xi" ); nodeText = m_AT.FindText( "spaceship_movement", find ); - if ( String.IsNullOrWhiteSpace( nodeText ) ) { - find = ActionTreeNode.ComposeNodeText( "v_pitch", ActionTreeNode.INV_MOD, "xi" ); - nodeText = m_AT.FindText( "spaceship_movement", find ); // find inverted ones too - } if ( !String.IsNullOrWhiteSpace( nodeText ) ) { dev = m_Gamepad; } @@ -1064,21 +1081,21 @@ namespace SCJMapper_V2 // JS commands that are supported if ( nodeText.ToLowerInvariant( ).EndsWith( "_x" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotx" ) ) { m_AT.ActionMaps.TuningP.GameDevice = dev; - m_AT.ActionMaps.TuningP.ActionCommand = nodeText; + m_AT.ActionMaps.TuningP.Action = nodeText; m_AT.ActionMaps.DeadzoneX.GameDevice = dev; m_AT.ActionMaps.TuningP.Deadzone = m_AT.ActionMaps.DeadzoneX; JSCAL.PitchTuning = m_AT.ActionMaps.TuningP; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_y" ) || nodeText.ToLowerInvariant( ).EndsWith( "_roty" ) ) { m_AT.ActionMaps.TuningP.GameDevice = dev; - m_AT.ActionMaps.TuningP.ActionCommand = nodeText; + m_AT.ActionMaps.TuningP.Action = nodeText; m_AT.ActionMaps.DeadzoneY.GameDevice = dev; m_AT.ActionMaps.TuningP.Deadzone = m_AT.ActionMaps.DeadzoneY; JSCAL.PitchTuning = m_AT.ActionMaps.TuningP; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_z" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotz" ) ) { m_AT.ActionMaps.TuningP.GameDevice = dev; - m_AT.ActionMaps.TuningP.ActionCommand = nodeText; + m_AT.ActionMaps.TuningP.Action = nodeText; m_AT.ActionMaps.DeadzoneZ.GameDevice = dev; m_AT.ActionMaps.TuningP.Deadzone = m_AT.ActionMaps.DeadzoneZ; JSCAL.PitchTuning = m_AT.ActionMaps.TuningP; @@ -1086,7 +1103,7 @@ namespace SCJMapper_V2 // GP commands that are supported - either Y else if ( nodeText.ToLowerInvariant( ).Contains( "_thumbly" ) || nodeText.ToLowerInvariant( ).Contains( "_thumbry" ) ) { m_AT.ActionMaps.TuningP.GameDevice = dev; - m_AT.ActionMaps.TuningP.ActionCommand = nodeText; + m_AT.ActionMaps.TuningP.Action = nodeText; m_AT.ActionMaps.DeadzoneY.GameDevice = dev; m_AT.ActionMaps.TuningP.Deadzone = m_AT.ActionMaps.DeadzoneY; JSCAL.PitchTuning = m_AT.ActionMaps.TuningP; @@ -1095,12 +1112,8 @@ namespace SCJMapper_V2 // attach Roll command - cannot use gamepad here dev = null; - find = ActionTreeNode.ComposeNodeText( "v_roll", ActionTreeNode.REG_MOD, "js" ); + find = ActionTreeNode.ComposeNodeText( "v_roll", "js" ); nodeText = m_AT.FindText( "spaceship_movement", find ); // returns "" or a complete text ("action - command") - if ( String.IsNullOrWhiteSpace( nodeText ) ) { - find = ActionTreeNode.ComposeNodeText( "v_roll", ActionTreeNode.INV_MOD, "js" ); - nodeText = m_AT.FindText( "spaceship_movement", find ); // find inverted ones too - } if ( !String.IsNullOrWhiteSpace( nodeText ) ) { dev = m_Joystick.Find_jsN( JoystickCls.JSNum( ActionTreeNode.CommandFromNodeText( nodeText ) ) ); } @@ -1109,21 +1122,21 @@ namespace SCJMapper_V2 // JS commands that are supported if ( nodeText.ToLowerInvariant( ).EndsWith( "_x" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotx" ) ) { m_AT.ActionMaps.TuningR.GameDevice = dev; - m_AT.ActionMaps.TuningR.ActionCommand = nodeText; + m_AT.ActionMaps.TuningR.Action = nodeText; m_AT.ActionMaps.DeadzoneX.GameDevice = dev; m_AT.ActionMaps.TuningR.Deadzone = m_AT.ActionMaps.DeadzoneX; JSCAL.RollTuning = m_AT.ActionMaps.TuningR; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_y" ) || nodeText.ToLowerInvariant( ).EndsWith( "_roty" ) ) { m_AT.ActionMaps.TuningR.GameDevice = dev; - m_AT.ActionMaps.TuningR.ActionCommand = nodeText; + m_AT.ActionMaps.TuningR.Action = nodeText; m_AT.ActionMaps.DeadzoneY.GameDevice = dev; m_AT.ActionMaps.TuningR.Deadzone = m_AT.ActionMaps.DeadzoneY; JSCAL.RollTuning = m_AT.ActionMaps.TuningR; } else if ( nodeText.ToLowerInvariant( ).EndsWith( "_z" ) || nodeText.ToLowerInvariant( ).EndsWith( "_rotz" ) ) { m_AT.ActionMaps.TuningR.GameDevice = dev; - m_AT.ActionMaps.TuningR.ActionCommand = nodeText; + m_AT.ActionMaps.TuningR.Action = nodeText; m_AT.ActionMaps.DeadzoneZ.GameDevice = dev; m_AT.ActionMaps.TuningR.Deadzone = m_AT.ActionMaps.DeadzoneZ; JSCAL.RollTuning = m_AT.ActionMaps.TuningR; @@ -1218,5 +1231,7 @@ namespace SCJMapper_V2 + + } } diff --git a/Form1.resx b/Form1.resx index 449401b..c1e6799 100644 --- a/Form1.resx +++ b/Form1.resx @@ -384,6 +384,9 @@ x1//2Q== + + 652, 17 + 494, 17 @@ -391,9 +394,9 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAg - DgAAAk1TRnQBSQFMAgEBBwEAATgBCwE4AQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo - AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABK + DwAAAk1TRnQBSQFMAgEBCAEAAZABCwGQAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm @@ -420,39 +423,44 @@ AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw - AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/yYAAXQFRgHyFQAB/wH0 - CwABBxUAAUYHJQHyFAACQwEVCQABQwEVAUMCAAHwCwAB8AQAAUYJJQHyEwABQwIVCAAB8gFDARUBQwEA - AgcB7QgAAf8BkgG8Ae8CAAFGAiUB/wFMAyUCGgIlARsRAAEHAUMBFQETAUMB9AUAAQcBFQEUARUBQwEA - AfcBvAHtCQAB9wHwAZIBAAF0AiUB9gL/AUwBJQH2Av8DJREAAfQBQwEVAeoB+QIPAx8BQwEUAR8BFAEV - AUMB/wHtAfAB7AHqAW0B7wMAAe8BDgHsAe8B8AHsAQABRgIlAUYD/wH2A/8DJRIAAUMBbQHqAUQCEAMg - AQ4BbQEUAhABEQEAAewBvAH3AeoB6wESAewBBwHsARIB6wFtAgcB6wEAAUYDKwFMBf8EKxIAAUMBFQES - ASABDgEPAR8CIAIVAREBFAEQAUMBAAFtAuwB7QEUAW0BkgHsAZIBbQHqAe0B7AHtAQ4BAAFGBEwB9gP/ - AXQETBIAAUMB7AEUAQ8CHwEAAQ4BDwEBAR4BRAFDARABEQIAAfcB7wHrAu8B7QGSAe0B7wH3AZEC7wIA - AUYDTAH2Bf8BdANMEgABvAEUAQ4BEAFDAUUBHgEBAUMBHgFvAQ4CEAMAAuwBvAHsAQcBvAFtArwBjQG8 - ARUBvAIAAUYCTAEaA/8BTAP/A0wTAAFDARABbQEVAQEBEQEVAQ4BHgELAR8CDgMAAfIB8wHsAfIF9AHy - ARIB8gHzAgAB8wFTAUwBmgL/A0wC/wJMAU0TAAEVAhEBHgEABw4FAAG8AvAFAALwAbwBEQMAAfMBUwpN - FQAB7AEQAQ8BFQMAAUMCDwH0BQABEQcAAf8BAAETBQAB8wlTNwAB8wdTlAAg/wcAAUMBAAHyFgAB/w7x - AfAG/wH0AygG/wUAAQ4BkQGuApEB6gH/BwAL/wIAAf8B8QNrAYsBkQGLBIoBSQFKAZEB8Qb/ASgDKQEo - Bf8EAAFDAZoBegFSAZEBtQESAfEGAAH3AQcBvAIHAu8DBwHwAfIBBwEAAf8B8QIGAYsBkAG7BYsCUAFr - AfEG/wFQBCkBKAT/AwABDwEHAZECcwGRAbUBtAFDAfQEAAH/AbwB7wO8AwcBvAEHAfAB8gHxAQAB/wHx - AgYBiwGQAbsEkAFsAVABUQFrAfEH/wVQAXMD/wEAARQBUgHzArwBBwH3AZECtAEOAfQEAAH/AbwB7wPw - ArwC8AG8AfEB8gHwAQAB/wHxAosBkAGzAbsBKQGzAXEDUAGQAWsB8QL/AXMFKAVQAXMC/wIAARoB9AH3 - ARIBQwERAbsBkQF6AewB/wLxAfMBAAH/Ae8B9wG8BvABvALxAbwBAAH/AfIDkAGzAbsCswNRASkBswFr - AfIB/w1QAZkB/wIAAQ4B7wETAeoBFQEPAZEBDwEOBfEBAAH/Ae0BvAnyAfABBwEAAf8B8gSzAboBiwEp - BHgBUQFrAfIB/w5QAf8EAAFtAREBQwEQARUB8QL/AfQC/wIAAf8B9wHxCPIB8QHwAbwBAAH/AfIEswG6 - AbsBKAJ4AVABeAEoAWsB8gH/ASkMUAEoAf8EAAG7AbQBkQFtCQAB/wGSAfEB8gbzAfIC8QHwAQAB/wHz - BLMBuQG6AdwBtAFJAlABSQFrAfMC/wFQBXgBVwRRASkC/wMAAfMBAAGRARMLAAGSAfEB8gLzAQcBkgLz - AfIB8QHyAfMBAAH/AfMGuQG6AdsD3AHbAWsB8wf/ASgEVwFQA/8DAAHwAQ4B7AEVCwAB7QHxAfIC8wHt - Ae8C8wHyAfEB8gH/AQAB/wHzDNoBiwHzBv8BmQR4AVcE/wEAAfEBAAEHAe0B7AGuAfIKAAEHAvIC8wG8 - A/MB8gHxAfICAAH/D/MG/wEpBHgF/wEAAW4BeQG8AfcBEwHwDAAC8gbzAfIB8QH0AgAB/wjzAfIB9wHy - AfcB8gH3AfMG/wEcA3gG/wHtAesBvALvDgAC8QbyAvEDAAH/AfMN/wHvB/8BmQFQCP8BEwHwAeocACD/ - AgAB8wH3Af8bAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/AQAE/wH4AQ8CAAGf - Af0C/wHwAQcCAAGPAfgB3wH9AeABAwIAAY8B8AGPAfABwAEBAgABAwHgAQcB8AGAAQEFAAKAAQECAAGA - AQABgAEAAYABAQIAAYABAAGAAQABgAEBAgABgAEAAYABAAGAAQECAAGAAQEBgAEAAYABAQIAAcABAQHA - AQEBgAEBAgABwAEBAcMB4QHAAQMCAAHgAQMB5wHjAeABBwIABP8B8AEPAgAG/wIABv8GAAH8AT8C/wQA - AfgBDwHgAQMEAAHwAQ8BwAEBBAABwAEHAYABAQQAAYABBwGAAQEEAAGAAQABgAEBBAABwAEAAYABAQQA - AeABAQGAAQEEAAHgAf8BgAEBBAAB4AH/AcABAQQAAeEB/wHAAQEEAAGAAf8BwAEDBAABgQH/AeABAwQA - AQMB/wHgAQcEAAEHA/8EAAHHA/8L + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AKgABdAVG + AfIHAARIAQ8IEgEAAf8B9AsAAQcVAAFGByUB8gYAAUgCTwFIAW0D+AP0Ae4BEgEAAkMBFQkAAUMBFQFD + AgAB8AsAAfAEAAFGCSUB8gIAA5EBSAFWAU8BSANJAfgD/wG8ARIBAAFDAhUIAAHyAUMBFQFDAQACBwHt + CAAB/wGSAbwB7wIAAUYCJQH/AUwDJQIaAiUBGwEAAUgDTwJWAk8BTgFIAe0D/wHwARIBBwFDARUBEwFD + AfQFAAEHARUBFAEVAUMBAAH3AbwB7QkAAfcB8AGSAQABdAIlAfYC/wFMASUB9gL/AyUBAAFIA1cDVgJP + AUgB9wP/AfABEgH0AUMBFQHqAfkCDwMfAUMBFAEfARQBFQFDAf8B7QHwAewB6gFtAe8DAAHvAQ4B7AHv + AfAB7AEAAUYCJQFGA/8B9gP/AyUBAAFIBFcBVgJXAVYBSAHvA/8B8AESAQABQwFtAeoBRAIQAyABDgFt + ARQCEAERAQAB7AG8AfcB6gHrARIB7AEHAewBEgHrAW0CBwHrAQABRgMrAUwF/wQrAQADkQFIAlcBSANx + Ae4D/wHxARIBAAFDARUBEgEgAQ4BDwEfAiACFQERARQBEAFDAQABbQLsAe0BFAFtAZIB7AGSAW0B6gHt + AewB7QEOAQABRgRMAfYD/wF0BEwEAAFIAlcBSAHxA/ID/wHxARIBAAFDAewBFAEPAh8BAAEOAQ8BAQEe + AUQBQwEQARECAAH3Ae8B6wLvAe0BkgHtAe8B9wGRAu8CAAFGA0wB9gX/AXQDTAQAAUgCTwFIAfQG/wHy + ARIBAAG8ARQBDgEQAUMBRQEeAQEBQwEeAW8BDgIQAwAC7AG8AewBBwG8AW0CvAGNAbwBFQG8AgABRgJM + ARoD/wFMA/8DTAQAARQBuwIIB/8B8wESAgABQwEQAW0BFQEBAREBFQEOAR4BCwEfAg4DAAHyAfMB7AHy + BfQB8gESAfIB8wIAAfMBUwFMAZoC/wNMAv8CTAFNBAABEgH0Bv8B9AHxAe4B7wESAgABFQIRAR4BAAcO + BQABvALwBQAC8AG8AREDAAHzAVMKTQUAARIB9AX/AfQBBwPyARIDAAHsARABDwEVAwABQwIPAfQFAAER + BwAB/wEAARMFAAHzCVMGAAESAfQF/wHxAe4C/wESAfEkAAHzB1MHAAESAfUF/wLuAf8BEgHxNAABEgb1 + Ae8B7gESAfE1AAkSAfEDACD/BwABQwEAAfIWAAH/DvEB8Ab/AfQDKAb/BQABDgGRAa4CkQHqAf8HAAv/ + AgAB/wHxA2sBiwGRAYsEigFJAUoBkQHxBv8BKAMpASgF/wQAAUMBmgF6AVIBkQG1ARIB8QYAAfcBBwG8 + AgcC7wMHAfAB8gEHAQAB/wHxAgYBiwGQAbsFiwJQAWsB8Qb/AVAEKQEoBP8DAAEPAQcBkQJzAZEBtQG0 + AUMB9AQAAf8BvAHvA7wDBwG8AQcB8AHyAfEBAAH/AfECBgGLAZABuwSQAWwBUAFRAWsB8Qf/BVABcwP/ + AQABFAFSAfMCvAEHAfcBkQK0AQ4B9AQAAf8BvAHvA/ACvALwAbwB8QHyAfABAAH/AfECiwGQAbMBuwEp + AbMBcQNQAZABawHxAv8BcwUoBVABcwL/AgABGgH0AfcBEgFDAREBuwGRAXoB7AH/AvEB8wEAAf8B7wH3 + AbwG8AG8AvEBvAEAAf8B8gOQAbMBuwKzA1EBKQGzAWsB8gH/DVABmQH/AgABDgHvARMB6gEVAQ8BkQEP + AQ4F8QEAAf8B7QG8CfIB8AEHAQAB/wHyBLMBugGLASkEeAFRAWsB8gH/DlAB/wQAAW0BEQFDARABFQHx + Av8B9AL/AgAB/wH3AfEI8gHxAfABvAEAAf8B8gSzAboBuwEoAngBUAF4ASgBawHyAf8BKQxQASgB/wQA + AbsBtAGRAW0JAAH/AZIB8QHyBvMB8gLxAfABAAH/AfMEswG5AboB3AG0AUkCUAFJAWsB8wL/AVAFeAFX + BFEBKQL/AwAB8wEAAZEBEwsAAZIB8QHyAvMBBwGSAvMB8gHxAfIB8wEAAf8B8wa5AboB2wPcAdsBawHz + B/8BKARXAVAD/wMAAfABDgHsARULAAHtAfEB8gLzAe0B7wLzAfIB8QHyAf8BAAH/AfMM2gGLAfMG/wGZ + BHgBVwT/AQAB8QEAAQcB7QHsAa4B8goAAQcC8gLzAbwD8wHyAfEB8gIAAf8P8wb/ASkEeAX/AQABbgF5 + AbwB9wETAfAMAALyBvMB8gHxAfQCAAH/CPMB8gH3AfIB9wHyAfcB8wb/ARwDeAb/Ae0B6wG8Au8OAALx + BvIC8QMAAf8B8w3/Ae8H/wGZAVAI/wETAfAB6hwAIP8CAAHzAfcB/xsAAUIBTQE+BwABPgMAASgDAAFA + AwABMAMAAQEBAAEBBQABgAEBFgAD/4EABP8B+AEPAeABAAGfAf0C/wHwAQcB4AEAAY8B+AHfAf0B4AED + AgABjwHwAY8B8AHAAQECAAEDAeABBwHwAYABAQUAAoABAQIAAYABAAGAAQABgAEBAgABgAEAAYABAAGA + AQEB4AEAAYABAAGAAQABgAEBAeABAAGAAQEBgAEAAYABAQHgAQABwAEBAcABAQGAAQEB4AEAAcABAQHD + AeEBwAEDAeABAAHgAQMB5wHjAeABBwHgAQAE/wHwAQ8B4AEBBv8B4AEDBv8B4AEHBAAB/AE/Av8EAAH4 + AQ8B4AEDBAAB8AEPAcABAQQAAcABBwGAAQEEAAGAAQcBgAEBBAABgAEAAYABAQQAAcABAAGAAQEEAAHg + AQEBgAEBBAAB4AH/AYABAQQAAeAB/wHAAQEEAAHhAf8BwAEBBAABgAH/AcABAwQAAYEB/wHgAQMEAAED + Af8B4AEHBAABBwP/BAABxwP/Cw== diff --git a/Joystick/DeviceDeadzoneParameter.cs b/Joystick/DeviceDeadzoneParameter.cs index 471ba64..049f4e2 100644 --- a/Joystick/DeviceDeadzoneParameter.cs +++ b/Joystick/DeviceDeadzoneParameter.cs @@ -10,13 +10,10 @@ namespace SCJMapper_V2 private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType ); - private String m_actionCommand = ""; // v_pitch - js1_x .. private String m_cmdCtrl = ""; // x, y, rotz ... private String m_type = ""; // joystick OR xboxpad private int m_devInstanceNo = -1; // jsN - instance in XML - String m_option = ""; // the option name (level where it applies) - private String m_deviceName = ""; private bool m_deadzoneEnabled = false; // default @@ -33,18 +30,20 @@ namespace SCJMapper_V2 public DeviceCls GameDevice { get { return m_device; } - set { m_device = value; + set + { + m_device = value; m_type = ""; m_devInstanceNo = -1; if ( JoystickCls.IsDeviceClass( m_device.DevClass ) ) { m_type = m_device.DevClass; - m_devInstanceNo = (m_device as JoystickCls).JSAssignment; + m_devInstanceNo = ( m_device as JoystickCls ).JSAssignment; } else if ( GamepadCls.IsDeviceClass( m_device.DevClass ) ) { m_type = m_device.DevClass; m_devInstanceNo = 1; // supports ONE gamepad } - } + } } @@ -104,6 +103,6 @@ namespace SCJMapper_V2 } - + } } diff --git a/Joystick/DeviceTuningParameter.cs b/Joystick/DeviceTuningParameter.cs index 86799f0..015ca97 100644 --- a/Joystick/DeviceTuningParameter.cs +++ b/Joystick/DeviceTuningParameter.cs @@ -13,10 +13,10 @@ namespace SCJMapper_V2 { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType ); - private String m_actionCommand = ""; // v_pitch - js1_x .. - private String m_cmdCtrl = ""; // x, y, rotz ... - private String m_type = ""; // joystick OR xboxpad - private int m_devInstanceNo = -1; // jsN - instance in XML + private String m_action = ""; // v_pitch + private String m_cmdCtrl = ""; // js1_x, js1_y, js1_rotz ... + private String m_type = ""; // joystick OR xboxpad + private int m_devInstanceNo = -1; // jsN - instance in XML String m_option = ""; // the option name (level where it applies) @@ -38,7 +38,7 @@ namespace SCJMapper_V2 private DeviceDeadzoneParameter m_deadzone = null; - public DeviceTuningParameter( ) + public DeviceTuningParameter( ) { } @@ -47,18 +47,20 @@ namespace SCJMapper_V2 public DeviceCls GameDevice { get { return m_device; } - set { m_device = value; + set + { + m_device = value; m_type = ""; m_devInstanceNo = -1; if ( JoystickCls.IsDeviceClass( m_device.DevClass ) ) { m_type = m_device.DevClass; - m_devInstanceNo = (m_device as JoystickCls).JSAssignment; + m_devInstanceNo = ( m_device as JoystickCls ).JSAssignment; } else if ( GamepadCls.IsDeviceClass( m_device.DevClass ) ) { m_type = m_device.DevClass; m_devInstanceNo = 1; // supports ONE gamepad } - } + } } @@ -73,10 +75,10 @@ namespace SCJMapper_V2 set { m_deviceName = value; } } - public String ActionCommand + public String Action { - get { return m_actionCommand; } - set { m_actionCommand = value; DecomposeCommand( ); } + get { return m_action; } + set { m_action = value; DecomposeCommand( ); } } public String CommandCtrl @@ -150,8 +152,8 @@ namespace SCJMapper_V2 { // populate from input // something like "v_pitch - js1_x" OR "v_pitch - xi_thumbl" OR "v_pitch - ximod+xi_thumbl+xi_mod" - String cmd = ActionTreeNode.CommandFromNodeText( ActionCommand ); - String action = ActionTreeNode.ActionFromNodeText( ActionCommand ); + String cmd = ActionTree.CommandFromNodeText( Action ); + String action = ActionTreeNode.ActionFromNodeText( Action ); m_cmdCtrl = ""; if ( !String.IsNullOrWhiteSpace( cmd ) ) { // decomp gamepad entries - could have modifiers so check for contains... diff --git a/MySounds.cs b/MySounds.cs new file mode 100644 index 0000000..bc287a7 --- /dev/null +++ b/MySounds.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Media; + +namespace SCJMapper_V2 +{ + public class MySounds + { + + /* + SystemSounds.Asterisk, + SystemSounds.Beep, + SystemSounds.Exclamation, + SystemSounds.Hand, + SystemSounds.Question + * + * Asterisk - the sound that is played when a popup alert is displayed, like a warning message. + Default Beep - this sound is played for multiple reasons, depending on what you do. For example, it will play if you try to select a parent window before closing the active one. + Exclamation - the sound that is played when you try to do something that is not supported by Windows. + */ + + public static void PlayNotfound( ) + { + SystemSounds.Beep.Play( ); + } + + public static void PlayCannot( ) + { + SystemSounds.Beep.Play( ); + } + + public static void PlayError( ) + { + SystemSounds.Exclamation.Play( ); + } + + + + + } +} diff --git a/OGL/FormJSCalCurve.cs b/OGL/FormJSCalCurve.cs index c937f9e..ddec1c4 100644 --- a/OGL/FormJSCalCurve.cs +++ b/OGL/FormJSCalCurve.cs @@ -145,7 +145,6 @@ namespace SCJMapper_V2 private float m_liveYsense = 1.0f; private float m_liveYexponent = 1.0f; private xyPoints m_liveYnonLinCurve = new xyPoints( 1000 ); // max val of Joystick Input - private bool m_YcmdInvert = false; // inverted by command (not as Tuning) /// /// Submit the tuning parameters @@ -163,8 +162,7 @@ namespace SCJMapper_V2 m_Ytuning = value; m_Ydev = m_Ytuning.GameDevice; // populate from input - lblYCmd.Text = m_Ytuning.ActionCommand; - m_YcmdInvert = ActionTreeNode.CommandInvertFromNodeText( m_Ytuning.ActionCommand ); + lblYCmd.Text = m_Ytuning.Action; m_liveYawCommand = m_Ytuning.CommandCtrl; log.Info( "FormJSCalCurve : Yaw Command is: " + value ); @@ -223,7 +221,6 @@ namespace SCJMapper_V2 private float m_livePsense = 1.0f; private float m_livePexponent = 1.0f; private xyPoints m_livePnonLinCurve = new xyPoints( 1000 ); // max val of Joystick Input - private bool m_PcmdInvert = false; // inverted by command (not as Tuning) /// /// Submit the tuning parameters @@ -242,9 +239,7 @@ namespace SCJMapper_V2 m_Ptuning = value; m_Pdev = m_Ptuning.GameDevice; // populate from input - lblPCmd.Text = m_Ptuning.ActionCommand; // - m_PcmdInvert = ActionTreeNode.CommandInvertFromNodeText( m_Ptuning.ActionCommand ); - if ( GamepadCls.IsDeviceClass( m_Pdev.DevClass ) ) m_PcmdInvert = !m_PcmdInvert; // Gamepad Pitch Movement is inverted by default in AC + lblPCmd.Text = m_Ptuning.Action; // m_livePitchCommand = m_Ptuning.CommandCtrl; log.Info( "FormJSCalCurve : Pitch Command is: " + value ); @@ -303,7 +298,6 @@ namespace SCJMapper_V2 private float m_liveRsense = 1.0f; private float m_liveRexponent = 1.0f; private xyPoints m_liveRnonLinCurve = new xyPoints( 1000 ); // max val of Joystick Input - private bool m_RcmdInvert = false; // inverted by command (not as Tuning) /// /// Submit the tuning parameters @@ -322,8 +316,7 @@ namespace SCJMapper_V2 m_Rtuning = value; m_Rdev = m_Rtuning.GameDevice; // populate from input - lblRCmd.Text = m_Rtuning.ActionCommand; // - m_RcmdInvert = ActionTreeNode.CommandInvertFromNodeText( m_Rtuning.ActionCommand ); + lblRCmd.Text = m_Rtuning.Action; // m_liveRollCommand = m_Rtuning.CommandCtrl; log.Info( "FormJSCalCurve : Roll Command is: " + value ); @@ -725,7 +718,7 @@ namespace SCJMapper_V2 // update in/out labels if active axis lblYInput.Text = ( i_x / 1000.0 ).ToString( "0.00" ); lblYOutput.Text = ( fout ).ToString( "0.00" ); // calculate new direction vector - m.X = ( ( m_YcmdInvert ) ? -1 : 1 ) * ( ( m_Ytuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbYuse.Checked ) ? fout : 0 ) * m_msElapsed * DegPerMS; + m.X = ( ( m_Ytuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbYuse.Checked ) ? fout : 0 ) * m_msElapsed * DegPerMS; } // Pitch @@ -746,7 +739,7 @@ namespace SCJMapper_V2 } fout = ( fout > 1.0 ) ? 1.0 : fout; lblPInput.Text = ( i_y / 1000.0 ).ToString( "0.00" ); lblPOutput.Text = ( fout ).ToString( "0.00" ); - m.Y = ( ( m_PcmdInvert ) ? -1 : 1 ) * ( ( m_Ptuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbPuse.Checked ) ? -fout : 0 ) * m_msElapsed * DegPerMS; + m.Y = ( ( m_Ptuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbPuse.Checked ) ? -fout : 0 ) * m_msElapsed * DegPerMS; } // Roll @@ -767,7 +760,7 @@ namespace SCJMapper_V2 } fout = ( fout > 1.0 ) ? 1.0 : fout; lblRInput.Text = ( i_z / 1000.0 ).ToString( "0.00" ); lblROutput.Text = ( fout ).ToString( "0.00" ); - m.Z = ( ( m_RcmdInvert ) ? -1 : 1 ) * ( ( m_Rtuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbRuse.Checked ) ? fout : 0 ) * m_msElapsed * DegPerMS; + m.Z = ( ( m_Rtuning.InvertUsed ) ? -1 : 1 ) * ( ( !cbRuse.Checked ) ? fout : 0 ) * m_msElapsed * DegPerMS; } // finalize diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 772d714..a0438ad 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion( "2.8.0.37" )] -[assembly: AssemblyFileVersion( "2.8.0.37" )] +[assembly: AssemblyVersion( "2.10.0.40" )] +[assembly: AssemblyFileVersion( "2.10.0.40" )] diff --git a/SCJMapper-V2.csproj b/SCJMapper-V2.csproj index 734bb74..4f2fd49 100644 --- a/SCJMapper-V2.csproj +++ b/SCJMapper-V2.csproj @@ -26,8 +26,8 @@ false false true - 37 - 2.8.0.%2a + 40 + 2.10.0.%2a false true @@ -116,6 +116,8 @@ + + @@ -124,6 +126,7 @@ + diff --git a/actions/ActionCls.cs b/actions/ActionCls.cs index 27204cb..8853d84 100644 --- a/actions/ActionCls.cs +++ b/actions/ActionCls.cs @@ -21,7 +21,7 @@ namespace SCJMapper_V2 /// /// /// - class ActionCls + public class ActionCls { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType ); @@ -34,6 +34,8 @@ namespace SCJMapper_V2 AD_Keyboard, } + #region Static Items + static public ActionDevice ADevice( String device ) { switch ( device.ToLower( ) ) { @@ -79,28 +81,29 @@ namespace SCJMapper_V2 } } + #endregion + // Class items public String key { get; set; } // the key is the "Daction" formatted item (as we can have the same name multiple times) - public String name { get; set; } - public String device { get; set; } - public String input { get; set; } - public String defBinding { get; set; } // the default binding - public Boolean inverted { get; set; } - public ActionDevice actionDevice { get; set; } + public String name { get; set; } // the plain action name e.g. v_yaw + public ActionDevice actionDevice { get; set; } // the enum of the device + public String device { get; set; } // name of the device (uses DeviceClass) + public String defBinding { get; set; } // the default binding + public List inputList { get; set; } + /// /// ctor /// public ActionCls( ) { - device = JoystickCls.DeviceClass; key = ""; + actionDevice = ActionDevice.AD_Unknown; + device = JoystickCls.DeviceClass; name = ""; - input = ""; defBinding = ""; - inverted = false; - actionDevice = ActionDevice.AD_Unknown; + inputList = new List( ); // empty list } @@ -114,24 +117,39 @@ namespace SCJMapper_V2 ActionCls newAc = new ActionCls( ); // full copy from 'this' newAc.key = this.key; - newAc.name = this.name; + newAc.actionDevice = this.actionDevice; newAc.device = this.device; + newAc.name = this.name; newAc.defBinding = this.defBinding; - newAc.input = this.input; - newAc.inverted = this.inverted; - - // reassign the jsX part for Joystick commands - if ( JoystickCls.IsDeviceClass( this.device ) && JoystickCls.IsDeviceClass( newAc.device ) ) { - int oldJsN = JoystickCls.JSNum( this.input ); - if ( JoystickCls.IsJSValid( oldJsN ) ) { - if ( newJsList.ContainsKey( oldJsN ) ) newAc.input = JoystickCls.ReassignJSTag( this.input, newJsList[oldJsN] ); - } + + foreach ( ActionCommandCls acc in inputList ) { + newAc.inputList.Add( acc.ReassignJsN( newJsList ) ); } return newAc; } + public ActionCommandCls AddCommand( String input, int index ) + { + ActionCommandCls acc = new ActionCommandCls( ); + acc.input = input; acc.nodeIndex = index; + inputList.Add( acc ); + return acc; + } + + public void DelCommand( int index ) + { + int removeIt = -1; + + for ( int i = 0; i < inputList.Count; i++ ) { + if ( inputList[i].nodeIndex == index ) removeIt = i; + if ( inputList[i].nodeIndex > index ) inputList[i].nodeIndex -= 1; // reorder trailing ones + } + if ( removeIt >= 0 ) inputList.RemoveAt( removeIt ); + } + + /// /// Merge action is simply copying the new input control @@ -139,8 +157,10 @@ namespace SCJMapper_V2 /// public void Merge( ActionCls newAc ) { - input = newAc.input; - inverted = newAc.inverted; + this.inputList.Clear( ); + foreach ( ActionCommandCls acc in newAc.inputList ) { + this.inputList.Add( acc ); + } } /// @@ -149,12 +169,21 @@ namespace SCJMapper_V2 /// the action as XML fragment public String toXML( ) { - String r = ""; - if ( !String.IsNullOrEmpty( input ) ) { - if ( inverted ) r = String.Format( "\t\n\t\t\t\n\t\t\n", name, device, input ); - else r = String.Format( "\t\n\t\t\t\n\t\t\n", name, device, input ); + String r = ""; String + bindCmd = "rebind"; + if ( inputList.Count > 0 ) { + if ( !String.IsNullOrEmpty( inputList[0].input ) ) { + r = String.Format( "\t\n", name ); + foreach ( ActionCommandCls acc in inputList ) { + if ( !String.IsNullOrEmpty( acc.input ) ) { + r += String.Format( "\t\t\t<{0} device=\"{1}\" {2}", bindCmd, device, acc.toXML( ) ); + bindCmd = "addbind"; + } + } + r += String.Format( "\t\t\n" ); + } } - + return r; } @@ -176,34 +205,43 @@ namespace SCJMapper_V2 if ( reader.Name == "action" ) { if ( reader.HasAttributes ) { name = reader["name"]; - // Move the reader back to the element node. - reader.ReadStartElement( "action" ); + reader.ReadStartElement( "action" ); // Checks that the current content node is an element with the given Name and advances the reader to the next node } else { return false; } } - if ( reader.Name == "rebind" ) { - if ( reader.HasAttributes ) { - device = reader["device"]; - input = reader["input"]; - if ( ( input == JoystickCls.BlendedInput ) || ( input == GamepadCls.BlendedInput ) ) input = ""; // don't carry jsx_reserved or xi_reserved into the action - key = DevID( device ) + name; // unique id of the action - actionDevice = ADevice( device ); // get the enum of the input device - String inv = reader["invert"]; - if ( String.IsNullOrWhiteSpace( inv ) ) { - inverted = false; + do { + if ( reader.Name == "rebind" ) { + if ( reader.HasAttributes ) { + device = reader["device"]; + ActionCommandCls acc = new ActionCommandCls( ); + acc.input = reader["input"]; + if ( ( acc.input == JoystickCls.BlendedInput ) || ( acc.input == GamepadCls.BlendedInput ) ) acc.input = ""; // don't carry jsx_reserved or xi_reserved into the action + key = DevID( device ) + name; // unique id of the action + actionDevice = ADevice( device ); // get the enum of the input device + inputList.Add( acc ); + // advances the reader to the next node + reader.ReadStartElement( "rebind" ); } - else { - inverted = ( inv == "1" ) ? true : false; + } + else if ( reader.Name == "addbind" ) { + if ( reader.HasAttributes ) { + device = reader["device"]; + ActionCommandCls acc = new ActionCommandCls( ); + acc.input = reader["input"]; + if ( ( acc.input == JoystickCls.BlendedInput ) || ( acc.input == GamepadCls.BlendedInput ) ) acc.input = ""; // don't carry jsx_reserved or xi_reserved into the action + key = DevID( device ) + name; // unique id of the action + actionDevice = ADevice( device ); // get the enum of the input device + inputList.Add( acc ); + // advances the reader to the next node + reader.ReadStartElement( "addbind" ); } - // Move the reader back to the element node. - reader.ReadStartElement( "rebind" ); } - } - else { - return false; - } + else { + return false; + } + } while ( reader.Name == "addbind" ); return true; } diff --git a/actions/ActionCommandCls.cs b/actions/ActionCommandCls.cs new file mode 100644 index 0000000..e02b638 --- /dev/null +++ b/actions/ActionCommandCls.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SCJMapper_V2 +{ + public class ActionCommandCls + { + + public String input { get; set; } // input command name e.g. js1_x + + /// + /// The index of the visible child node (-1 -> shown in ActionNode) + /// + public int nodeIndex { get; set; } // index of the vis treenode + + + // ctor + public ActionCommandCls( ) + { + input = "UNDEF"; + nodeIndex = -1; + } + + + /// + /// Copy return the action while reassigning the JsN Tag + /// + /// The JsN reassign list + /// The action copy with reassigned input + public ActionCommandCls ReassignJsN( Dictionary newJsList ) + { + ActionCommandCls newAc = new ActionCommandCls( ); + // full copy from 'this' + newAc.input = this.input; + + // reassign the jsX part for Joystick commands (silly but rather fast comparison) + if ( this.input.Contains( "js1_" ) || this.input.Contains( "js2_" ) || this.input.Contains( "js3_" ) || this.input.Contains( "js4_" ) ) { + int oldJsN = JoystickCls.JSNum( this.input ); + if ( JoystickCls.IsJSValid( oldJsN ) ) { + if ( newJsList.ContainsKey( oldJsN ) ) newAc.input = JoystickCls.ReassignJSTag( this.input, newJsList[oldJsN] ); + } + } + + return newAc; + } + + + /// + /// Dump the action as partial XML nicely formatted + /// + /// the action as XML fragment + public String toXML( ) + { + String r = ""; + if ( !String.IsNullOrEmpty( input ) ) { + r = String.Format( "input=\"{0}\" />\n", input ); + } + else { + r = String.Format( " />\n" ); // actually an ERROR... + } + + return r; + } + + } +} diff --git a/actions/ActionMapsCls.cs b/actions/ActionMapsCls.cs index 9134992..d96291a 100644 --- a/actions/ActionMapsCls.cs +++ b/actions/ActionMapsCls.cs @@ -35,6 +35,8 @@ namespace SCJMapper_V2 #endregion Static Part of ActionMaps + private const String ACM_VERSION = "1"; // the default version + private String version { get; set; } private String ignoreversion { get; set; } @@ -125,7 +127,7 @@ namespace SCJMapper_V2 /// public ActionMapsCls( JoystickList jsList ) { - version = "0"; + version = ACM_VERSION; m_joystickList = jsList; // have to save this for Reassign // create the Joystick assignments @@ -216,7 +218,7 @@ namespace SCJMapper_V2 r += String.Format( "version=\"{0}\" \n", version ); } else { - version = "0"; // preset if missing + version = ACM_VERSION; // preset if missing r += String.Format( "version=\"{0}\" \n", version ); } @@ -270,6 +272,8 @@ namespace SCJMapper_V2 if ( reader.Name == "ActionMaps" ) { if ( reader.HasAttributes ) { version = reader["version"]; + if ( version == "0" ) version = ACM_VERSION; // update from legacy to actual version + ignoreversion = reader["ignoreVersion"]; // could be either / or .. // get the joystick mapping if there is one diff --git a/actions/ActionTree.cs b/actions/ActionTree.cs index 409aab6..63814b0 100644 --- a/actions/ActionTree.cs +++ b/actions/ActionTree.cs @@ -97,6 +97,82 @@ namespace SCJMapper_V2 } + public Boolean CanBlendBinding + { + get + { + if ( Ctrl.SelectedNode == null ) return false; + else return ( Ctrl.SelectedNode.Level == 1 ); + } + } + + public Boolean CanClearBinding + { + get + { + if ( Ctrl.SelectedNode == null ) return false; + else return ( Ctrl.SelectedNode.Level == 1 ); + } + } + + public Boolean CanAddBinding + { + get + { + if ( Ctrl.SelectedNode == null ) return false; + else return ( Ctrl.SelectedNode.Level == 1 ); + } + } + + public Boolean CanDelBinding + { + get { + if ( Ctrl.SelectedNode == null ) return false; + else return ( Ctrl.SelectedNode.Level == 2 ); + } + } + + + /// + /// Add a new Action Child to the selected Node to apply an addtional mapping + /// + public void AddBinding( ) + { + if ( Ctrl.SelectedNode == null ) return; + if ( Ctrl.SelectedNode.Level != 1 ) return; // can only add to level 1 nodes + + ActionTreeNode matn = FindMasterAction( ( ActionTreeNode )Ctrl.SelectedNode ); + ActionCls ac = FindActionObject( matn.Parent.Name, matn.Name ); // the related action + // make new items + ActionTreeInputNode matin = new ActionTreeInputNode( "UNDEF" ); matin.ImageKey = "Add"; + matn.Nodes.Add( matin ); // add to master tree + ActionCommandCls acc = ac.AddCommand( "", matin.Index ); + // show stuff + FilterTree( ); + FindAndSelectCtrlByName( matn.Name ); + } + + + /// + /// Delete the selected ActionChild and remove corresponding ActionCommands + /// + public void DelBinding( ) + { + if ( Ctrl.SelectedNode == null ) return; + if ( Ctrl.SelectedNode.Level != 2 ) return; // can only delete level 2 nodes + + ActionTreeNode matn = FindMasterAction( ( ActionTreeNode )Ctrl.SelectedNode.Parent ); // the parent treenode + ActionCls ac = FindActionObject( matn.Parent.Name, matn.Name ); // the related action + // delete items + ac.DelCommand( m_ctrl.SelectedNode.Index ); + matn.Nodes.RemoveAt( m_ctrl.SelectedNode.Index ); + Dirty = true; + // show stuff + FilterTree( ); + FindAndSelectCtrlByName( matn.Name ); + } + + private void UpdateMasterNode( ActionTreeNode node ) { // copy to master node @@ -105,12 +181,47 @@ namespace SCJMapper_V2 // could return more than one if the action is the same in different actionmaps foreach ( ActionTreeNode mtn in masterNode ) { if ( mtn.Parent.Name == node.Parent.Name ) { - mtn.Command = node.Command; mtn.InvertCommand = node.InvertCommand; mtn.BackColor = node.BackColor; + mtn.Command = node.Command; mtn.BackColor = node.BackColor; + } + } + } + + private void UpdateMasterNode( ActionTreeInputNode node ) + { + // copy to master node + TreeNode[] masterNode = m_MasterTree.Nodes.Find( node.Name, true ); // find the same node in master + if ( masterNode.Length == 0 ) throw new IndexOutOfRangeException( "ActionTree ERROR - cannot find synched node in master" ); // OUT OF SYNC + // could return more than one if the action is the same in different actionmaps + foreach ( ActionTreeInputNode mtn in masterNode ) { + if ( mtn.Parent.Name == node.Parent.Name ) { + mtn.Command = node.Command; mtn.BackColor = node.BackColor; } } } + /// + /// Find the master element for the given ActionNode + /// + /// The ActionNode to find + /// The sought node or null + private ActionTreeNode FindMasterAction( ActionTreeNode atn ) + { + if ( atn.Level != 1 ) return null; // sanity + + TreeNode[] masterNode = m_MasterTree.Nodes.Find( atn.Name, true ); // find the same node in master + if ( masterNode.Length == 0 ) throw new IndexOutOfRangeException( "ActionTree ERROR - cannot find synched node in master" ); // OUT OF SYNC + // could return more than one if the action is the same in different actionmaps + foreach ( ActionTreeNode mtn in masterNode ) { + if ( mtn.Parent.Name == atn.Parent.Name ) { + return mtn; + } + } + return null; + } + + + /// /// Apply the filter to the GUI TreeView /// @@ -136,12 +247,15 @@ namespace SCJMapper_V2 } else { ActionTreeNode tnAction = new ActionTreeNode( stn ); tnMap.Nodes.Add( tnAction ); // copy level 1 nodes + foreach ( ActionTreeInputNode istn in stn.Nodes ) { + ActionTreeInputNode tnActionInput = new ActionTreeInputNode( istn ); tnAction.Nodes.Add( tnActionInput ); // copy level 2 nodes + } allHidden = false; } } // make it tidier.. if ( allHidden ) tnMap.Collapse( ); - else tnMap.Expand( ); + else tnMap.ExpandAll( ); } if ( topNode != null ) Ctrl.TopNode = topNode; // set view to topnode @@ -187,17 +301,18 @@ namespace SCJMapper_V2 /// /// The name of the profile to load (w/o extension) /// True if default mappings should be carried on - public void LoadTree( String defaultProfileName, Boolean applyDefaults ) + public void LoadProfileTree( String defaultProfileName, Boolean applyDefaults ) { - log.Debug( "LoadTree - Entry" ); + log.Debug( "LoadProfileTree - Entry" ); ActionTreeNode tn = null; ActionTreeNode[] cnl = { }; ActionTreeNode cn = null; ActionTreeNode topNode = null; - ActionCls ac = null; ActionMapCls acm = null; + ActionCls ac = null; + ActionCommandCls acc = null; ActionMaps = new ActionMapsCls( m_jsList ); m_MasterTree.Nodes.Clear( ); @@ -212,6 +327,9 @@ namespace SCJMapper_V2 txReader = new StringReader( dpReader.CSVMap ); } + // we assume no addbind items in the profile + // so all actions are shown in the ActionTreeNode and no ActionTreeNode childs must be created here + // however we create the ActionCommand for each entry that is supported - even if it is not mapped (input= "") using ( TextReader sr = txReader ) { String buf = sr.ReadLine( ); while ( !String.IsNullOrEmpty( buf ) ) { @@ -227,59 +345,64 @@ namespace SCJMapper_V2 // default assignments String action = elem[ei].Substring( 1 ); String defBinding = elem[ei + 1].Substring( 0 ); - cn = new ActionTreeNode( "UNDEF" ); cn.Name = elem[ei]; cn.Action = action; cn.BackColor = Color.White; // name with the key it to find it.. String devID = elem[ei].Substring( 0, 1 ); String device = ActionCls.DeviceFromID( devID ); - cn.ImageKey = devID; - cn.BackColor = Color.White; // some stuff does not work properly... + // visual item for the action + cn = new ActionTreeNode( "UNDEF" ); cn.Name = elem[ei]; cn.Action = action; cn.BackColor = Color.White; // name with the key it to find it.. + cn.ImageKey = devID; cn.BackColor = Color.White; // some stuff does not work properly... Array.Resize( ref cnl, cnl.Length + 1 ); cnl[cnl.Length - 1] = cn; + + // derive content tree ac = new ActionCls( ); ac.key = cn.Name; ac.name = action; ac.device = device; ac.actionDevice = ActionCls.ADevice( device ); ac.defBinding = defBinding; - cn.ActionDevice = ac.actionDevice; // should be known now acm.Add( ac ); // add to our map + cn.ActionDevice = ac.actionDevice; // should be known now + // create just an unmapped ActionCommand item + acc = new ActionCommandCls( ); acc.input = ""; acc.nodeIndex = -1; // profile items are shown in the ActionTreeNode (not in a child) + ac.inputList.Add( acc );// add to our Action + // modify defaults and blendings if ( applyDefaults ) { // apply the default mappings - if ( JoystickCls.IsDeviceClass( ac.device ) ) { + if ( ac.actionDevice == ActionCls.ActionDevice.AD_Joystick ) { int jNum = JoystickCls.JSNum( ac.defBinding ); if ( JoystickCls.IsJSValid( jNum ) ) { - ac.input = ac.defBinding; + acc.input = ac.defBinding; cn.Command = ac.defBinding; cn.BackColor = JoystickCls.JsNColor( jNum ); } else if ( BlendUnmappedJS ) { // jsx_reserved gets here - ac.input = JoystickCls.BlendedInput; + acc.input = JoystickCls.BlendedInput; cn.Command = JoystickCls.BlendedInput; cn.BackColor = MyColors.BlendedColor; } } - else if ( GamepadCls.IsDeviceClass( ac.device ) ) { + else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Gamepad ) { if ( GamepadCls.IsXiValid( ac.defBinding ) ) { - ac.input = ac.defBinding; + acc.input = ac.defBinding; cn.Command = ac.defBinding; cn.BackColor = GamepadCls.XiColor( ); } else if ( BlendUnmappedGP ) { // xi_reserved gets here - ac.input = GamepadCls.BlendedInput; + acc.input = GamepadCls.BlendedInput; cn.Command = GamepadCls.BlendedInput; cn.BackColor = MyColors.BlendedColor; } } - else if ( KeyboardCls.IsDeviceClass( ac.device ) ) { + else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Keyboard ) { if ( !String.IsNullOrEmpty( ac.defBinding ) ) { - ac.input = ac.defBinding; + acc.input = ac.defBinding; cn.Command = ac.defBinding; cn.BackColor = KeyboardCls.KbdColor( ); } } } // Don't apply defaults - but blend if checked else { - // init empty - if ( JoystickCls.IsDeviceClass( ac.device ) && BlendUnmappedJS ) { - ac.input = JoystickCls.BlendedInput; + if ( ( ac.actionDevice == ActionCls.ActionDevice.AD_Joystick ) && BlendUnmappedJS ) { cn.Command = JoystickCls.BlendedInput; cn.BackColor = MyColors.BlendedColor; + acc.input = JoystickCls.BlendedInput; } - else if ( GamepadCls.IsDeviceClass( ac.device ) && BlendUnmappedGP ) { - ac.input = GamepadCls.BlendedInput; + else if ( ( ac.actionDevice == ActionCls.ActionDevice.AD_Gamepad ) && BlendUnmappedGP ) { cn.Command = GamepadCls.BlendedInput; cn.BackColor = MyColors.BlendedColor; + acc.input = GamepadCls.BlendedInput; } } } @@ -319,15 +442,105 @@ namespace SCJMapper_V2 /// First apply to the GUI tree where the selection happend then copy it over to master tree /// /// The new Text property - public void UpdateSelectedItem( String input, Boolean invert, DeviceCls.InputKind inKind ) + public Boolean UpdateSelectedItem( String input, ActionCls.ActionDevice inKind ) { - if ( Ctrl.SelectedNode == null ) return; + if ( ( Ctrl.SelectedNode.Level == 0 ) || ( Ctrl.SelectedNode.Level > 2 ) ) return false; // ERROR exit + if ( Ctrl.SelectedNode == null ) return false; // ERROR exit + if ( Ctrl.SelectedNode.Parent == null ) return false; // ERROR exit + + // has a parent - must be level 1 or 2 + if ( Ctrl.SelectedNode.Level == 1 ) { + // this is the main node with Action Cmd + ActionCls ac = FindActionObject( Ctrl.SelectedNode.Parent.Name, Ctrl.SelectedNode.Name ); + if ( ac == null ) return false; // ERROR exit + if ( ac.actionDevice != inKind ) return false; // ERROR exit + + ActionCommandCls acc = FindActionInputObject( Ctrl.SelectedNode.Parent.Name, Ctrl.SelectedNode.Name, CommandFromNodeText( Ctrl.SelectedNode.Text ) ); + if ( acc == null ) return false; // ERROR exit + UpdateActionCommandFromInput( input, acc, inKind ); + UpdateNodeFromAction( ( ActionTreeNode )Ctrl.SelectedNode, acc, inKind ); + } + else if ( Ctrl.SelectedNode.Level == 2 ) { + // this is a child of an action with further commands + ActionTreeNode atn = ( m_ctrl.SelectedNode.Parent as ActionTreeNode ); // the parent treenode + ActionCls ac = FindActionObject( atn.Parent.Name, atn.Name ); // the related action + if ( ac == null ) return false; // ERROR exit + if ( ac.actionDevice != inKind ) return false; // ERROR exit + + ActionCommandCls acc = FindActionInputObject( ac, m_ctrl.SelectedNode.Index ); + if ( acc == null ) return false; // ERROR exit + UpdateActionCommandFromInput( input, acc, inKind ); + UpdateInputNodeFromAction( ( ActionTreeInputNode )Ctrl.SelectedNode, acc, inKind ); + } + return true; + } - ActionCls ac = FindActionObject( Ctrl.SelectedNode.Parent.Name, Ctrl.SelectedNode.Name ); - UpdateActionFromInput( input, invert, ac ); - UpdateNodeFromAction( ( ActionTreeNode )Ctrl.SelectedNode, ac, inKind ); + /// + /// Find an action with name in a actionmap + /// + /// The actionmap name + /// The action + /// The input + /// An actionCommand or null if not found + private ActionCommandCls FindActionInputObject( String actionMap, String action, String input ) + { + log.Debug( "FindActionInputObject - Entry" ); + // Apply the input to the ActionTree + ActionCls ac = null; ActionCommandCls acc = null; + ActionMapCls ACM = ActionMaps.Find( delegate( ActionMapCls _ACM ) { return _ACM.name == actionMap; } ); + if ( ACM != null ) ac = ACM.Find( delegate( ActionCls _AC ) { return _AC.key == action; } ); + if ( ac != null ) acc = ac.inputList.Find( delegate( ActionCommandCls _ACC ) { return _ACC.input == input; } ); + if ( acc == null ) { + log.Error( "FindActionInputObject - Action Input not found in tree" ); + return null; // ERROR - Action Input not found in tree + } + return acc; } + /// + /// Find an action with name in a actionmap + /// + /// The actionmap name + /// The action + /// The input + /// An actionCommand or null if not found + private ActionCommandCls FindActionInputObject( String actionMap, String action, int index ) + { + log.Debug( "FindActionInputObject - Entry" ); + // Apply the input to the ActionTree + ActionCls ac = null; ActionCommandCls acc = null; + ActionMapCls ACM = ActionMaps.Find( delegate( ActionMapCls _ACM ) { return _ACM.name == actionMap; } ); + if ( ACM != null ) ac = ACM.Find( delegate( ActionCls _AC ) { return _AC.key == action; } ); + if ( ac != null ) acc = ac.inputList.Find( delegate( ActionCommandCls _ACC ) { return _ACC.nodeIndex == index; } ); + if ( acc == null ) { + log.Error( "FindActionInputObject - Action Input not found in tree" ); + return null; // ERROR - Action Input not found in tree + } + return acc; + } + + + /// + /// Find an ActionCommand with index in an Action + /// + /// The actionmap name + /// The action + /// The input + /// An actionCommand or null if not found + private ActionCommandCls FindActionInputObject( ActionCls ac, int index ) + { + log.Debug( "FindActionInputObject - Entry" ); + // Apply the input to the ActionTree + ActionCommandCls acc = null; + if ( ac != null ) acc = ac.inputList.Find( delegate( ActionCommandCls _ACC ) { return _ACC.nodeIndex == index; } ); + if ( acc == null ) { + log.Error( "FindActionInputObject - Action Input not found in Action" ); + return null; // ERROR - Action Input not found in tree + } + return acc; + } + + /// /// Find an action with name in a actionmap /// @@ -350,28 +563,26 @@ namespace SCJMapper_V2 /// - /// Updates an action with a new input (command) + /// Updates an actionCommand with a new input (command) /// /// The input command - /// The action to update - /// The input device - private void UpdateActionFromInput( String input, Boolean invert, ActionCls action ) + /// The action to containing the command + /// The actionCommand to update + private void UpdateActionCommandFromInput( String input, ActionCommandCls actionCmd, ActionCls.ActionDevice inKind ) { - log.Debug( "UpdateActionFromInput - Entry" ); - if ( action == null ) return; + log.Debug( "UpdateActionCommandFromInput - Entry" ); + if ( actionCmd == null ) return; // Apply the input to the ActionTree if ( String.IsNullOrEmpty( input ) ) { // unmapped - handle the blended ones from setting - action.inverted = false; // reset in any case - if ( JoystickCls.IsDeviceClass( action.device ) && BlendUnmappedJS ) action.input = JoystickCls.BlendedInput; - else if ( GamepadCls.IsDeviceClass( action.device ) && BlendUnmappedGP ) action.input = GamepadCls.BlendedInput; - else action.input = ""; + if ( ( inKind == ActionCls.ActionDevice.AD_Joystick ) && BlendUnmappedJS ) actionCmd.input = JoystickCls.BlendedInput; + else if ( ( inKind == ActionCls.ActionDevice.AD_Gamepad ) && BlendUnmappedGP ) actionCmd.input = GamepadCls.BlendedInput; + else actionCmd.input = ""; } else { // mapped ones - action.input = input; - action.inverted = invert; + actionCmd.input = input; } Dirty = true; } @@ -384,43 +595,42 @@ namespace SCJMapper_V2 /// The TreeNode to update /// The action that carries the update /// The input device - private void UpdateNodeFromAction( ActionTreeNode node, ActionCls action, DeviceCls.InputKind inKind ) + private void UpdateNodeFromAction( ActionTreeNode node, ActionCommandCls actionCmd, ActionCls.ActionDevice inKind ) { log.Debug( "UpdateNodeFromAction - Entry" ); - if ( action == null ) return; + if ( actionCmd == null ) return; - // applies only to ActionNodes + // applies only to ActionTreeNode if ( node.Level == 1 ) { // input is either "" or a valid mapping or a blended mapping - if ( String.IsNullOrEmpty( action.input ) ) { + if ( String.IsNullOrEmpty( actionCmd.input ) ) { // new unmapped - node.Command = ""; node.InvertCommand = false; node.BackColor = MyColors.UnassignedColor; + node.Command = ""; node.BackColor = MyColors.UnassignedColor; } // blended mapped ones - can only get a Blend Background - else if ( JoystickCls.IsDeviceClass( action.device ) && ( action.input == JoystickCls.BlendedInput ) ) { - node.Command = action.input; node.InvertCommand = false; node.BackColor = MyColors.BlendedColor; + else if ( ( inKind == ActionCls.ActionDevice.AD_Joystick ) && ( actionCmd.input == JoystickCls.BlendedInput ) ) { + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; } - else if ( GamepadCls.IsDeviceClass( action.device ) && ( action.input == GamepadCls.BlendedInput ) ) { - node.Command = action.input; node.InvertCommand = false; node.BackColor = MyColors.BlendedColor; + else if ( ( inKind == ActionCls.ActionDevice.AD_Gamepad ) && ( actionCmd.input == GamepadCls.BlendedInput ) ) { + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; } - else if ( action.input == DeviceCls.BlendedInput ) { + else if ( actionCmd.input == DeviceCls.BlendedInput ) { // Manually Blended input - node.Command = action.input; node.InvertCommand = false; node.BackColor = MyColors.BlendedColor; + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; } else { // mapped ( regular ones ) - node.Command = action.input; - node.InvertCommand = action.inverted; + node.Command = actionCmd.input; // background is along the input - if ( inKind == DeviceCls.InputKind.Joystick ) { - int jNum = JoystickCls.JSNum( action.input ); + if ( inKind == ActionCls.ActionDevice.AD_Joystick ) { + int jNum = JoystickCls.JSNum( actionCmd.input ); node.BackColor = JoystickCls.JsNColor( jNum ); } - else if ( inKind == DeviceCls.InputKind.Gamepad ) { + else if ( inKind == ActionCls.ActionDevice.AD_Gamepad ) { node.BackColor = GamepadCls.XiColor( ); } - else if ( inKind == DeviceCls.InputKind.Kbd ) { + else if ( inKind == ActionCls.ActionDevice.AD_Keyboard ) { node.BackColor = KeyboardCls.KbdColor( ); } else { @@ -433,6 +643,62 @@ namespace SCJMapper_V2 } } + + /// + /// Apply an update from the action to the treenode + /// First apply to the GUI tree where the selection happend then copy it over to master tree + /// + /// The input command + /// The TreeNode to update + /// The actionCommand that carries the update + /// The input device + private void UpdateInputNodeFromAction( ActionTreeInputNode node, ActionCommandCls actionCmd, ActionCls.ActionDevice inKind ) + { + log.Debug( "UpdateInputNodeFromAction - Entry" ); + if ( actionCmd == null ) return; + if ( node.Level != 2 ) return; // applies only to ActionTreeInputNode + + // input is either "" or a valid mapping or a blended mapping + if ( String.IsNullOrEmpty( actionCmd.input ) ) { + // new unmapped + node.Command = ""; node.BackColor = MyColors.UnassignedColor; + } + + // blended mapped ones - can only get a Blend Background + else if ( ( inKind == ActionCls.ActionDevice.AD_Joystick ) && ( actionCmd.input == JoystickCls.BlendedInput ) ) { + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; + } + else if ( ( inKind == ActionCls.ActionDevice.AD_Gamepad ) && ( actionCmd.input == GamepadCls.BlendedInput ) ) { + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; + } + else if ( actionCmd.input == DeviceCls.BlendedInput ) { + // Manually Blended input + node.Command = actionCmd.input; node.BackColor = MyColors.BlendedColor; + } + else { + // mapped ( regular ones ) + node.Command = actionCmd.input; + + // background is along the input + if ( inKind == ActionCls.ActionDevice.AD_Joystick ) { + int jNum = JoystickCls.JSNum( actionCmd.input ); + node.BackColor = JoystickCls.JsNColor( jNum ); + } + else if ( inKind == ActionCls.ActionDevice.AD_Gamepad ) { + node.BackColor = GamepadCls.XiColor( ); + } + else if ( inKind == ActionCls.ActionDevice.AD_Keyboard ) { + node.BackColor = KeyboardCls.KbdColor( ); + } + else { + // ?? what else + node.BackColor = MyColors.UnassignedColor; + } + } + UpdateMasterNode( node ); + + } + /// /// Defines what to show in the tree /// @@ -440,7 +706,7 @@ namespace SCJMapper_V2 /// True to show Gamepad actions /// True to show Keyboard actions /// True to show mapped actions only - public void DefineShowOptions(Boolean showJoystick, Boolean showGamepad, Boolean showKeyboard, Boolean showMappedOnly) + public void DefineShowOptions( Boolean showJoystick, Boolean showGamepad, Boolean showKeyboard, Boolean showMappedOnly ) { m_showJoy = showJoystick; m_showGameP = showGamepad; @@ -460,37 +726,32 @@ namespace SCJMapper_V2 foreach ( ActionMapCls acm in ActionMaps ) { if ( IgnoreMaps.Contains( "," + acm.name + "," ) ) break; // next try { - ActionTreeNode amTn = ( ActionTreeNode )m_MasterTree.Nodes[acm.name]; // get the map node + ActionTreeNode mtn = ( ActionTreeNode )m_MasterTree.Nodes[acm.name]; // get the map node // find the item to reload into the treeview foreach ( ActionCls ac in acm ) { - try { - ActionTreeNode tnl = ( ActionTreeNode )amTn.Nodes[ac.key]; - UpdateActionFromInput( ac.input, ac.inverted, ac ); // this may apply (un)Blending if needed - // input kind priority first - if ( JoystickCls.IsJsN( ac.input ) ) { - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Joystick ); - } - else if ( GamepadCls.IsXiValid( ac.input ) ) { - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Gamepad ); - } - // device priority second - else if ( JoystickCls.IsDeviceClass( ac.device ) ) { - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Joystick ); - } - else if ( GamepadCls.IsDeviceClass( ac.device ) ) { - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Gamepad ); - } - else if ( KeyboardCls.IsDeviceClass( ac.device ) ) { - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Kbd ); + ActionTreeNode matn = ( ActionTreeNode )mtn.Nodes[ac.key]; // get the action node + Boolean first=true; + // refresh commands + foreach ( ActionCommandCls acc in ac.inputList ) { + try { + UpdateActionCommandFromInput( acc.input, acc, ac.actionDevice ); // this may apply (un)Blending if needed + // the first one goes into the node, further must be created if not existing + if ( first ) { + UpdateNodeFromAction( matn, acc, ac.actionDevice ); + matn.Nodes.Clear( ); // clear add childs - those don't persist from newly loaded actionmaps + first = false; + } + else { + // have to recreate the action child nodes + ActionTreeInputNode matin = new ActionTreeInputNode( "UNDEF" ); matin.ImageKey = "Add"; + acc.nodeIndex = matin.Index; // assign visual reference + matn.Nodes.Add( matin ); // add to master tree + UpdateInputNodeFromAction( matin, acc, ac.actionDevice ); + } } - else { - // ?? defaults to unassigned color - UpdateNodeFromAction( tnl, ac, DeviceCls.InputKind.Other ); + catch { + ; // key not found } - - } - catch { - ; // key not found } } } @@ -513,24 +774,59 @@ namespace SCJMapper_V2 { log.Debug( "FindAndSelectCtrl - Entry" ); - Boolean found = false; foreach ( ActionTreeNode tn in Ctrl.Nodes ) { // have to search nodes of nodes foreach ( ActionTreeNode stn in tn.Nodes ) { if ( stn.Text.Contains( ctrl ) ) { Ctrl.SelectedNode = stn; Ctrl.SelectedNode.EnsureVisible( ); - found = true; - break; + return; // exit all loops + } + // have to search nodes of nodes + foreach ( ActionTreeInputNode sstn in stn.Nodes ) { + if ( sstn.Text.Contains( ctrl ) ) { + Ctrl.SelectedNode = sstn; + Ctrl.SelectedNode.EnsureVisible( ); + return; // exit all loops + } } } - if ( found ) break; // exit all loops } } /// - /// Find a control that contains the Command + /// Find a control that contains the string and mark it + /// this method is applied to the GUI TreeView only + /// + /// The string to find + public void FindAndSelectCtrlByName( String ctrlName ) + { + log.Debug( "FindAndSelectCtrlByName - Entry" ); + + foreach ( ActionTreeNode tn in Ctrl.Nodes ) { + // have to search nodes of nodes + foreach ( ActionTreeNode stn in tn.Nodes ) { + if ( stn.Name == ctrlName ) { + Ctrl.SelectedNode = stn; + Ctrl.SelectedNode.EnsureVisible( ); + return; // exit all loops + } + // have to search nodes of nodes + foreach ( ActionTreeInputNode sstn in stn.Nodes ) { + if ( sstn.Name == ctrlName ) { + Ctrl.SelectedNode = sstn; + Ctrl.SelectedNode.EnsureVisible( ); + return; // exit all loops + } + } + } + } + } + + + /// + /// Find a control that contains the Action /// /// The actionmap to find the string /// The string to find @@ -561,6 +857,14 @@ namespace SCJMapper_V2 } + + static public String CommandFromNodeText( String actionCommand ) + { + String[] e = actionCommand.Split( new char[] { '-' } ); + if ( e.Length > 1 ) return e[1].Substring( 1 ); + return ""; + } + /// /// Find a control that contains the Command /// @@ -574,8 +878,10 @@ namespace SCJMapper_V2 if ( String.IsNullOrEmpty( actionmap ) || ( tn.Text == actionmap ) ) { // have to search nodes of nodes foreach ( ActionTreeNode stn in tn.Nodes ) { - if ( stn.Command.Contains( command ) ) { - return stn.Text; + foreach ( ActionTreeInputNode istn in stn.Nodes ) { + if ( istn.Command.Contains( command ) ) { + return stn.Text + " - " + istn.Text; + } } } } @@ -625,6 +931,23 @@ namespace SCJMapper_V2 } + public String SelectedAction + { + get { + if ( Ctrl.SelectedNode == null ) return ""; + if ( Ctrl.SelectedNode.Level == 1 ) { + ActionTreeNode matn = FindMasterAction( ( ActionTreeNode )Ctrl.SelectedNode ); + return ActionTreeNode.ActionFromNodeText( matn.Text ); + } + else if ( Ctrl.SelectedNode.Level == 2 ) { + ActionTreeNode matn = FindMasterAction( ( ActionTreeNode )Ctrl.SelectedNode.Parent ); // the parent treenode + return ActionTreeNode.ActionFromNodeText( matn.Text ); + } + else return ""; + } + } + + /// /// Reports a summary list of the mapped items /// @@ -644,9 +967,11 @@ namespace SCJMapper_V2 String rep = String.Format( "*** {0}\n", acm.name ); repList += rep; foreach ( ActionCls ac in acm ) { - if ( !String.IsNullOrEmpty( ac.input ) && !( ac.input == JoystickCls.BlendedInput ) ) { - rep = String.Format( " {0} - {1} - ({2})\n", ac.name.PadRight( 35 ), ac.input.PadRight( 30 ), ac.device ); - repList += rep; + foreach ( ActionCommandCls acc in ac.inputList ) { + if ( !String.IsNullOrEmpty( acc.input ) && !( acc.input == JoystickCls.BlendedInput ) ) { + rep = String.Format( " {0} - {1} - ({2})\n", ac.name.PadRight( 35 ), acc.input.PadRight( 30 ), ac.device ); + repList += rep; + } } } repList += String.Format( "\n" ); diff --git a/actions/ActionTreeInputNode.cs b/actions/ActionTreeInputNode.cs new file mode 100644 index 0000000..a0575e6 --- /dev/null +++ b/actions/ActionTreeInputNode.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace SCJMapper_V2 +{ + /// + /// Our INPUT TreeNode - inherits a regular one and adds some functionality + /// + /// contains the input command i.e. - js2_button3 OR ! js1_x (MODs applies at the very beginning of the string) + /// + class ActionTreeInputNode : TreeNode + { + + #region Static items + + + // Handle all text label composition and extraction here + + public static String ComposeNodeText( String cmd ) + { + if ( String.IsNullOrEmpty( cmd ) ) { + return ""; + } + else { + return cmd; + } + } + + + public static void DecompNodeText( String nodeText, out String cmd ) + { + cmd = nodeText; + } + + + /// + /// Returns the command part from a node text + /// i.e. v_pitch - js1_x returns js1_x + /// + /// The node text in 'action - command' notation + /// the command part or an empty string + public static String CommandFromNodeText( String nodeText ) + { + String cmd; + DecompNodeText( nodeText, out cmd ); + return cmd; + } + + #endregion + + + // Object defs + + // ctor + public ActionTreeInputNode( ) + : base( ) + { + } + + // ctor + public ActionTreeInputNode( ActionTreeInputNode srcNode ) + : base( ) + { + if ( srcNode == null ) return; + this.Name = srcNode.Name; + this.Text = srcNode.Text; + this.BackColor = srcNode.BackColor; + this.ForeColor = srcNode.ForeColor; + this.NodeFont = srcNode.NodeFont; + this.ImageKey = srcNode.ImageKey; + this.Tag = srcNode.Tag; + this.m_command = srcNode.m_command; + } + + // ctor + public ActionTreeInputNode( string text ) + { + this.Text = text; + } + + // ctor + public ActionTreeInputNode( string text, ActionTreeInputNode[] children ) + : base( text, children ) + { + } + + + private String m_command =""; + + public new String Text + { + get { return base.Text; } + set + { + DecompNodeText( value, out m_command ); + base.Text = ComposeNodeText( m_command ); + } + } + + + public String Command + { + get { return m_command; } + set + { + m_command = value; + base.Text = ComposeNodeText( m_command ); + } + } + + public Boolean IsMappedAction + { + get + { + return !( String.IsNullOrEmpty( m_command ) + || ( m_command == JoystickCls.BlendedInput ) + || ( m_command == GamepadCls.BlendedInput ) ); + } + } + + } +} diff --git a/actions/ActionTreeNode.cs b/actions/ActionTreeNode.cs index e34a281..cc3482e 100644 --- a/actions/ActionTreeNode.cs +++ b/actions/ActionTreeNode.cs @@ -14,27 +14,23 @@ namespace SCJMapper_V2 #region Static items - public const char REG_MOD = '-'; - public const char INV_MOD = '!'; - - // Handle all text label composition and extraction here - public static String ComposeNodeText( String action, char mod, String cmd ) + public static String ComposeNodeText( String action, String cmd ) { if ( String.IsNullOrEmpty( cmd ) ) { return action; } else { - return action + " " + mod + " " + cmd; + return action + " - " + cmd; } } - public static void DecompNodeText( String nodeText, out String action, out char mod, out String cmd ) + public static void DecompNodeText( String nodeText, out String action, out String cmd ) { - action = ""; cmd = ""; mod = ( nodeText.Contains( INV_MOD ) ) ? INV_MOD : REG_MOD; - String[] e = nodeText.Split( new char[] { REG_MOD, INV_MOD }, StringSplitOptions.RemoveEmptyEntries ); + action = ""; cmd = ""; + String[] e = nodeText.Split( new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries ); if ( e.Length > 1 ) { action = e[0].TrimEnd( ); if ( e[1] == " " + DeviceCls.BlendedInput ) { @@ -59,8 +55,8 @@ namespace SCJMapper_V2 /// the action part or an empty string public static String ActionFromNodeText( String nodeText ) { - String action, cmd; char mod; - DecompNodeText( nodeText, out action, out mod, out cmd ); + String action, cmd; + DecompNodeText( nodeText, out action, out cmd ); return action; } @@ -72,24 +68,11 @@ namespace SCJMapper_V2 /// the command part or an empty string public static String CommandFromNodeText( String nodeText ) { - String action, cmd; char mod; - DecompNodeText( nodeText, out action, out mod, out cmd ); + String action, cmd; + DecompNodeText( nodeText, out action, out cmd ); return cmd; } - /// - /// Returns the invert modifier of the command part from a node text - /// i.e. v_pitch - js1_x returns false v_pitch ! js1_x returns true - /// - /// The node text in 'action - command' notation - /// True if there is a command and if it contains an inverter else false - public static Boolean CommandInvertFromNodeText( String nodeText ) - { - String action, cmd; char mod; - DecompNodeText( nodeText, out action, out mod, out cmd ); - return ( mod == INV_MOD ); - } - #endregion @@ -115,8 +98,6 @@ namespace SCJMapper_V2 this.Tag = srcNode.Tag; this.m_action = srcNode.m_action; this.m_actionDevice = srcNode.m_actionDevice; - this.m_command = srcNode.m_command; - this.m_modifier = srcNode.m_modifier; } // ctor @@ -134,7 +115,6 @@ namespace SCJMapper_V2 private String m_action = ""; private String m_command =""; - private char m_modifier = REG_MOD; private ActionCls.ActionDevice m_actionDevice = ActionCls.ActionDevice.AD_Unknown; public new String Text @@ -142,8 +122,8 @@ namespace SCJMapper_V2 get { return base.Text; } set { - DecompNodeText( value, out m_action, out m_modifier, out m_command ); - base.Text = ComposeNodeText( m_action, m_modifier, m_command ); + DecompNodeText( value, out m_action, out m_command ); + base.Text = ComposeNodeText( m_action, m_command ); } } @@ -154,7 +134,7 @@ namespace SCJMapper_V2 set { m_action = value; - base.Text = ComposeNodeText( m_action, m_modifier, m_command ); + base.Text = ComposeNodeText( m_action, m_command ); } } @@ -164,17 +144,7 @@ namespace SCJMapper_V2 set { m_command = value; - base.Text = ComposeNodeText( m_action, m_modifier, m_command ); - } - } - - public Boolean InvertCommand - { - get { return ( m_modifier == INV_MOD ); } - set - { - m_modifier = ( value ) ? INV_MOD : REG_MOD; - base.Text = ComposeNodeText( m_action, m_modifier, m_command ); + base.Text = ComposeNodeText( m_action, m_command ); } } @@ -204,9 +174,11 @@ namespace SCJMapper_V2 public Boolean IsMappedAction { - get { return !( String.IsNullOrEmpty(m_command) - || ( m_command == JoystickCls.BlendedInput ) - || ( m_command == GamepadCls.BlendedInput ) ); + get + { + return !( String.IsNullOrEmpty( m_command ) + || ( m_command == JoystickCls.BlendedInput ) + || ( m_command == GamepadCls.BlendedInput ) ); } } diff --git a/graphics/Addbind.ico b/graphics/Addbind.ico new file mode 100644 index 0000000..9200878 Binary files /dev/null and b/graphics/Addbind.ico differ