diff --git a/DeviceCls.cs b/DeviceCls.cs index 42c2858..426ac6f 100644 --- a/DeviceCls.cs +++ b/DeviceCls.cs @@ -42,6 +42,10 @@ namespace SCJMapper_V2 { return blendedInput.Replace( BlendedInput, " " ); // must make spaces (tilde is for internal processing only) } + static public String toXMLBlendExtension( String blendedInput ) + { + return (IsBlendedInput(blendedInput) ? string.Format( "multiTap=\"1\"") : "" ); // blending needs to overwrite potential multitaps (2+) + } static public String fromXML( String blendedInput ) { return blendedInput.Replace( " ", BlendedInput ); // must make tilde (spaces is for external processing only) diff --git a/Form1.Designer.cs b/Form1.Designer.cs index fd92f08..c688c32 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -75,11 +75,15 @@ this.tdiAddBinding = new System.Windows.Forms.ToolStripMenuItem(); this.tdiDelBinding = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.tdiTxDefActivationMode = new System.Windows.Forms.ToolStripTextBox(); + this.tdiCbxActivation = new System.Windows.Forms.ToolStripComboBox(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); this.tdiAddMod1 = new System.Windows.Forms.ToolStripMenuItem(); this.tdiAddMod2 = new System.Windows.Forms.ToolStripMenuItem(); this.tdiAddMod3 = new System.Windows.Forms.ToolStripMenuItem(); this.tc1 = new System.Windows.Forms.TabControl(); this.tabJS1 = new System.Windows.Forms.TabPage(); + this.UC_JoyPanel = new SCJMapper_V2.UC_JoyPanel(); this.panel1 = new System.Windows.Forms.Panel(); this.btClip = new System.Windows.Forms.Button(); this.txRebind = new System.Windows.Forms.TextBox(); @@ -137,10 +141,6 @@ this.loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); - this.tdiCbxActivation = new System.Windows.Forms.ToolStripComboBox(); - this.tdiTxDefActivationMode = new System.Windows.Forms.ToolStripTextBox(); - this.UC_JoyPanel = new SCJMapper_V2.UC_JoyPanel(); this.cmCopyPaste.SuspendLayout(); this.panel2.SuspendLayout(); this.cmMouseEntry.SuspendLayout(); @@ -280,12 +280,12 @@ this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; this.panel2.Location = new System.Drawing.Point(3, 358); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(289, 170); + this.panel2.Size = new System.Drawing.Size(289, 168); this.panel2.TabIndex = 17; // // btMakeMod // - this.btMakeMod.Location = new System.Drawing.Point(10, 140); + this.btMakeMod.Location = new System.Drawing.Point(10, 137); this.btMakeMod.Name = "btMakeMod"; this.btMakeMod.Size = new System.Drawing.Size(73, 25); this.btMakeMod.TabIndex = 17; @@ -549,6 +549,33 @@ this.toolStripSeparator5.Name = "toolStripSeparator5"; this.toolStripSeparator5.Size = new System.Drawing.Size(217, 6); // + // tdiTxDefActivationMode + // + this.tdiTxDefActivationMode.BackColor = System.Drawing.Color.PapayaWhip; + this.tdiTxDefActivationMode.Name = "tdiTxDefActivationMode"; + this.tdiTxDefActivationMode.ReadOnly = true; + this.tdiTxDefActivationMode.Size = new System.Drawing.Size(160, 23); + this.tdiTxDefActivationMode.Text = "Default ActMode"; + // + // tdiCbxActivation + // + this.tdiCbxActivation.AutoSize = false; + this.tdiCbxActivation.DropDownHeight = 140; + this.tdiCbxActivation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.Simple; + this.tdiCbxActivation.DropDownWidth = 160; + this.tdiCbxActivation.IntegralHeight = false; + this.tdiCbxActivation.Items.AddRange(new object[] { + "None"}); + this.tdiCbxActivation.MaxDropDownItems = 10; + this.tdiCbxActivation.Name = "tdiCbxActivation"; + this.tdiCbxActivation.Size = new System.Drawing.Size(160, 180); + this.tdiCbxActivation.Click += new System.EventHandler(this.tdiCbxActivation_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(217, 6); + // // tdiAddMod1 // this.tdiAddMod1.Name = "tdiAddMod1"; @@ -603,6 +630,15 @@ this.tabJS1.TabIndex = 0; this.tabJS1.Text = "Joystick 1"; // + // UC_JoyPanel + // + this.UC_JoyPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.UC_JoyPanel.JsAssignment = 0; + this.UC_JoyPanel.Location = new System.Drawing.Point(3, 3); + this.UC_JoyPanel.Name = "UC_JoyPanel"; + this.UC_JoyPanel.Size = new System.Drawing.Size(275, 315); + this.UC_JoyPanel.TabIndex = 0; + // // panel1 // this.tlpanel.SetColumnSpan(this.panel1, 3); @@ -1239,42 +1275,6 @@ this.statusStrip1.TabIndex = 26; this.statusStrip1.Text = "statusStrip1"; // - // toolStripSeparator6 - // - this.toolStripSeparator6.Name = "toolStripSeparator6"; - this.toolStripSeparator6.Size = new System.Drawing.Size(217, 6); - // - // tdiCbxActivation - // - this.tdiCbxActivation.AutoSize = false; - this.tdiCbxActivation.DropDownHeight = 140; - this.tdiCbxActivation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.Simple; - this.tdiCbxActivation.DropDownWidth = 160; - this.tdiCbxActivation.IntegralHeight = false; - this.tdiCbxActivation.Items.AddRange(new object[] { - "None"}); - this.tdiCbxActivation.MaxDropDownItems = 10; - this.tdiCbxActivation.Name = "tdiCbxActivation"; - this.tdiCbxActivation.Size = new System.Drawing.Size(160, 180); - // - // tdiTxDefActivationMode - // - this.tdiTxDefActivationMode.BackColor = System.Drawing.Color.PapayaWhip; - this.tdiTxDefActivationMode.Font = new System.Drawing.Font("Segoe UI", 9F); - this.tdiTxDefActivationMode.Name = "tdiTxDefActivationMode"; - this.tdiTxDefActivationMode.ReadOnly = true; - this.tdiTxDefActivationMode.Size = new System.Drawing.Size(160, 23); - this.tdiTxDefActivationMode.Text = "Default ActMode"; - // - // UC_JoyPanel - // - this.UC_JoyPanel.Dock = System.Windows.Forms.DockStyle.Fill; - this.UC_JoyPanel.JsAssignment = 0; - this.UC_JoyPanel.Location = new System.Drawing.Point(3, 3); - this.UC_JoyPanel.Name = "UC_JoyPanel"; - this.UC_JoyPanel.Size = new System.Drawing.Size(275, 315); - this.UC_JoyPanel.TabIndex = 0; - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/Form1.cs b/Form1.cs index e0664e0..81ef81f 100644 --- a/Form1.cs +++ b/Form1.cs @@ -22,6 +22,11 @@ namespace SCJMapper_V2 private AppSettings m_AppSettings = new AppSettings( ); private Boolean m_appLoading = true; // used to detect if we are loading (or running) + // keyboard modifier handling variables + private String m_persistentMods = ""; + private const int c_modifierTime = 3500; // msec time before a modifier times out and will be removed + private int m_modifierTimeout = 0; + /// /// Holds the DXInput Joystick List @@ -276,7 +281,7 @@ namespace SCJMapper_V2 // init PTU folder usage sign lblPTU.Visible = m_AppSettings.UsePTU; - if (m_AppSettings.UsePTU) log.Debug( "Using PTU Folders" ); + if ( m_AppSettings.UsePTU ) log.Debug( "Using PTU Folders" ); // poll the XInput log.Debug( "Start XInput polling" ); @@ -401,7 +406,7 @@ namespace SCJMapper_V2 // Activation Update tdiCbxActivation.Items.Clear( ); - tdiCbxActivation.Items.AddRange( m_AT.ActivationModes.ToArray() ); + tdiCbxActivation.Items.AddRange( ActivationModes.Instance.Names.ToArray( ) ); tdiCbxActivation.SelectedIndex = 0; // apply a default JS to Joystick mapping - can be changed and reloaded from XML mappings @@ -423,6 +428,8 @@ namespace SCJMapper_V2 } } } + m_AT.FilterTree( txFilter.Text ); + } @@ -585,7 +592,7 @@ namespace SCJMapper_V2 // Collect modifiers - simply overwrite existing ones as we deal with THIS file now tdiAddMod1.Visible = false; tdiAddMod2.Visible = false; tdiAddMod3.Visible = false; // make context menu invisible tdiAddMod1.Text = ""; tdiAddMod2.Text = ""; tdiAddMod3.Text = ""; // and clear - for (int i=flpExtensions.Controls.Count-1; i>=0; i-- ) { + for ( int i = flpExtensions.Controls.Count - 1; i >= 0; i-- ) { if ( ( flpExtensions.Controls[i] as CheckBox ).Text.StartsWith( "js" ) ) flpExtensions.Controls.RemoveAt( i ); } if ( m_AT.ActionMaps.Modifiers.Count > 2 ) { @@ -647,6 +654,14 @@ namespace SCJMapper_V2 btDump.BackColor = btClear.BackColor; btDump.UseVisualStyleBackColor = btClear.UseVisualStyleBackColor; // neutral again btGrab.BackColor = btClear.BackColor; btGrab.UseVisualStyleBackColor = btClear.UseVisualStyleBackColor; // neutral again + + // get the text into the view + try { + rtb.ScrollToCaret( ); + } + catch { + ; // just ignore + } } @@ -684,46 +699,51 @@ namespace SCJMapper_V2 } - String m_persistentMods = ""; - // polls the devices to get the latest update private void timer1_Tick( object sender, System.EventArgs e ) { - if ( m_keyIn ) return; // allow keyboard / mouse input - if ( tc1.SelectedTab.Tag == null ) return; + // Handle Kbd modifier timeout for joystick + m_modifierTimeout -= timer1.Interval; // decrement timeout + if ( m_modifierTimeout < 0 ) m_modifierTimeout = 0; // prevent undeflow after long time not using modifiers + + + if ( m_keyIn || tc1.SelectedTab.Tag == null ) return; // don't handle those String ctrl = ""; if ( m_curJoystick == null ) { + // no active joystick - may be a gamepad if ( m_Gamepad != null ) { // poll Gamepad if active m_Gamepad.GetData( ); ctrl = m_Gamepad.GetLastChange( ); - timer1.Interval = 750; // allow more time to release buttons + timer1.Interval = 750; // allow more time to release buttons [msec] } } else { // poll active Joystick m_curJoystick.GetData( ); // poll the device + // add keyboard modifier - if there are .. if ( m_Keyboard == null ) { - // no keyboard = no modifier + // no keyboard => no modifier ctrl = JSStr( ) + m_curJoystick.GetLastChange( ); // show last handled JS control } else { - UpdateModifiers( ); // get the last keyboard modifer to compose the command + UpdateModifiers( ); // get the last keyboard modifer to compose the command, also handles the modifier lifetime ctrl = JSStr( ) + m_persistentMods + m_curJoystick.GetLastChange( ); // show last handled JS control } - timer1.Interval = 150; // standard polling + timer1.Interval = 150; // standard polling [msec] } lblLastJ.Text = ctrl; + // Handle Throttle checkbox if ( JoystickCls.CanThrottle( ctrl ) ) { cbxThrottle.Enabled = true; } else { cbxThrottle.Checked = false; cbxThrottle.Enabled = false; } - + // Update joystick modifiers - not currently used btMakeMod.Enabled = JoystickCls.ValidModifier( ctrl ); } @@ -791,7 +811,7 @@ namespace SCJMapper_V2 private void btClear_Click( object sender, EventArgs e ) { - if ( m_AT.CanClearBinding ) { + if ( m_AT.CanClearBinding || m_AT.CanBlendBinding ) { m_AT.ClearBinding( ); if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; } @@ -811,7 +831,7 @@ namespace SCJMapper_V2 flpExtensions.Controls.Add( cbx ); m_AT.ActionMaps.Modifiers.Add( lblLastJ.Text ); // maintain context menu - quick and d.. version - if ( string.IsNullOrEmpty( tdiAddMod1.Text) ) { + if ( string.IsNullOrEmpty( tdiAddMod1.Text ) ) { tdiAddMod1.Text = string.Format( "MOD: {0}", lblLastJ.Text ); tdiAddMod1.Visible = true; m_curJoystick.UpdateModifier( lblLastJ.Text, true ); @@ -1014,7 +1034,7 @@ namespace SCJMapper_V2 } // Node Menu - private string m_prevActivationMode =""; + private ActivationMode m_prevActivationMode = new ActivationMode( ActivationMode.Default ); private void cmAddDel_Opening( object sender, CancelEventArgs e ) { @@ -1022,7 +1042,7 @@ namespace SCJMapper_V2 ContextMenuStrip cts = ( sender as ContextMenuStrip ); Boolean any=false; // above separator Boolean any2 = false; // below separator - m_prevActivationMode = ""; // switch Closing handling OFF in case we don't show anything + m_prevActivationMode = ActivationMode.Default; // switch Closing handling OFF in case we don't show anything if ( m_AT.CanAssignBinding ) { cts.Items[0].Text = "Assign: " + JoystickCls.MakeThrottle( lblLastJ.Text, cbxThrottle.Checked ); @@ -1041,29 +1061,37 @@ namespace SCJMapper_V2 tdiCbxActivation.Visible = false; ActivationModes am = m_AT.ActivationModeSelectedItem( ); // have to fudge around with a descriptive text here - if ( am[0] == ActivationModes.Default ) + if ( am[0] == ActivationMode.Default ) tdiTxDefActivationMode.Text = string.Format( "Profile: {0}", "no ActivationMode" ); // show the default element else - tdiTxDefActivationMode.Text = string.Format( "Profile: {0}", am[0] ); // show the default element + tdiTxDefActivationMode.Text = string.Format( "Profile: {0}", am[0].Name ); // show the default element - if ( any && m_AT.IsMappedAction ) { + if ( any && m_AT.IsMappedAction ) { m_prevActivationMode = am[1]; // this is the selected one - tdiCbxActivation.Visible =true; - tdiCbxActivation.Text = m_prevActivationMode; + tdiCbxActivation.Visible = true; + tdiCbxActivation.Text = m_prevActivationMode.Name; } e.Cancel = !( any || any2 ); } + // after user entry of the context menu - see if one has changed the ActivationMode private void cmAddDel_Closed( object sender, ToolStripDropDownClosedEventArgs e ) { - if ( !string.IsNullOrEmpty(m_prevActivationMode) && ( m_prevActivationMode != tdiCbxActivation.Text )) { + if ( !string.IsNullOrEmpty( m_prevActivationMode.Name ) && ( m_prevActivationMode.Name != ( string )tdiCbxActivation.SelectedItem ) ) { + tdiCbxActivation.Text = ( string )tdiCbxActivation.SelectedItem; + // seems to have changed - evaluate + // it is either one of the ActivationModes, or profile default m_AT.UpdateActivationModeSelectedItem( tdiCbxActivation.Text ); - if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; - m_prevActivationMode = ""; + if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor; + m_prevActivationMode = ActivationMode.Default; // reset prev entry for next edit } } + private void tdiCbxActivation_Click( object sender, EventArgs e ) + { + cmAddDel.Close( ToolStripDropDownCloseReason.ItemClicked ); + } private void tdiAssignBinding_Click( object sender, EventArgs e ) { // same as btAssign_Click @@ -1108,6 +1136,7 @@ namespace SCJMapper_V2 } + // rtb drop xml file private void rtb_DragEnter( object sender, DragEventArgs e ) { @@ -1449,22 +1478,18 @@ namespace SCJMapper_V2 { if ( m_keyIn ) { m_Keyboard.GetData( ); - lblLastJ.Text = m_Keyboard.GetLastChange( true ); - m_mouseIn = false; // clear on kbd input - // also maintain persistent mods - String modS = m_Keyboard.GetLastChange( false ); - if ( !String.IsNullOrEmpty( modS ) ) { - if ( modS.Contains( KeyboardCls.ClearMods ) ) { - // allow to cancel modifiers - m_persistentMods = ""; // kill persistent ones - } - else { - m_persistentMods = modS + "+"; - } + String modS = m_Keyboard.GetLastChange( false ); // modifiers only + String keyModS = m_Keyboard.GetLastChange( true ); // modifiers+keyboard input + // don't override modifiers when we are in mouse mode and the mod is the same and there is no kbd entry.... + if ( m_mouseIn && ( keyModS == modS ) && ( m_persistentMods == ( modS + "+" ) ) ) { + ; // nothing here - } - else - m_persistentMods = ""; // kill persistent ones - + else { + lblLastJ.Text = m_Keyboard.GetLastChange( true ); + m_mouseIn = false; // clear on kbd input + } + // also maintain persistent mods + UpdateModifiers( ); } // don't spill the field with regular input e.SuppressKeyPress = true; @@ -1487,6 +1512,13 @@ namespace SCJMapper_V2 } else { m_persistentMods = modS + "+"; + m_modifierTimeout = c_modifierTime; // restart show interval + } + } + else { + if ( m_modifierTimeout <= 0 ) { + m_persistentMods = ""; // modifier timed out + m_mouseIn = false; } } } @@ -1535,8 +1567,8 @@ namespace SCJMapper_V2 } - #endregion + #endregion } } diff --git a/Form1.resx b/Form1.resx index df71d3a..5f962b9 100644 --- a/Form1.resx +++ b/Form1.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA8 - EAAAAk1TRnQBSQFMAgEBCQEAAZgBDwGYAQ8BEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + EAAAAk1TRnQBSQFMAgEBCQEAAcABDwHAAQ8BEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index e53e05e..5f4cc31 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.17.0.50" )] -[assembly: AssemblyFileVersion( "2.17.0.50" )] +[assembly: AssemblyVersion( "2.18.0.51" )] +[assembly: AssemblyFileVersion( "2.18.0.51" )] diff --git a/SC/ActivationModes.cs b/SC/ActivationModes.cs index df6eb93..a975f34 100644 --- a/SC/ActivationModes.cs +++ b/SC/ActivationModes.cs @@ -5,6 +5,162 @@ using System.Text; namespace SCJMapper_V2 { + /// + /// Defines a single activation mode + /// + public class ActivationMode + { + private const string c_DefaultActModeName = "Use Profile"; + + /// + /// The default ActivationMode + /// + static public ActivationMode Default = new ActivationMode( c_DefaultActModeName ); + + /// + /// Returns true if the given name matches the default name + /// + /// Name to test + /// True if the name matches the default name + static public Boolean IsDefault( string activationName ) + { + return ( activationName == Default.Name ); + } + + + /// + /// The name of the ActivationMode + /// + public string Name { get; set; } + /// + /// Number of 'multitaps' defined (1..) + /// + public int MultiTap { get; set; } + + + /// + /// cTor: empty constructor + /// + public ActivationMode( ) + { + this.Name = Default.Name; + this.MultiTap = Default.MultiTap; + } + + /// + /// cTor: copy constructor + /// + /// + public ActivationMode( ActivationMode other ) + { + this.Name = other.Name; + this.MultiTap = other.MultiTap; + } + + /// + /// cTor: with init arguments, try to find the multiTap from the Instance list + /// + /// The Name + public ActivationMode( string name ) + { + Name = name; + // if the name is default - multitap is valid else it should be 0 and is given by the mode list + if ( Name == c_DefaultActModeName ) { + MultiTap = 1; + } + else { + // try to get the one from the list (if the list is available..) + try { + MultiTap = ActivationModes.Instance.MultiTapFor( Name ); + } + catch { + // not in list - set to 1 + MultiTap = 1; + } + } + } + + /// + /// cTor: with init arguments + /// + /// The Name + /// The multiTap number + public ActivationMode( string name, int mTaps ) + { + Name = name; + MultiTap = mTaps; + } + + /// + /// Returns true if multiTap is more than 1 + /// + public Boolean IsDoubleTap { get { return ( MultiTap > 1 ); } } + + + + public static bool operator ==( ActivationMode a, ActivationMode b ) + { + // If both are null, or both are same instance, return true. + if ( System.Object.ReferenceEquals( a, b ) ) { + return true; + } + + // If one is null, but not both, return false. + if ( ( ( object )a == null ) || ( ( object )b == null ) ) { + return false; + } + + // Return true if the fields match: + return a.Equals( b ); + } + + public static bool operator !=( ActivationMode a, ActivationMode b ) + { + return !( a == b ); + } + + public override bool Equals( System.Object obj ) + { + // If parameter is null return false. + if ( obj == null ) { + return false; + } + + // If parameter cannot be cast to Point return false. + ActivationMode p = obj as ActivationMode; + if ( ( System.Object )p == null ) { + return false; + } + + // Return true if the fields match: + return ( this.Equals( p ) ); + } + + /// + /// Returns true if they are the same + /// + /// ActivationMode to compare with + /// True if both are the same, else false + public bool Equals( ActivationMode p ) + { + // If parameter is null return false: + if ( ( object )p == null ) { + return false; + } + + // Return true if the fields match: + return ( Name == p.Name ) && ( MultiTap == p.MultiTap ); + } + + + public override int GetHashCode( ) + { + return Name.GetHashCode( ) ^ MultiTap.GetHashCode( ); + } + + }// end class + + /// /// Contains the ActivationMode from SC @@ -12,29 +168,87 @@ namespace SCJMapper_V2 /// "Default" using the defActivationMode setting of the profile /// any of the List of profileDefined ones /// - class ActivationModes : List + public sealed class ActivationModes : List { + private static readonly ActivationModes instance = new ActivationModes( ActivationMode.Default ); - public const String Default = "Use Profile"; - /// - /// cTor: create a default one - with one Default element preset - /// - public ActivationModes( ) + public static ActivationModes Instance { - this.Add( Default ); // this is always in.. + get + { + return instance; + } } + + /// + /// cTor: Empty - hidden + /// + private ActivationModes( ) { } + /// /// cTor: create one with a first item only /// /// - public ActivationModes( string firstItem ) + public ActivationModes( ActivationMode firstItem ) { this.Clear( ); this.Add( firstItem ); } + /// + /// Returns the multitap number for an item + /// + /// + /// + public int MultiTapFor( string actModeName ) + { + try { + ActivationMode fAm = this.Find( am => am.Name == actModeName ); + return fAm.MultiTap; + } + catch { + return 1; + } + } + + + /// + /// Returns the list of ActivationMode names + /// + /// A list of names + public List Names + { + get + { + ListretVal = new List(); + foreach ( ActivationMode am in this ) retVal.Add( am.Name ); + return retVal; + } + } + + + /// + /// Returns a new instance from given name from the list + /// Or Default if not found + /// + /// The activationMode to get + /// A new ActivationMode instance + public ActivationMode ActivationModeByName( string actModeName ) + { + try { + ActivationMode fAm = this.Find( am => am.Name == actModeName ); + return new ActivationMode( fAm ); + } + catch { + return new ActivationMode( ); + } + } + + + + } } diff --git a/SC/DProfileReader.cs b/SC/DProfileReader.cs index 9411fe5..3a2fc84 100644 --- a/SC/DProfileReader.cs +++ b/SC/DProfileReader.cs @@ -34,8 +34,10 @@ namespace SCJMapper_V2 public String devID { get; set; } // the input method K,J,X,P private String m_defBinding = ""; // NOTE: this is AC1 style in the Profile - need to conver later when dumping out public String defBinding { get { return m_defBinding; } set { m_defBinding = value; } } // DONT! need to clean this one, found spaces... - private String m_defActivationMode = ""; - public String defActivationMode { get { return m_defActivationMode; } set { m_defActivationMode = value; } } + + private ActivationMode m_defActivationMode = ActivationMode.Default; + public ActivationMode defActivationMode { get { return m_defActivationMode; } set { m_defActivationMode = value; } } + public String keyName { get { return devID + name; } } // prep for TreView usage - create a key from input+name } @@ -47,9 +49,7 @@ namespace SCJMapper_V2 }; Dictionary m_aMap = null; // key would be the actionmap name ActionMap m_currentMap = null; - - ActivationModes m_activationModes = new ActivationModes(); - public ActivationModes ActivationModes { get { return m_activationModes; } } + // ****************** CLASS ********************** @@ -77,7 +77,7 @@ namespace SCJMapper_V2 foreach ( ActionMap am in m_aMap.Values ) { buf += am.name + ";"; foreach ( ProfileAction a in am ) { - buf += a.keyName + ";" + a.defBinding + ";" + a.defActivationMode + ";"; // add default binding + activation mode to the CSV + buf += a.keyName + ";" + a.defBinding + ";" + a.defActivationMode.Name + ";" + a.defActivationMode.MultiTap.ToString() + ";"; // add default binding + activation mode to the CSV } buf += String.Format( "\n" ); } @@ -94,10 +94,24 @@ namespace SCJMapper_V2 private void CollectActions( Dictionary attr ) { //first find an ActivationMode if there is - applies to all actions - String actMode = ActivationModes.Default; + string actModeName = ActivationMode.Default.Name; + string multiTap = "0"; + + // this can be an Activation Mode OR a multitap + // if there is an activationMode the multiTap remains 0 + // if no ActivationMode is given, multitap is 1 or may be 2... if ( attr.ContainsKey( "ActivationMode" ) ) { - actMode = attr["ActivationMode"]; + actModeName = attr["ActivationMode"]; + multiTap = ActivationModes.Instance.MultiTapFor( actModeName ).ToString( ); // given by the already collected items + } + else { + // name remains default - we handle multiTaps only here + multiTap = "1"; // default if not changed in the action to may be 2 or so.. + if ( attr.ContainsKey( "multiTap" ) ) { + multiTap = attr["multiTap"]; + } } + ActivationMode actMode = new ActivationMode(actModeName, int.Parse(multiTap) ); // should be a valid ActivationMode for this action // we collect actions for each input ie for K,J,X and M if ( attr.ContainsKey( "joystick" ) ) { @@ -376,7 +390,8 @@ namespace SCJMapper_V2 break; // finished } String name = xr["name"]; - if ( ! string.IsNullOrEmpty(name)) m_activationModes.Add( name ); + String mTap = xr["multiTap"]; + if ( ! string.IsNullOrEmpty(name)) ActivationModes.Instance.Add( new ActivationMode( name, int.Parse(mTap) ) ); } while ( xr.Read( ) ); return true; @@ -406,7 +421,9 @@ namespace SCJMapper_V2 m_nodeNameStack = new Stack( ); m_aMap = new Dictionary( ); - m_activationModes = new ActivationModes( ); + // init the activation modes singleton + ActivationModes.Instance.Clear( ); + ActivationModes.Instance.Add( ActivationMode.Default ); ValidContent = true; // init reader.Read( ); diff --git a/SC/SCDefaultProfile.cs b/SC/SCDefaultProfile.cs index 8bebd3f..c429fac 100644 --- a/SC/SCDefaultProfile.cs +++ b/SC/SCDefaultProfile.cs @@ -29,7 +29,7 @@ namespace SCJMapper_V2 /// /// Returns the sought default profile as string from GameData.pak /// - /// The filename of the profile to be extracted + /// The filename of the profile to be extracted /// A string containing the file contents static public String DefaultProfile( String defaultProfileName ) { @@ -38,8 +38,8 @@ namespace SCJMapper_V2 String retVal = ""; // first choice a defaultProfile.xml in the app dir distributed with the application ??? to be deleted ??? - if ( File.Exists( SCPath.DefaultProfileName + ".xml" ) ) { - using ( StreamReader sr = new StreamReader( SCPath.DefaultProfileName + ".xml" ) ) { + if ( File.Exists( SCPath.DefaultProfileName ) ) { + using ( StreamReader sr = new StreamReader( SCPath.DefaultProfileName ) ) { retVal = sr.ReadToEnd( ); log.Info( "- Use AppDirectory defaultProfile" ); } diff --git a/SC/SCMappings.cs b/SC/SCMappings.cs index 64d41dc..b5e3144 100644 --- a/SC/SCMappings.cs +++ b/SC/SCMappings.cs @@ -75,6 +75,9 @@ namespace SCJMapper_V2 m_scMappings.Clear( ); m_scMappings = ( List )Directory.EnumerateFiles( SCPath.SCClientMappingPath ).ToList( ); } + else { + log.Warn( "UpdateMappingNames - cannot find SC Mapping directory" ); + } } @@ -88,13 +91,7 @@ namespace SCJMapper_V2 { log.Debug( "MappingNames - Entry" ); if ( m_scMappings.Count == 0 ) { - if ( Directory.Exists( SCPath.SCClientMappingPath ) ) { - m_scMappings.Clear( ); - m_scMappings = ( List )Directory.EnumerateFiles( SCPath.SCClientMappingPath ).ToList( ); - } - } - else { - log.Warn( "MappingNames - cannot find SC Mapping directory" ); + UpdateMappingNames( ); } return m_scMappings; } diff --git a/SC/SCPath.cs b/SC/SCPath.cs index 81825c0..282ca49 100644 --- a/SC/SCPath.cs +++ b/SC/SCPath.cs @@ -126,6 +126,7 @@ namespace SCJMapper_V2 if ( appSettings.UserSCPathUsed ) { // User has priority scp = appSettings.UserSCPath; + log.InfoFormat( "SCBasePath - user defined folder given: {0}", scp ); if ( !Directory.Exists( scp ) ) { log.WarnFormat( "SCBasePath - user defined folder does not exist: {0}", scp ); return ""; // sorry path does not exist diff --git a/SCJMapper-V2.csproj b/SCJMapper-V2.csproj index 1e099f9..efaf71e 100644 --- a/SCJMapper-V2.csproj +++ b/SCJMapper-V2.csproj @@ -26,8 +26,8 @@ false false true - 50 - 2.17.0.%2a + 51 + 2.18.0.%2a false true diff --git a/actions/ActionCls.cs b/actions/ActionCls.cs index 5ee6631..b008af5 100644 --- a/actions/ActionCls.cs +++ b/actions/ActionCls.cs @@ -128,6 +128,9 @@ namespace SCJMapper_V2 { Boolean blendedInput = false; + blendedInput = DeviceCls.IsBlendedInput( input ); // generic + if ( blendedInput ) return blendedInput; + blendedInput = JoystickCls.IsBlendedInput( input ); if ( blendedInput ) return blendedInput; blendedInput = GamepadCls.IsBlendedInput( input ); @@ -167,7 +170,7 @@ namespace SCJMapper_V2 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 String defActivationMode { get; set; } // the default binding ActivationMode (can be "" if not used) + public ActivationMode defActivationMode { get; set; } // the default binding ActivationMode public List inputList { get; set; } // regular bind is the 0-element, addbinds are added to the list /// @@ -180,7 +183,7 @@ namespace SCJMapper_V2 device = JoystickCls.DeviceClass; name = ""; defBinding = ""; - defActivationMode = ""; + defActivationMode = ActivationMode.Default; inputList = new List( ); // empty list } @@ -211,22 +214,16 @@ namespace SCJMapper_V2 /// - /// Created and adds the inputCommand list with given input string + /// Creates and adds the inputCommand list with given input string /// AC2 style input is used i.e. with device tag in front /// apply given ActivationMode - can be "~" to indicate DONT APPLY /// /// /// Returns the ActionCommand created - public ActionCommandCls AddCommand( String devInput, String activationMode ) + public ActionCommandCls AddCommand( String devInput, ActivationMode activationMode ) { ActionCommandCls acc = new ActionCommandCls( devInput, inputList.Count - 1 ); // starts from -1 ... - if ( activationMode == "~" ) { - // not assigned - acc.ActivationMode = ""; - } - else { - acc.ActivationMode = activationMode; - } + acc.ActivationMode = activationMode; inputList.Add( acc ); return acc; } @@ -241,7 +238,7 @@ namespace SCJMapper_V2 public ActionCommandCls AddCommand( String devInput, int index ) { ActionCommandCls acc = new ActionCommandCls( devInput, index ); - acc.ActivationMode = defActivationMode; + acc.ActivationMode = ActivationMode.Default; inputList.Add( acc ); return acc; } @@ -284,8 +281,8 @@ namespace SCJMapper_V2 // Apply the input to the ActionTree actionCmd.DevInput = BlendInput( devInput, this.actionDevice ); - if ( string.IsNullOrEmpty( actionCmd.Input)) { - actionCmd.ActivationMode = defActivationMode; // reset activation mode if the input is empty + if ( IsBlendedInput( actionCmd.DevInput ) ) { + actionCmd.ActivationMode = ActivationMode.Default; // reset activation mode if the input is empty } } @@ -394,13 +391,27 @@ namespace SCJMapper_V2 else if ( MouseCls.IsDeviceClass( device ) ) input = MouseCls.FromAC1( input ); else if ( GamepadCls.IsDeviceClass( device ) ) input = GamepadCls.FromAC1( input ); } - // Get default ActivationMode - String activationMode = reader["ActivationMode"]; - if ( string.IsNullOrEmpty(activationMode)) activationMode = ActivationModes.Default; // MARK AS NOT USED + //first find an ActivationMode if there is - applies to all actions + // this can be an Activation Mode OR a multitap + // if there is an activationMode - copy the one from our List + // if no ActivationMode is given, create one with multitap 1 or may be 2... + string actModeName = reader["ActivationMode"]; + ActivationMode actMode = null; + if ( ! string.IsNullOrEmpty( actModeName ) ) { + actMode = ActivationModes.Instance.ActivationModeByName( actModeName ); // should be a valid ActivationMode for this action + } + else { + actMode = new ActivationMode( ActivationMode.Default ); // no specific name given, use default + string multiTap = reader["multiTap"]; + if ( !string.IsNullOrEmpty( multiTap ) ) { + actMode.MultiTap = int.Parse(multiTap); // modify with given multiTap + } + } key = DevID( device ) + name; // unique id of the action actionDevice = ADevice( device ); // get the enum of the input device - AddCommand( input, activationMode ); + + AddCommand( input, actMode ); // advances the reader to the next node reader.ReadStartElement( "rebind" ); } @@ -421,9 +432,23 @@ namespace SCJMapper_V2 else if ( MouseCls.IsDeviceClass( device ) ) input = MouseCls.FromAC1( input ); else if ( GamepadCls.IsDeviceClass( device ) ) input = GamepadCls.FromAC1( input ); } - String activationMode = reader["ActivationMode"]; - if ( string.IsNullOrEmpty( activationMode ) ) activationMode = ActivationModes.Default; // MARK AS NOT USED - AddCommand( input, activationMode ); + //first find an ActivationMode if there is - applies to all actions + // this can be an Activation Mode OR a multitap + // if there is an activationMode - copy the one from our List + // if no ActivationMode is given, create one with multitap 1 or may be 2... + string actModeName = reader["ActivationMode"]; + ActivationMode actMode = null; + if ( !string.IsNullOrEmpty( actModeName ) ) { + actMode = ActivationModes.Instance.ActivationModeByName( actModeName ); // should be a valid ActivationMode for this action + } + else { + actMode = new ActivationMode( ActivationMode.Default ); // no specific name given, use default + string multiTap = reader["multiTap"]; + if ( !string.IsNullOrEmpty( multiTap ) ) { + actMode.MultiTap = int.Parse( multiTap ); // modify with given multiTap + } + } + AddCommand( input, actMode ); // advances the reader to the next node reader.ReadStartElement( "addbind" ); } diff --git a/actions/ActionCommandCls.cs b/actions/ActionCommandCls.cs index a867766..3506246 100644 --- a/actions/ActionCommandCls.cs +++ b/actions/ActionCommandCls.cs @@ -27,7 +27,7 @@ namespace SCJMapper_V2 /// /// The applied ActivationMode for this command /// - public String ActivationMode { get; set; } // "" or one of the defined ActivationModes + public ActivationMode ActivationMode { get; set; } // "" or one of the defined ActivationModes /// @@ -76,7 +76,7 @@ namespace SCJMapper_V2 // init with something to debug if needed Input = "UNDEF"; DevID = "NA0"; - ActivationMode = ""; + ActivationMode = ActivationMode.Default; NodeIndex = -1; } @@ -93,7 +93,7 @@ namespace SCJMapper_V2 public ActionCommandCls( String devInp ) { DevInput = devInp; - ActivationMode = ""; + ActivationMode = ActivationMode.Default; NodeIndex = -1; } @@ -101,7 +101,7 @@ namespace SCJMapper_V2 public ActionCommandCls( String devInp, int nodeIx ) { DevInput = devInp; - ActivationMode = ""; + ActivationMode = ActivationMode.Default; NodeIndex = nodeIx; } @@ -110,7 +110,7 @@ namespace SCJMapper_V2 { Input = inp; DevID = dev; - ActivationMode = ""; + ActivationMode = ActivationMode.Default; NodeIndex = -1; } @@ -119,7 +119,7 @@ namespace SCJMapper_V2 { Input = inp; DevID = dev; - ActivationMode = ""; + ActivationMode = ActivationMode.Default; NodeIndex = nodeIx; } @@ -150,14 +150,13 @@ namespace SCJMapper_V2 /// /// /// - private String MutitapFudge( string actMode ) + private String MutitapFudge( ActivationMode actMode ) { - // guesswork - if the activation mode name contains double we assume a double tap thing - if ( actMode.ToLowerInvariant( ).Contains( "double" ) ) { - return "multitap = \"2\""; + if ( actMode.IsDoubleTap ) { + return "multiTap = \"2\""; } else { - return "multitap = \"1\""; + return "multiTap = \"1\""; } } @@ -170,9 +169,9 @@ namespace SCJMapper_V2 String r = ""; if ( !String.IsNullOrEmpty( Input ) ) { // regular - apply XML formatting to internally blended items - r += String.Format( "input=\"{0}_{1}\" ", DevID, DeviceCls.toXML( Input ) ); - if ( ActivationMode != ActivationModes.Default ) { - r += String.Format( "ActivationMode=\"{0}\" {1} ", ActivationMode, MutitapFudge(ActivationMode) ); + r += String.Format( "input=\"{0}_{1}\" {2} ", DevID, DeviceCls.toXML( Input ), DeviceCls.toXMLBlendExtension(Input) ); // add multitap override if needed + if ( ! ActivationMode.Equals( ActivationMode.Default ) ) { + r += String.Format( "ActivationMode=\"{0}\" {1} ", ActivationMode.Name, MutitapFudge(ActivationMode) ); } } r += String.Format( " />\n" ); diff --git a/actions/ActionTree.cs b/actions/ActionTree.cs index 97f7215..141ca9d 100644 --- a/actions/ActionTree.cs +++ b/actions/ActionTree.cs @@ -16,9 +16,7 @@ namespace SCJMapper_V2 { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType ); - public ActionMapsCls ActionMaps { get; set; } // the Action Maps and Actions - public ActivationModes ActivationModes { get; set; } // the ActivationModes found in Profile private TreeView m_MasterTree = new TreeView( ); // the master TreeView (mem only) private TreeView m_ctrl = null; // the TreeView in the GUI - injected from GUI via Ctrl property @@ -65,7 +63,6 @@ namespace SCJMapper_V2 m_gamepad = gamepad; IgnoreMaps = ""; // nothing to ignore - ActivationModes = new ActivationModes( ); // an empty list for now } @@ -150,6 +147,19 @@ namespace SCJMapper_V2 } + public Boolean ShowAction( ActionCls.ActionDevice actDev, string input ) + { + if ( ActionCls.IsBlendedInput( input ) && m_showMappedOnly ) return false; + switch ( actDev ) { + case ActionCls.ActionDevice.AD_Gamepad: return m_showGameP; + case ActionCls.ActionDevice.AD_Joystick: return m_showJoy; + case ActionCls.ActionDevice.AD_Keyboard: return m_showKbd; + case ActionCls.ActionDevice.AD_Mouse: return m_showMouse; + default: return false; + } + } + + #endregion /// @@ -404,7 +414,7 @@ namespace SCJMapper_V2 /// /// Load Mappings into the ActionList and create the Master TreeView /// - /// The name of the profile to load (w/o extension) + /// The name of the profile to load (w extension) /// True if default mappings should be carried on public void LoadProfileTree( String defaultProfileName, Boolean applyDefaults ) { @@ -420,18 +430,15 @@ namespace SCJMapper_V2 ActionCommandCls acc = null; ActionMaps = new ActionMapsCls( m_jsList ); - ActivationModes = new ActivationModes( ); m_MasterTree.Nodes.Clear( ); // read the action items into the TreeView DProfileReader dpReader = new DProfileReader( ); // we may read a profile TextReader txReader = null; - dpReader.fromXML( SCDefaultProfile.DefaultProfile( defaultProfileName + ".xml" ) ); + dpReader.fromXML( SCDefaultProfile.DefaultProfile( defaultProfileName ) ); if ( dpReader.ValidContent ) { txReader = new StringReader( dpReader.CSVMap ); - ActivationModes.Clear( ); - ActivationModes.AddRange( dpReader.ActivationModes ); // content copy from profile } // we assume no addbind items in the profile @@ -447,12 +454,16 @@ namespace SCJMapper_V2 Array.Resize( ref cnl, 0 ); acm = new ActionMapCls( ); acm.name = elem[0]; // get actionmap name // process items - for ( int ei = 1; ei < elem.Length; ei += 3 ) { // step 2 - action;defaultBinding;defaultActivationMode come in as tripples + for ( int ei = 1; ei < elem.Length; ei += 4 ) { // step 2 - action;defaultBinding;defaultActivationMode;defMultiTap come in as quadrupples if ( !String.IsNullOrEmpty( elem[ei] ) ) { // default assignments String action = elem[ei].Substring( 1 ); String defBinding = elem[ei + 1]; - String defActivationMode = elem[ei + 2]; + string defActivationModeName = elem[ei + 2]; + int defMultiTap = int.Parse( elem[ei + 3] ); + // need to create a ActivationMode here + ActivationMode defActivationMode = new ActivationMode( defActivationModeName, defMultiTap ); + String devID = elem[ei].Substring( 0, 1 ); String device = ActionCls.DeviceFromID( devID ); @@ -476,7 +487,6 @@ namespace SCJMapper_V2 if ( applyDefaults ) { if ( JoystickCls.IsJSValid( jNum ) ) { acc.DevInput = ac.defBinding; - acc.ActivationMode = ac.defActivationMode; cn.Command = ac.defBinding; cn.BackColor = JoystickCls.JsNColor( jNum ); } } @@ -486,7 +496,6 @@ namespace SCJMapper_V2 if ( applyDefaults ) { if ( !String.IsNullOrEmpty( ac.defBinding ) ) { acc.DevInput = ac.defBinding; - acc.ActivationMode = ac.defActivationMode; cn.Command = ac.defBinding; cn.BackColor = GamepadCls.XiColor( ); } } @@ -496,7 +505,6 @@ namespace SCJMapper_V2 if ( applyDefaults ) { if ( !String.IsNullOrEmpty( ac.defBinding ) ) { acc.DevInput = ac.defBinding; - acc.ActivationMode = ac.defActivationMode; cn.Command = ac.defBinding; cn.BackColor = KeyboardCls.KbdColor( ); } } @@ -506,7 +514,6 @@ namespace SCJMapper_V2 if ( applyDefaults ) { if ( !String.IsNullOrEmpty( ac.defBinding ) ) { acc.DevInput = ac.defBinding; - acc.ActivationMode = ac.defActivationMode; cn.Command = ac.defBinding; cn.BackColor = MouseCls.MouseColor( ); } } @@ -543,11 +550,12 @@ namespace SCJMapper_V2 /// - /// Find the ActivationMode of the selected item + /// Find the ActivationModes of the selected item /// + /// A ActivationModes list - first element is the default, second the selected Mode public ActivationModes ActivationModeSelectedItem( ) { - ActivationModes am = new ActivationModes(); am.Add( ActivationModes.Default ); // dummy answer Default is Default and selected is Default + ActivationModes am = new ActivationModes( ActivationMode.Default ); am.Add( ActivationMode.Default );// dummy answer Default is Default and selected is Default if ( ( Ctrl.SelectedNode.Level == 0 ) || ( Ctrl.SelectedNode.Level > 2 ) ) return am; if ( Ctrl.SelectedNode == null ) return am; // ERROR exit @@ -578,10 +586,8 @@ namespace SCJMapper_V2 /// /// Update the ActivationMode of the selected item /// - public void UpdateActivationModeSelectedItem( string newActivationMode ) + public void UpdateActivationModeSelectedItem( string newActivationModeName ) { - ActivationModes am = new ActivationModes(); am.Add( ActivationModes.Default ); // dummy answer Default is Default and selected is Default - if ( ( Ctrl.SelectedNode.Level == 0 ) || ( Ctrl.SelectedNode.Level > 2 ) ) return; if ( Ctrl.SelectedNode == null ) return; // ERROR exit if ( Ctrl.SelectedNode.Parent == null ) return; // ERROR exit @@ -591,7 +597,14 @@ namespace SCJMapper_V2 // this is the main node with Action Cmd ActionCls ac = FindActionObject( Ctrl.SelectedNode.Parent.Name, Ctrl.SelectedNode.Name ); if ( ac == null ) return; // ERROR exit ActionCommandCls acc = ac.FindActionInputObject( CommandFromNodeText( Ctrl.SelectedNode.Text ) ); if ( acc == null ) return; // ERROR exit - acc.ActivationMode = newActivationMode; + // new am is either a named one or the Default from Profile (which is the default from the Action due to multiTaps..) + if ( ActivationMode.IsDefault( newActivationModeName ) ) { + acc.ActivationMode = ActivationMode.Default; + } + else { + acc.ActivationMode = ActivationModes.Instance.ActivationModeByName( newActivationModeName ); + } + Dirty = true; } else if ( Ctrl.SelectedNode.Level == 2 ) { @@ -600,7 +613,13 @@ namespace SCJMapper_V2 // the related action ActionCls ac = FindActionObject( atn.Parent.Name, atn.Name ); if ( ac == null ) return; // ERROR exit ActionCommandCls acc = ac.FindActionInputObject( m_ctrl.SelectedNode.Index ); if ( acc == null ) return; // ERROR exit - acc.ActivationMode = newActivationMode; + // new am is either a named one or the Default from Profile (which is the default from the Action due to multiTaps..) + if ( ActivationMode.IsDefault( newActivationModeName ) ) { + acc.ActivationMode = ActivationMode.Default; + } + else { + acc.ActivationMode = ActivationModes.Instance.ActivationModeByName( newActivationModeName ); + } Dirty = true; } } @@ -1085,19 +1104,38 @@ namespace SCJMapper_V2 if ( !String.IsNullOrEmpty( ActionMaps.jsN[i] ) ) repList += String.Format( "** js{0} = {1}\n", i + 1, ActionMaps.jsN[i] ); } // now the mapped actions + const int padAction = 42; + const int padInput = 25; + repList += String.Format( "\n" ); + repList += String.Format( " {0}+= {1} _ {2}+=[{4}] {3}\n\n", "Action".PadRight( padAction ), "Dev", "Binding".PadRight( padInput ), "Activation", "T" ); // col description line + foreach ( ActionMapCls acm in ActionMaps ) { String rep = String.Format( "*** {0}\n", acm.name ); repList += rep; foreach ( ActionCls ac in acm ) { foreach ( ActionCommandCls acc in ac.inputList ) { - if ( !String.IsNullOrEmpty( acc.Input ) && !( acc.Input == DeviceCls.BlendedInput ) ) { - rep = String.Format( " {0} - {1} - {2}\n", ac.name.PadRight( 42 ), acc.DevID, acc.Input.PadRight( 30 ) ); - repList += rep; + if ( ShowAction( ac.actionDevice, acc.Input ) ) { + if ( !String.IsNullOrEmpty( acc.Input ) /* && !( acc.Input == DeviceCls.BlendedInput )*/ ) { + if ( acc.DevInput == ac.defBinding ) { + rep = String.Format( " {0} = {1} _ {2}", ac.name.PadRight( padAction ), acc.DevID, acc.Input.PadRight( padInput ) ); + } + else { + rep = String.Format( " {0} + {1} _ {2}", ac.name.PadRight( padAction ), acc.DevID, acc.Input.PadRight( padInput ) ); // my binding + } + if ( acc.ActivationMode == ActivationMode.Default ) { + rep += String.Format( " = [{1}] {0}\n", ac.defActivationMode.Name, ac.defActivationMode.MultiTap ); + } + else { + rep += String.Format( " + [{1}] {0}\n", acc.ActivationMode.Name, acc.ActivationMode.MultiTap ); + } + + repList += rep; + } } } } - repList += String.Format( "\n" ); + repList += String.Format( "\n" ); // actionmap spacer } return repList; } diff --git a/doc/ReadMe.txt b/doc/ReadMe.txt index 49a393f..088f0e5 100644 --- a/doc/ReadMe.txt +++ b/doc/ReadMe.txt @@ -1,10 +1,10 @@ -SC Joystick Mapper V 2.17 - Build 50 BETA -(c) Cassini, StandardToaster - 28-December-2015 +SC Joystick Mapper V 2.18 - Build 51 BETA +(c) Cassini, StandardToaster - 02-January-2016 Contains 9 files: -SCJMapper.exe The program (V2.17) -SCJMapper.exe.config Program config (V2.17) - MUST be in the same folder as the Exe file +SCJMapper.exe The program (V2.18) +SCJMapper.exe.config Program config (V2.18) - MUST be in the same folder as the Exe file SharpDX.DirectInput.dll Managed DirectInput Assembly - MUST be in the same folder as the Exe file SharpDX.dll Managed DirectX Assembly - MUST be in the same folder as the Exe file OpenTK.dll Managed OpenGL Assembly - MUST be in the same folder as the Exe file @@ -13,7 +13,7 @@ Ionic.Zip.Reduced.dll Managed Zip Assembly - MUST be in th log4net.dll Managed Logging Assembly - MUST be in the same folder as the Exe file log4net.config.OFF Config file for logging - To use it - rename as log4net.config and run the program then look for trace.log in the same folder -SCJMapper_QGuide V2.17.pdf Quick Guide +SCJMapper_QGuide V2.18beta.pdf Quick Guide ReadMe.txt This file graphics folder Skybox Images - graphics folder MUST be in the same folder as the Exe file @@ -29,6 +29,15 @@ Scanned for viruses before packing... cassini@burri-web.org Changelog: +V 2.18 - BETA Build 51 +- fix - layout works now for Win10 +- fix - uses game defaultProfile +- improvement - timeout for kbd modifiers (Esc no longer needed) +- improvement - ActivationMode handling +- improvement - Blending adds multiTap=1 +- improvement - List commands; added Act.Modes +- update - doc SCJMapper_QGuide V2.18beta.pdf +- Known Issue: Some Ctrl-keyboard commands are not shown (Ctrl Sequences) V 2.17 - BETA Build 50 - update - Updated for SC Alpha 2.0/2.1PTU using new actionmap syntax (no longer use device attribute) - update - Complete new QuickReference Guide diff --git a/doc/SCJMapper_QGuide V2.18beta.pdf b/doc/SCJMapper_QGuide V2.18beta.pdf new file mode 100644 index 0000000..b247ff5 Binary files /dev/null and b/doc/SCJMapper_QGuide V2.18beta.pdf differ diff --git a/doc/SCJMapper_QGuide V2.x.pub b/doc/SCJMapper_QGuide V2.x.pub index 4dc9d86..52e43cd 100644 Binary files a/doc/SCJMapper_QGuide V2.x.pub and b/doc/SCJMapper_QGuide V2.x.pub differ