V 2.23 - BETA Build 57

- update - Using .Net 4.5.2 Now (seems to handle some scaling issues WinForm apps)
- update - Try to find the SC path also as StarCitizen\Live (instead of Public) was mentioned for SC2.2.2 onwards ???
- fix - addbind UNDEF removed when assigned
- improvement - Issue a infobox if the Client folder cannot be found
               (please submit the complete folder structure of your installation as bug report ...)
- add - a table display for mappings
- some internal stuff (namespaces etc)
- update - doc SCJMapper_QGuide V2.23beta.pdf
pull/104/head
bm98 8 years ago
parent 9d4c71db51
commit ac0ca1c208

Binary file not shown.

@ -264,6 +264,35 @@ namespace SCJMapper_V2
}
//**** Form Table
// Control bound settings
[UserScopedSettingAttribute( )]
[DefaultSettingValueAttribute( "1000, 900" )]
public Size FormTableSize
{
get { return ( Size )this["FormTableSize"]; }
set { this["FormTableSize"] = value; }
}
[UserScopedSettingAttribute( )]
[DefaultSettingValueAttribute( "760, 320" )]
public Point FormTableLocation
{
get { return ( Point )this["FormTableLocation"]; }
set { this["FormTableLocation"] = value; }
}
[UserScopedSettingAttribute( )]
[DefaultSettingValueAttribute( "" )]
public string FormTableColumnWidth
{
get { return ( string )this["FormTableColumnWidth"]; }
set { this["FormTableColumnWidth"] = value; }
}
#endregion

44
Form1.Designer.cs generated

@ -15,7 +15,7 @@
{
timer1.Stop( );
// Unacquire all DirectInput objects.
foreach ( JoystickCls js in m_Joystick ) js.FinishDX( );
foreach ( Joystick.JoystickCls js in m_Joystick ) js.FinishDX( );
m_Joystick.Clear( );
if ( disposing && ( components != null ) ) {
@ -85,7 +85,7 @@
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.UC_JoyPanel = new SCJMapper_V2.Joystick.UC_JoyPanel();
this.panel1 = new System.Windows.Forms.Panel();
this.btClip = new System.Windows.Forms.Button();
this.txRebind = new System.Windows.Forms.TextBox();
@ -101,6 +101,8 @@
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.btDumpLog = new System.Windows.Forms.Button();
this.btJSTuning = new System.Windows.Forms.Button();
this.btDumpProfile = new System.Windows.Forms.Button();
this.btTable = new System.Windows.Forms.Button();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.btSettings = new System.Windows.Forms.Button();
this.btJsReassign = new System.Windows.Forms.Button();
@ -145,7 +147,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.btDumpProfile = new System.Windows.Forms.Button();
this.cmCopyPaste.SuspendLayout();
this.panel2.SuspendLayout();
this.cmMouseEntry.SuspendLayout();
@ -801,6 +802,7 @@
this.tableLayoutPanel1.Controls.Add(this.btDumpLog, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.btJSTuning, 1, 3);
this.tableLayoutPanel1.Controls.Add(this.btDumpProfile, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.btTable, 1, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize;
this.tableLayoutPanel1.Location = new System.Drawing.Point(376, 648);
@ -831,9 +833,30 @@
this.btJSTuning.Name = "btJSTuning";
this.btJSTuning.Size = new System.Drawing.Size(120, 23);
this.btJSTuning.TabIndex = 17;
this.btJSTuning.Text = "Device Tuning";
this.btJSTuning.Text = "Device Tuning...";
this.btJSTuning.Click += new System.EventHandler(this.btJSTuning_Click);
//
// btDumpProfile
//
this.btDumpProfile.Location = new System.Drawing.Point(3, 93);
this.btDumpProfile.Name = "btDumpProfile";
this.btDumpProfile.Size = new System.Drawing.Size(120, 23);
this.btDumpProfile.TabIndex = 26;
this.btDumpProfile.Text = "Dump Profile -->";
this.btDumpProfile.UseVisualStyleBackColor = true;
this.btDumpProfile.Click += new System.EventHandler(this.btDumpProfile_Click);
//
// btTable
//
this.btTable.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btTable.Location = new System.Drawing.Point(171, 63);
this.btTable.Name = "btTable";
this.btTable.Size = new System.Drawing.Size(120, 24);
this.btTable.TabIndex = 27;
this.btTable.Text = "Toggle Table...";
this.btTable.UseVisualStyleBackColor = true;
this.btTable.Click += new System.EventHandler(this.btTable_Click);
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
@ -1326,16 +1349,6 @@
this.statusStrip1.TabIndex = 26;
this.statusStrip1.Text = "statusStrip1";
//
// btDumpProfile
//
this.btDumpProfile.Location = new System.Drawing.Point(3, 93);
this.btDumpProfile.Name = "btDumpProfile";
this.btDumpProfile.Size = new System.Drawing.Size(120, 23);
this.btDumpProfile.TabIndex = 26;
this.btDumpProfile.Text = "Dump Profile -->";
this.btDumpProfile.UseVisualStyleBackColor = true;
this.btDumpProfile.Click += new System.EventHandler(this.btDumpProfile_Click);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1411,7 +1424,7 @@
private System.Windows.Forms.ToolStripMenuItem tsiSaveAs;
private System.Windows.Forms.SaveFileDialog SFD;
private System.Windows.Forms.ImageList IL;
private UC_JoyPanel UC_JoyPanel;
private Joystick.UC_JoyPanel UC_JoyPanel;
private System.Windows.Forms.TableLayoutPanel tlpanel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
@ -1492,6 +1505,7 @@
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.Button btDumpProfile;
private System.Windows.Forms.Button btTable;
}
}

@ -10,6 +10,12 @@ using System.Windows.Forms;
using SharpDX.DirectInput;
using System.IO;
using SCJMapper_V2.SC;
using SCJMapper_V2.Table;
using SCJMapper_V2.Keyboard;
using SCJMapper_V2.Mouse;
using SCJMapper_V2.Gamepad;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
@ -60,8 +66,9 @@ namespace SCJMapper_V2
///</remarks>
private ActionTree m_AT = null;
private FormJSCalCurve JSCAL = null;
private OGL.FormJSCalCurve JSCAL = null;
private FormTable FTAB = null;
#region Tools section
@ -431,7 +438,6 @@ namespace SCJMapper_V2
}
}
m_AT.FilterTree( txFilter.Text );
}
@ -453,10 +459,10 @@ namespace SCJMapper_V2
try {
log.Debug( "Get Keyboard device" );
m_Keyboard = new KeyboardCls( new Keyboard( directInput ), this );
m_Keyboard = new KeyboardCls( new SharpDX.DirectInput.Keyboard( directInput ), this );
log.Debug( "Get Mouse device" );
m_Mouse = new MouseCls( new Mouse( directInput ), this );
m_Mouse = new MouseCls( new SharpDX.DirectInput.Mouse( directInput ), this );
}
catch ( Exception ex ) {
@ -488,7 +494,7 @@ namespace SCJMapper_V2
}
}
else {
jsDevice = new Joystick( directInput, instance.InstanceGuid );
jsDevice = new SharpDX.DirectInput.Joystick( directInput, instance.InstanceGuid );
log.DebugFormat( "Create the device interface for: {0}", jsDevice.Information.ProductName );
}
@ -665,6 +671,7 @@ namespace SCJMapper_V2
catch {
; // just ignore
}
UpdateTable( );
}
@ -698,6 +705,16 @@ namespace SCJMapper_V2
m_AppSettings.FormSize = this.Size;
m_AppSettings.FormLocation = this.Location;
if ( FTAB != null ) {
m_AppSettings.FormTableLocation = FTAB.LastLocation;
m_AppSettings.FormTableSize = FTAB.LastSize;
m_AppSettings.FormTableColumnWidth = FTAB.LastColSize;
FTAB.Close( );
FTAB = null;
}
m_AppSettings.Save( );
}
@ -799,6 +816,7 @@ namespace SCJMapper_V2
{
if ( m_AT.UpdateSelectedItem( JoystickCls.MakeThrottle( lblLastJ.Text, cbxThrottle.Checked ), InputMode, true ) ) {
if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor;
UpdateTableSelectedItem( );
}
else MySounds.PlayNotfound( );
}
@ -807,6 +825,7 @@ namespace SCJMapper_V2
{
if ( m_AT.CanBlendBinding ) {
m_AT.BlendBinding( );
UpdateTableSelectedItem( );
if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor;
}
else MySounds.PlayCannot( );
@ -816,6 +835,7 @@ namespace SCJMapper_V2
{
if ( m_AT.CanClearBinding || m_AT.CanBlendBinding ) {
m_AT.ClearBinding( );
UpdateTableSelectedItem( );
if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor;
}
else MySounds.PlayCannot( );
@ -929,6 +949,7 @@ namespace SCJMapper_V2
// start over
InitActionTree( false );
rtb.Text = "";
UpdateTable( );
}
private void resetDefaultsToolStripMenuItem_Click( object sender, EventArgs e )
@ -936,6 +957,7 @@ namespace SCJMapper_V2
// start over and if chosen, load defaults from SC game
InitActionTree( true );
rtb.Text = "";
UpdateTable( );
}
private void tsDDbtMappings_DropDownItemClicked( object sender, ToolStripItemClickedEventArgs e )
@ -1255,6 +1277,7 @@ namespace SCJMapper_V2
m_AT.IgnoreMaps = m_AppSettings.IgnoreActionmaps;
// and start over with an empty tree
InitActionTree( false );
UpdateTable( );
}
timer1.Enabled = true;
@ -1304,7 +1327,7 @@ namespace SCJMapper_V2
{
timer1.Enabled = false; // must be off while a modal window is shown, else DX gets crazy
JSCAL = new FormJSCalCurve( );
JSCAL = new OGL.FormJSCalCurve( );
// get current mapping from ActionMaps
String nodeText = "";
@ -1582,9 +1605,76 @@ namespace SCJMapper_V2
lblLastJ.Text = ctrl;
}
#endregion
#endregion
// Called when the table must be rebuild
private void UpdateTable( )
{
// only if needed
if ( ( FTAB != null ) && FTAB.Visible ) {
m_AT.ActionMaps.toDataSet( FTAB.DS_AMaps);
FTAB.Populate( );
}
}
// Called when an entry has been modified
private void UpdateTableSelectedItem( )
{
// only if needed
if ( ( FTAB != null ) && FTAB.Visible ) {
string actionID = m_AT.SelectedActionID;
m_AT.ActionMaps.updateDataSet( FTAB.DS_AMaps, actionID );
FTAB.UpdateRow( actionID );
}
}
// Show the Table Window
private void btTable_Click( object sender, EventArgs e )
{
if (FTAB == null ) {
FTAB = new FormTable( );
FTAB.EditActionEvent += FTAB_EditActionEvent;
FTAB.UpdateEditEvent += FTAB_UpdateEditEvent;
}
if ( FTAB.Visible ) {
m_AppSettings.FormTableSize = FTAB.LastSize;
m_AppSettings.FormTableLocation = FTAB.LastLocation;
m_AppSettings.FormTableColumnWidth = FTAB.LastColSize;
FTAB.Hide( );
} else {
FTAB.Show( );
FTAB.Size = m_AppSettings.FormTableSize;
FTAB.Location = m_AppSettings.FormTableLocation;
FTAB.LastColSize = m_AppSettings.FormTableColumnWidth;
UpdateTable( );
}
}
// called when the user clicks Update from the Table Window
private void FTAB_UpdateEditEvent( object sender, UpdateEditEventArgs e )
{
ActionTree newTree = m_AT.UpdateFromDataSet( FTAB.DS_AMaps );
// returns a null if no changes have been found
if ( newTree != null ) {
m_AT = newTree; // make it the valid one
m_AT.DefineShowOptions( cbxShowJoystick.Checked, cbxShowGamepad.Checked, cbxShowKeyboard.Checked, cbxShowMouse.Checked, cbxShowMappedOnly.Checked );
m_AT.ReloadTreeView( );
if ( m_AT.Dirty ) btDump.BackColor = MyColors.DirtyColor;
}
}
// called when the user if the TAB form wants to edit a row
private void FTAB_EditActionEvent( object sender, EditRowEventArgs e )
{
m_AT.FindAndSelectActionKey( e.Actionmap, e.Actionkey, e.Nodeindex );
}
}

@ -128,7 +128,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA6
EAAAAk1TRnQBSQFMAgEBCQEAAUgBEAFIAhABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA
EAAAAk1TRnQBSQFMAgEBCQEAAWABEAFgAhABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA
AUADAAEwAwABAQEAAQgGAAEMGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA
AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA
AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm
@ -470,6 +470,15 @@
x1//2Q==
</value>
</data>
<metadata name="OFD.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>133, 17</value>
</metadata>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>209, 17</value>
</metadata>
<metadata name="SFD.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>421, 17</value>
</metadata>
<data name="btSaveMyMapping.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
@ -542,15 +551,6 @@
Tesk88046SuRb2gfwdMB6S/DHs/UzS4d0QAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="OFD.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>133, 17</value>
</metadata>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>209, 17</value>
</metadata>
<metadata name="SFD.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>421, 17</value>
</metadata>
<data name="tsBtReset.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8

@ -8,7 +8,7 @@ using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
namespace SCJMapper_V2
namespace SCJMapper_V2.Gamepad
{
/// <summary>
/// Handles one JS device as DXInput device

@ -1,4 +1,4 @@
namespace SCJMapper_V2
namespace SCJMapper_V2.Gamepad
{
partial class UC_GpadPanel
{

@ -7,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Gamepad
{
public partial class UC_GpadPanel : UserControl
{

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
public class DeviceDeadzoneParameter
{

@ -5,7 +5,7 @@ using System.Text;
using System.Xml;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// set of parameters to tune the Joystick
@ -59,7 +59,7 @@ namespace SCJMapper_V2
m_type = m_device.DevClass;
m_devInstanceNo = ( m_device as JoystickCls ).JSAssignment;
}
else if ( GamepadCls.IsDeviceClass( m_device.DevClass ) ) {
else if ( Gamepad.GamepadCls.IsDeviceClass( m_device.DevClass ) ) {
m_type = m_device.DevClass;
m_devInstanceNo = 1; // supports ONE gamepad
}

@ -6,7 +6,7 @@ using System.Xml;
using System.IO;
using System.Xml.Linq;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// Maintains an Deviceoptions - something like:

@ -1,4 +1,4 @@
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
partial class FormReassign
{

@ -7,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
partial class FormReassign : Form
{

@ -8,7 +8,7 @@ using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// Handles one JS device as DXInput device
@ -322,7 +322,7 @@ namespace SCJMapper_V2
// ****************** CLASS *************************
private Joystick m_device;
private SharpDX.DirectInput.Joystick m_device;
private JoystickState m_state = new JoystickState( );
private JoystickState m_prevState = new JoystickState( );
@ -413,7 +413,7 @@ namespace SCJMapper_V2
/// <param name="device">A DXInput device</param>
/// <param name="hwnd">The WinHandle of the main window</param>
/// <param name="panel">The respective JS panel to show the properties</param>
public JoystickCls( Joystick device, Control hwnd, int joystickNum, UC_JoyPanel panel, int tabIndex )
public JoystickCls( SharpDX.DirectInput.Joystick device, Control hwnd, int joystickNum, UC_JoyPanel panel, int tabIndex )
{
log.DebugFormat( "JoystickCls ctor - Entry with {0}", device.Information.ProductName );

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
public class JoystickList : List<JoystickCls>
{

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
public struct JsReassingR
{

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Xml;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// Maintain actionmap Modifiers

@ -7,7 +7,7 @@ using System.IO;
using System.Xml.Linq;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// Maintains an Options - something like:

@ -5,7 +5,7 @@ using System.Text;
using System.Xml;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
public class OptionsInvert
{
@ -74,7 +74,7 @@ namespace SCJMapper_V2
m_type = m_device.DevClass;
m_devInstanceNo = ( m_device as JoystickCls ).JSAssignment;
}
else if ( GamepadCls.IsDeviceClass( m_device.DevClass ) ) {
else if ( Gamepad.GamepadCls.IsDeviceClass( m_device.DevClass ) ) {
m_type = m_device.DevClass;
m_devInstanceNo = 1; // supports ONE gamepad
}

@ -1,4 +1,4 @@
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
partial class UC_JoyPanel
{

@ -7,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
public partial class UC_JoyPanel : UserControl
{

@ -6,7 +6,7 @@ using System.Xml;
using System.IO;
using System.Xml.Linq;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// Maintains an CustomisationUIHeader - something like:

@ -5,7 +5,7 @@ using System.Text;
using OpenTK;
namespace SCJMapper_V2
namespace SCJMapper_V2.Joystick
{
/// <summary>
/// contains the x(in) and y(out) points of the nonlin curve for joysticks (MAX 3 interpolation pts)
@ -18,7 +18,7 @@ namespace SCJMapper_V2
private Vector2[] m_points = null;
private double[] m_outCurve = null;
private int m_Npoints = 0;
private CalcCurve m_curve;
private OGL.CalcCurve m_curve;
public xyPoints( int maxPoints )
{
@ -86,7 +86,7 @@ namespace SCJMapper_V2
Setup( 1 );
float[] cout = new float[m_maxpts * 2];
int resolution = m_maxpts; // The number of points in the bezier curve
m_curve = new BezierInterpolation( m_points, resolution );
m_curve = new OGL.BezierInterpolation( m_points, resolution );
Vector2 pos = Vector2.One;
for ( int p = 0; p <= resolution; p++ ) {
pos = m_curve.CalculatePoint( ( float )p / ( float )resolution );
@ -104,7 +104,7 @@ namespace SCJMapper_V2
float[] cout = new float[m_maxpts * 2];
int resolution = m_maxpts; // The number of points in the bezier curve
m_curve = new BezierInterpolation( m_points, resolution );
m_curve = new OGL.BezierInterpolation( m_points, resolution );
Vector2 pos = Vector2.One;
for ( int p = 0; p <= resolution; p++ ) {
pos = m_curve.CalculatePoint( ( float )p / ( float )resolution );
@ -123,7 +123,7 @@ namespace SCJMapper_V2
float[] cout = new float[m_maxpts * 2];
int resolution = m_maxpts; // The number of points in the bezier curve
m_curve = new BezierInterpolation( m_points, resolution );
m_curve = new OGL.BezierInterpolation( m_points, resolution );
Vector2 pos = Vector2.One;
for ( int p = 0; p <= resolution; p++ ) {
pos = m_curve.CalculatePoint( ( float )p / ( float )resolution );
@ -143,7 +143,7 @@ namespace SCJMapper_V2
float[] cout = new float[m_maxpts * 2];
int resolution = m_maxpts-1; // The number of points in the bezier curve
m_curve = new BezierInterpolation( m_points, resolution );
m_curve = new OGL.BezierInterpolation( m_points, resolution );
Vector2 pos = Vector2.One;
for ( int p = 0; p <= resolution; p++ ) {
pos = m_curve.CalculatePoint( ( float )p / ( float )resolution );

@ -7,7 +7,7 @@ using System.Windows.Forms;
using SharpDX;
using System.Text.RegularExpressions;
namespace SCJMapper_V2
namespace SCJMapper_V2.Keyboard
{
/// <summary>
/// Handles one Keyboard device as DXInput device
@ -244,7 +244,7 @@ namespace SCJMapper_V2
#endregion
private Keyboard m_device;
private SharpDX.DirectInput.Keyboard m_device;
private KeyboardState m_state = new KeyboardState( );
private Control m_hwnd;
@ -288,7 +288,7 @@ namespace SCJMapper_V2
/// </summary>
/// <param name="device">A DXInput device</param>
/// <param name="hwnd">The WinHandle of the main window</param>
public KeyboardCls( Keyboard device, Control hwnd )
public KeyboardCls( SharpDX.DirectInput.Keyboard device, Control hwnd )
{
log.DebugFormat( "KeyboardCls ctor - Entry with {0}", device.Information.ProductName );

@ -8,7 +8,7 @@ using SharpDX;
using System.Reflection;
using System.Text.RegularExpressions;
namespace SCJMapper_V2
namespace SCJMapper_V2.Mouse
{
/// <summary>
/// Handles one Mouse device as DXInput device
@ -120,7 +120,7 @@ namespace SCJMapper_V2
#endregion
private Mouse m_device;
private SharpDX.DirectInput.Mouse m_device;
private MouseState m_state = new MouseState( );
private MouseState m_prevState = new MouseState( );
@ -167,7 +167,7 @@ namespace SCJMapper_V2
/// </summary>
/// <param name="device">A DXInput device</param>
/// <param name="hwnd">The WinHandle of the main window</param>
public MouseCls( Mouse device, Control hwnd )
public MouseCls( SharpDX.DirectInput.Mouse device, Control hwnd )
{
log.DebugFormat( "MouseCls cTor - Entry with {0}", device.Information.ProductName );

@ -6,7 +6,7 @@ using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Forms;
using OpenTK;
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
public class BezierPointCollection : List<DataPoint>
{

@ -2,7 +2,7 @@
using OpenTK;
using System.Collections.Generic;
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
public abstract class CalcCurve
{

@ -27,59 +27,59 @@
using System;
using OpenTK;
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
/// <summary>
/// Cubic spline interpolation.
/// Call Fit (or use the corrector constructor) to compute spline coefficients, then Eval to evaluate the spline at other X coordinates.
/// </summary>
/// <remarks>
/// <para>
/// This is implemented based on the wikipedia article:
/// http://en.wikipedia.org/wiki/Spline_interpolation
/// I'm not sure I have the right to include a copy of the article so the equation numbers referenced in
/// comments will end up being wrong at some point.
/// </para>
/// <para>
/// This is not optimized, and is not MT safe.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </para>
/// </remarks>
public class CubicSpline
{
#region Fields
// N-1 spline coefficients for N points
private float[] a;
private float[] b;
// Save the original x and y for Eval
private float[] xOrig;
private float[] yOrig;
#endregion
#region Ctor
/// <summary>
/// Default ctor.
/// </summary>
public CubicSpline()
{
}
/// <summary>
/// Construct and call Fit.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
public CubicSpline(float[] x, float[] y, float startSlope = float.NaN, float endSlope = float.NaN, bool debug = false)
{
Fit(x, y, startSlope, endSlope );
}
/// <summary>
/// Cubic spline interpolation.
/// Call Fit (or use the corrector constructor) to compute spline coefficients, then Eval to evaluate the spline at other X coordinates.
/// </summary>
/// <remarks>
/// <para>
/// This is implemented based on the wikipedia article:
/// http://en.wikipedia.org/wiki/Spline_interpolation
/// I'm not sure I have the right to include a copy of the article so the equation numbers referenced in
/// comments will end up being wrong at some point.
/// </para>
/// <para>
/// This is not optimized, and is not MT safe.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </para>
/// </remarks>
public class CubicSpline
{
#region Fields
// N-1 spline coefficients for N points
private float[] a;
private float[] b;
// Save the original x and y for Eval
private float[] xOrig;
private float[] yOrig;
#endregion
#region Ctor
/// <summary>
/// Default ctor.
/// </summary>
public CubicSpline()
{
}
/// <summary>
/// Construct and call Fit.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
public CubicSpline(float[] x, float[] y, float startSlope = float.NaN, float endSlope = float.NaN, bool debug = false)
{
Fit(x, y, startSlope, endSlope );
}
/// <summary>
/// Construct and call Fit.
@ -106,161 +106,161 @@ namespace SCJMapper_V2
/// Throws if Fit has not been called.
/// </summary>
private void CheckAlreadyFitted( )
{
if (a == null) throw new Exception("Fit must be called before you can evaluate.");
}
private int _lastIndex = 0;
/// <summary>
/// Find where in xOrig the specified x falls, by simultaneous traverse.
/// This allows xs to be less than x[0] and/or greater than x[n-1]. So allows extrapolation.
/// This keeps state, so requires that x be sorted and xs called in ascending order, and is not multi-thread safe.
/// </summary>
private int GetNextXIndex(float x)
{
if (x < xOrig[_lastIndex])
{
throw new ArgumentException("The X values to evaluate must be sorted.");
}
while ((_lastIndex < xOrig.Length - 2) && (x > xOrig[_lastIndex + 1]))
{
_lastIndex++;
}
return _lastIndex;
}
/// <summary>
/// Evaluate the specified x value using the specified spline.
/// </summary>
/// <param name="x">The x value.</param>
/// <param name="j">Which spline to use.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
/// <returns>The y value.</returns>
private float EvalSpline(float x, int j)
{
float dx = xOrig[j + 1] - xOrig[j];
float t = (x - xOrig[j]) / dx;
float y = (1 - t) * yOrig[j] + t * yOrig[j + 1] + t * (1 - t) * (a[j] * (1 - t) + b[j] * t); // equation 9
return y;
}
#endregion
#region Fit*
/// <summary>
/// Fit x,y and then eval at points xs and return the corresponding y's.
/// This does the "natural spline" style for ends.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="xs">Input. X coordinates to evaluate the fitted curve at.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
/// <returns>The computed y values for each xs.</returns>
public float[] FitAndEval(float[] x, float[] y, float[] xs, float startSlope = float.NaN, float endSlope = float.NaN)
{
Fit(x, y, startSlope, endSlope);
return Eval(xs);
}
/// <summary>
/// Compute spline coefficients for the specified x,y points.
/// This does the "natural spline" style for ends.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
public void Fit(float[] x, float[] y, float startSlope = float.NaN, float endSlope = float.NaN)
{
if (Single.IsInfinity(startSlope) || Single.IsInfinity(endSlope))
{
throw new Exception("startSlope and endSlope cannot be infinity.");
}
// Save x and y for eval
this.xOrig = x;
this.yOrig = y;
int n = x.Length;
float[] r = new float[n]; // the right hand side numbers: wikipedia page overloads b
TriDiagonalMatrixF m = new TriDiagonalMatrixF(n);
float dx1, dx2, dy1, dy2;
// First row is different (equation 16 from the article)
if (float.IsNaN(startSlope))
{
dx1 = x[1] - x[0];
m.C[0] = 1.0f / dx1;
m.B[0] = 2.0f * m.C[0];
r[0] = 3 * (y[1] - y[0]) / (dx1 * dx1);
}
else
{
m.B[0] = 1;
r[0] = startSlope;
}
// Body rows (equation 15 from the article)
for (int i = 1; i < n - 1; i++)
{
dx1 = x[i] - x[i - 1];
dx2 = x[i + 1] - x[i];
m.A[i] = 1.0f / dx1;
m.C[i] = 1.0f / dx2;
m.B[i] = 2.0f * (m.A[i] + m.C[i]);
dy1 = y[i] - y[i - 1];
dy2 = y[i + 1] - y[i];
r[i] = 3 * (dy1 / (dx1 * dx1) + dy2 / (dx2 * dx2));
}
// Last row also different (equation 17 from the article)
if (float.IsNaN(endSlope))
{
dx1 = x[n - 1] - x[n - 2];
dy1 = y[n - 1] - y[n - 2];
m.A[n - 1] = 1.0f / dx1;
m.B[n - 1] = 2.0f * m.A[n - 1];
r[n - 1] = 3 * (dy1 / (dx1 * dx1));
}
else
{
m.B[n - 1] = 1;
r[n - 1] = endSlope;
}
// k is the solution to the matrix
float[] k = m.Solve(r);
// a and b are each spline's coefficients
this.a = new float[n - 1];
this.b = new float[n - 1];
for (int i = 1; i < n; i++)
{
dx1 = x[i] - x[i - 1];
dy1 = y[i] - y[i - 1];
a[i - 1] = k[i - 1] * dx1 - dy1; // equation 10 from the article
b[i - 1] = -k[i] * dx1 + dy1; // equation 11 from the article
}
}
#endregion
#region Eval*
{
if (a == null) throw new Exception("Fit must be called before you can evaluate.");
}
private int _lastIndex = 0;
/// <summary>
/// Find where in xOrig the specified x falls, by simultaneous traverse.
/// This allows xs to be less than x[0] and/or greater than x[n-1]. So allows extrapolation.
/// This keeps state, so requires that x be sorted and xs called in ascending order, and is not multi-thread safe.
/// </summary>
private int GetNextXIndex(float x)
{
if (x < xOrig[_lastIndex])
{
throw new ArgumentException("The X values to evaluate must be sorted.");
}
while ((_lastIndex < xOrig.Length - 2) && (x > xOrig[_lastIndex + 1]))
{
_lastIndex++;
}
return _lastIndex;
}
/// <summary>
/// Evaluate the specified x value using the specified spline.
/// </summary>
/// <param name="x">The x value.</param>
/// <param name="j">Which spline to use.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
/// <returns>The y value.</returns>
private float EvalSpline(float x, int j)
{
float dx = xOrig[j + 1] - xOrig[j];
float t = (x - xOrig[j]) / dx;
float y = (1 - t) * yOrig[j] + t * yOrig[j + 1] + t * (1 - t) * (a[j] * (1 - t) + b[j] * t); // equation 9
return y;
}
#endregion
#region Fit*
/// <summary>
/// Fit x,y and then eval at points xs and return the corresponding y's.
/// This does the "natural spline" style for ends.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="xs">Input. X coordinates to evaluate the fitted curve at.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
/// <returns>The computed y values for each xs.</returns>
public float[] FitAndEval(float[] x, float[] y, float[] xs, float startSlope = float.NaN, float endSlope = float.NaN)
{
Fit(x, y, startSlope, endSlope);
return Eval(xs);
}
/// <summary>
/// Compute spline coefficients for the specified x,y points.
/// This does the "natural spline" style for ends.
/// This can extrapolate off the ends of the splines.
/// You must provide points in X sort order.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <param name="debug">Turn on console output. Default is false.</param>
public void Fit(float[] x, float[] y, float startSlope = float.NaN, float endSlope = float.NaN)
{
if (Single.IsInfinity(startSlope) || Single.IsInfinity(endSlope))
{
throw new Exception("startSlope and endSlope cannot be infinity.");
}
// Save x and y for eval
this.xOrig = x;
this.yOrig = y;
int n = x.Length;
float[] r = new float[n]; // the right hand side numbers: wikipedia page overloads b
TriDiagonalMatrixF m = new TriDiagonalMatrixF(n);
float dx1, dx2, dy1, dy2;
// First row is different (equation 16 from the article)
if (float.IsNaN(startSlope))
{
dx1 = x[1] - x[0];
m.C[0] = 1.0f / dx1;
m.B[0] = 2.0f * m.C[0];
r[0] = 3 * (y[1] - y[0]) / (dx1 * dx1);
}
else
{
m.B[0] = 1;
r[0] = startSlope;
}
// Body rows (equation 15 from the article)
for (int i = 1; i < n - 1; i++)
{
dx1 = x[i] - x[i - 1];
dx2 = x[i + 1] - x[i];
m.A[i] = 1.0f / dx1;
m.C[i] = 1.0f / dx2;
m.B[i] = 2.0f * (m.A[i] + m.C[i]);
dy1 = y[i] - y[i - 1];
dy2 = y[i + 1] - y[i];
r[i] = 3 * (dy1 / (dx1 * dx1) + dy2 / (dx2 * dx2));
}
// Last row also different (equation 17 from the article)
if (float.IsNaN(endSlope))
{
dx1 = x[n - 1] - x[n - 2];
dy1 = y[n - 1] - y[n - 2];
m.A[n - 1] = 1.0f / dx1;
m.B[n - 1] = 2.0f * m.A[n - 1];
r[n - 1] = 3 * (dy1 / (dx1 * dx1));
}
else
{
m.B[n - 1] = 1;
r[n - 1] = endSlope;
}
// k is the solution to the matrix
float[] k = m.Solve(r);
// a and b are each spline's coefficients
this.a = new float[n - 1];
this.b = new float[n - 1];
for (int i = 1; i < n; i++)
{
dx1 = x[i] - x[i - 1];
dy1 = y[i] - y[i - 1];
a[i - 1] = k[i - 1] * dx1 - dy1; // equation 10 from the article
b[i - 1] = -k[i] * dx1 + dy1; // equation 11 from the article
}
}
#endregion
#region Eval*
/// <summary>
/// Evaluate the spline at the specified x coordinate.
@ -313,104 +313,104 @@ namespace SCJMapper_V2
}
/// <summary>
/// Evaluate (compute) the slope of the spline at the specified x coordinates.
/// This can extrapolate off the ends of the splines.
/// You must provide X's in ascending order.
/// The spline must already be computed before calling this, meaning you must have already called Fit() or FitAndEval().
/// </summary>
/// <param name="x">Input. X coordinates to evaluate the fitted curve at.</param>
/// <returns>The computed y values for each x.</returns>
public float[] EvalSlope(float[] x )
{
CheckAlreadyFitted();
int n = x.Length;
float[] qPrime = new float[n];
_lastIndex = 0; // Reset simultaneous traversal in case there are multiple calls
for (int i = 0; i < n; i++)
{
// Find which spline can be used to compute this x (by simultaneous traverse)
int j = GetNextXIndex(x[i]);
// Evaluate using j'th spline
float dx = xOrig[j + 1] - xOrig[j];
float dy = yOrig[j + 1] - yOrig[j];
float t = (x[i] - xOrig[j]) / dx;
// From equation 5 we could also compute q' (qp) which is the slope at this x
qPrime[i] = dy / dx
+ (1 - 2 * t) * (a[j] * (1 - t) + b[j] * t) / dx
+ t * (1 - t) * (b[j] - a[j]) / dx;
}
return qPrime;
}
#endregion
#region Static Methods
/// <summary>
/// Static all-in-one method to fit the splines and evaluate at X coordinates.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="xs">Input. X coordinates to evaluate the fitted curve at.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <returns>The computed y values for each xs.</returns>
public static float[] Compute(float[] x, float[] y, float[] xs, float startSlope = float.NaN, float endSlope = float.NaN )
{
CubicSpline spline = new CubicSpline();
return spline.FitAndEval(x, y, xs, startSlope, endSlope );
}
/// <summary>
/// Fit the input x,y points using a 'geometric' strategy so that y does not have to be a single-valued
/// function of x.
/// </summary>
/// <param name="x">Input x coordinates.</param>
/// <param name="y">Input y coordinates, do not need to be a single-valued function of x.</param>
/// <param name="nOutputPoints">How many output points to create.</param>
/// <param name="xs">Output (interpolated) x values.</param>
/// <param name="ys">Output (interpolated) y values.</param>
public static void FitGeometric(float[] x, float[] y, int nOutputPoints, out float[] xs, out float[] ys)
{
// Compute distances
int n = x.Length;
float[] dists = new float[n]; // cumulative distance
dists[0] = 0;
float totalDist = 0;
for (int i = 1; i < n; i++)
{
float dx = x[i] - x[i - 1];
float dy = y[i] - y[i - 1];
float dist = (float)Math.Sqrt(dx * dx + dy * dy);
totalDist += dist;
dists[i] = totalDist;
}
// Create 'times' to interpolate to
float dt = totalDist / (nOutputPoints - 1);
float[] times = new float[nOutputPoints];
times[0] = 0;
for (int i = 1; i < nOutputPoints; i++)
{
times[i] = times[i - 1] + dt;
}
// Spline fit both x and y to times
CubicSpline xSpline = new CubicSpline();
xs = xSpline.FitAndEval(dists, x, times);
CubicSpline ySpline = new CubicSpline();
ys = ySpline.FitAndEval(dists, y, times);
}
#endregion
}
/// Evaluate (compute) the slope of the spline at the specified x coordinates.
/// This can extrapolate off the ends of the splines.
/// You must provide X's in ascending order.
/// The spline must already be computed before calling this, meaning you must have already called Fit() or FitAndEval().
/// </summary>
/// <param name="x">Input. X coordinates to evaluate the fitted curve at.</param>
/// <returns>The computed y values for each x.</returns>
public float[] EvalSlope(float[] x )
{
CheckAlreadyFitted();
int n = x.Length;
float[] qPrime = new float[n];
_lastIndex = 0; // Reset simultaneous traversal in case there are multiple calls
for (int i = 0; i < n; i++)
{
// Find which spline can be used to compute this x (by simultaneous traverse)
int j = GetNextXIndex(x[i]);
// Evaluate using j'th spline
float dx = xOrig[j + 1] - xOrig[j];
float dy = yOrig[j + 1] - yOrig[j];
float t = (x[i] - xOrig[j]) / dx;
// From equation 5 we could also compute q' (qp) which is the slope at this x
qPrime[i] = dy / dx
+ (1 - 2 * t) * (a[j] * (1 - t) + b[j] * t) / dx
+ t * (1 - t) * (b[j] - a[j]) / dx;
}
return qPrime;
}
#endregion
#region Static Methods
/// <summary>
/// Static all-in-one method to fit the splines and evaluate at X coordinates.
/// </summary>
/// <param name="x">Input. X coordinates to fit.</param>
/// <param name="y">Input. Y coordinates to fit.</param>
/// <param name="xs">Input. X coordinates to evaluate the fitted curve at.</param>
/// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
/// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
/// <returns>The computed y values for each xs.</returns>
public static float[] Compute(float[] x, float[] y, float[] xs, float startSlope = float.NaN, float endSlope = float.NaN )
{
CubicSpline spline = new CubicSpline();
return spline.FitAndEval(x, y, xs, startSlope, endSlope );
}
/// <summary>
/// Fit the input x,y points using a 'geometric' strategy so that y does not have to be a single-valued
/// function of x.
/// </summary>
/// <param name="x">Input x coordinates.</param>
/// <param name="y">Input y coordinates, do not need to be a single-valued function of x.</param>
/// <param name="nOutputPoints">How many output points to create.</param>
/// <param name="xs">Output (interpolated) x values.</param>
/// <param name="ys">Output (interpolated) y values.</param>
public static void FitGeometric(float[] x, float[] y, int nOutputPoints, out float[] xs, out float[] ys)
{
// Compute distances
int n = x.Length;
float[] dists = new float[n]; // cumulative distance
dists[0] = 0;
float totalDist = 0;
for (int i = 1; i < n; i++)
{
float dx = x[i] - x[i - 1];
float dy = y[i] - y[i - 1];
float dist = (float)Math.Sqrt(dx * dx + dy * dy);
totalDist += dist;
dists[i] = totalDist;
}
// Create 'times' to interpolate to
float dt = totalDist / (nOutputPoints - 1);
float[] times = new float[nOutputPoints];
times[0] = 0;
for (int i = 1; i < nOutputPoints; i++)
{
times[i] = times[i - 1] + dt;
}
// Spline fit both x and y to times
CubicSpline xSpline = new CubicSpline();
xs = xSpline.FitAndEval(dists, x, times);
CubicSpline ySpline = new CubicSpline();
ys = ySpline.FitAndEval(dists, y, times);
}
#endregion
}
}

@ -1,4 +1,4 @@
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
partial class FormJSCalCurve
{

@ -12,12 +12,15 @@ using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using SCJMapper_V2.TextureLoaders;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms.DataVisualization.Charting;
namespace SCJMapper_V2
using SCJMapper_V2.OGL.TextureLoaders;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2.OGL
{
public partial class FormJSCalCurve : Form
{

@ -19,7 +19,7 @@ using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
namespace SCJMapper_V2.TextureLoaders
namespace SCJMapper_V2.OGL.TextureLoaders
{
/// <summary>
/// Expects the presence of a valid OpenGL Context and Texture Compression Extensions (GL 1.5) and Cube Maps (GL 1.3).

@ -10,7 +10,7 @@ using System;
using OpenTK.Graphics.OpenGL;
namespace SCJMapper_V2.TextureLoaders
namespace SCJMapper_V2.OGL.TextureLoaders
{
/// <summary>The parameters in this class have only effect on the following Texture loads.</summary>

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using OpenTK;
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
/// <summary>
/// 4th order Runge-Kutta integrator

@ -28,7 +28,7 @@ using System;
using System.Diagnostics;
using System.Text;
namespace SCJMapper_V2
namespace SCJMapper_V2.OGL
{
/// <summary>
/// A tri-diagonal matrix has non-zero entries only on the main diagonal, the diagonal above the main (super), and the

@ -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.22.0.56" )]
[assembly: AssemblyFileVersion( "2.22.0.56" )]
[assembly: AssemblyVersion( "2.23.0.57" )]
[assembly: AssemblyFileVersion( "2.23.0.57" )]

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -91,22 +91,21 @@ namespace SCJMapper_V2.Properties {
}
/// <summary>
/// Looks up a localized string similar to &lt;profile version=&quot;0&quot;&gt;
/// Looks up a localized string similar to &lt;profile version=&quot;1&quot; optionsVersion=&quot;2&quot; rebindVersion=&quot;2&quot; &gt;
/// &lt;platforms&gt;
/// &lt;PC keyboard=&quot;1&quot; xboxpad=&quot;1&quot; ps3pad=&quot;1&quot; joystick=&quot;1&quot; /&gt;
/// &lt;Xbox keyboard=&quot;1&quot; xboxpad=&quot;1&quot; ps3pad=&quot;0&quot; /&gt;
/// &lt;PS3 keyboard=&quot;1&quot; xboxpad=&quot;0&quot; ps3pad=&quot;1&quot; /&gt;
/// &lt;PC keyboard=&quot;1&quot; mouse=&quot;1&quot; xboxpad=&quot;1&quot; ps3pad=&quot;0&quot; joystick=&quot;1&quot; /&gt;
/// &lt;Xbox keyboard=&quot;1&quot; xboxpad=&quot;1&quot; ps3pad=&quot;0&quot; /&gt;
/// &lt;PS3 keyboard=&quot;1&quot; xboxpad=&quot;0&quot; ps3pad=&quot;1&quot; /&gt;
/// &lt;/platforms&gt;
///
/// &lt;actiongroup action=&quot;v_attack1&quot;&gt;
/// &lt;action name=&quot;v_attack1_group1&quot; /&gt;
/// &lt;action name=&quot;v_attack1_group2&quot; /&gt;
/// &lt;action name=&quot;v_attack1_group3&quot; /&gt;
/// &lt;actiongroup action=&quot;v_attack1&quot; &gt;
/// &lt;action name=&quot;v_attack1_group1&quot; /&gt;
/// &lt;action name=&quot;v_attack1_group2&quot; /&gt;
/// &lt;action name=&quot;v_attack1_group3&quot; /&gt;
/// &lt;/actiongroup&gt;
///
/// &lt;CustomisationUIHeader&gt;
/// &lt;keyboard label=&quot;Default&quot; description=&quot;@ui_KeyboardDefaultDesc&quot; image=&quot;KeyboardDefault&quot; /&gt;
/// &lt;xboxpad labe [rest of string was truncated]&quot;;.
///
/// &lt;ActivationModes&gt;
/// &lt;ActivationMode name=&quot;tap&quot; onPress=&quot;0 [rest of string was truncated]&quot;;.
/// </summary>
internal static string defaultProfile {
get {

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -12,7 +12,7 @@ namespace SCJMapper_V2.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
/// <summary>
/// Defines a single activation mode

@ -22,9 +22,12 @@ namespace SCJMapper_V2.CryXMLlib
// Return new array.
T[] res = new T[len];
/*
for ( int i = 0; i < len; i++ ) {
res[i] = source[i + start];
resOLD[i] = source[i + start];
}
*/
Array.ConstrainedCopy( source, ( int )start, res, 0, ( int )len );
return res;
}
@ -43,9 +46,12 @@ namespace SCJMapper_V2.CryXMLlib
// Return new array.
T[] res = new T[len];
/*
for ( int i = 0; i < len; i++ ) {
res[i] = source[i + offset];
}
*/
Array.ConstrainedCopy( source, ( int )offset, res, 0, ( int )len );
return res;
}
}

@ -56,30 +56,30 @@ namespace SCJMapper_V2.CryXMLlib
return null;
}
BinaryReader binReader = new BinaryReader( File.Open( filename, FileMode.Open ) );
try {
UInt32 fileSize = ( UInt32 )binReader.BaseStream.Length;
using ( BinaryReader binReader = new BinaryReader( File.Open( filename, FileMode.Open ) ) ) {
try {
UInt32 fileSize = ( UInt32 )binReader.BaseStream.Length;
if ( fileSize < CryXMLHeader.MySize( ) ) {
result = EResult.NotBinXml;
SetErrorDescription( "File is not a binary XML file (file size is too small)." );
return null;
}
if ( fileSize < CryXMLHeader.MySize( ) ) {
result = EResult.NotBinXml;
SetErrorDescription( "File is not a binary XML file (file size is too small)." );
return null;
}
// read from binary file and map the content into the memory
CryXmlBinContext pData = Create( binReader, fileSize, out result );
// read from binary file and map the content into the memory
CryXmlBinContext pData = Create( binReader, fileSize, out result );
if ( result != EResult.Success ) return null; // Well...
if ( result != EResult.Success ) return null; // Well...
// Return first node
CryXmlNodeRef n = pData.pBinaryNodes[0];
return n;
// Return first node
CryXmlNodeRef n = pData.pBinaryNodes[0];
return n;
}
catch {
result = EResult.NotBinXml;
SetErrorDescription( "Exception in BinaryReader." );
return null;
} catch {
result = EResult.NotBinXml;
SetErrorDescription( "Exception in BinaryReader." );
return null;
}
}
}
@ -97,7 +97,7 @@ namespace SCJMapper_V2.CryXMLlib
UInt32 fileSize = ( UInt32 )binBuffer.Length;
try {
try {
if ( fileSize < CryXMLHeader.MySize( ) ) {
result = EResult.NotBinXml;
SetErrorDescription( "File is not a binary XML file (file size is too small)." );
@ -113,8 +113,7 @@ namespace SCJMapper_V2.CryXMLlib
CryXmlNodeRef n = pData.pBinaryNodes[0];
return n;
}
catch {
} catch {
result = EResult.NotBinXml;
SetErrorDescription( "Exception in buffer reader" );
return null;
@ -166,18 +165,17 @@ namespace SCJMapper_V2.CryXMLlib
// Create binary nodes to wrap the ones to read later
pData.pBinaryNodes = new List<CryXmlBinNode>( ); // dynamic list used, not an array
for ( int i=0; i < header.nNodeCount; i++ ) { pData.pBinaryNodes.Add( new CryXmlBinNode( ) ); }
for ( int i = 0; i < header.nNodeCount; i++ ) { pData.pBinaryNodes.Add( new CryXmlBinNode( ) ); }
// map file content to binary.. here we really allocate arrays of elements and copy rather than the original which worked well with ptrs in c++
try {
pData.pAttributes = ( CryXMLAttribute[] )Array.CreateInstance( typeof( CryXMLAttribute ), header.nAttributeCount ); // alloc enough
UInt32 incr = CryXMLAttribute.MySize( ); // size of one element to read
for ( UInt32 aIdx=0; aIdx < header.nAttributeCount; aIdx++ ) {
for ( UInt32 aIdx = 0; aIdx < header.nAttributeCount; aIdx++ ) {
pData.pAttributes[aIdx] = Conversions.ByteToType<CryXMLAttribute>( fileContents, header.nAttributeTablePosition + aIdx * incr );
}
}
catch ( Exception e ) {
} catch ( Exception e ) {
SetErrorDescription( string.Format( "EXC Attributes: {0}", e.Message ) );
return null;
}
@ -185,11 +183,10 @@ namespace SCJMapper_V2.CryXMLlib
try {
pData.pChildIndices = ( CryXMLNodeIndex[] )Array.CreateInstance( typeof( CryXMLNodeIndex ), header.nChildCount ); // alloc enough
UInt32 incr = CryXMLNodeIndex.MySize( ); // size of one element to read
for ( UInt32 aIdx=0; aIdx < header.nChildCount; aIdx++ ) {
for ( UInt32 aIdx = 0; aIdx < header.nChildCount; aIdx++ ) {
pData.pChildIndices[aIdx] = Conversions.ByteToType<CryXMLNodeIndex>( fileContents, header.nChildTablePosition + aIdx * incr );
}
}
catch ( Exception e ) {
} catch ( Exception e ) {
SetErrorDescription( string.Format( "EXC ChildIndices: {0}", e.Message ) );
return null;
}
@ -197,11 +194,10 @@ namespace SCJMapper_V2.CryXMLlib
try {
pData.pNodes = ( CryXMLNode[] )Array.CreateInstance( typeof( CryXMLNode ), header.nNodeCount ); // alloc enough
UInt32 incr = CryXMLNode.MySize( ); // size of one element to read
for ( UInt32 aIdx=0; aIdx < header.nNodeCount; aIdx++ ) {
for ( UInt32 aIdx = 0; aIdx < header.nNodeCount; aIdx++ ) {
pData.pNodes[aIdx] = Conversions.ByteToType<CryXMLNode>( fileContents, header.nNodeTablePosition + aIdx * incr );
}
}
catch ( Exception e ) {
} catch ( Exception e ) {
SetErrorDescription( string.Format( "EXC Nodes: {0}", e.Message ) );
return null;
}
@ -209,8 +205,7 @@ namespace SCJMapper_V2.CryXMLlib
try {
pData.pStringDataLength = header.nStringDataSize;
pData.pStringData = fileContents.SliceL( header.nStringDataPosition, header.nStringDataSize );
}
catch ( Exception e ) {
} catch ( Exception e ) {
SetErrorDescription( string.Format( "EXC StringData: {0}", e.Message ) );
return null;
}

@ -24,8 +24,8 @@ namespace SCJMapper_V2.CryXMLlib
public string XML_string
{
get {
string xml = "";
foreach ( string s in m_doc ) xml += string.Format( "{0}\n", s );
string xml = ""; string CR = string.Format("\n");
foreach ( string s in m_doc ) xml += ( s + CR );
return xml;
}
}

@ -4,7 +4,7 @@ using System.Text;
using System.Xml;
using System.IO;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
/// <summary>
/// should read the default profile - may be replacing the MappingVars once
@ -150,7 +150,7 @@ namespace SCJMapper_V2
ac.defBinding = attr["joystick"];
ac.defActivationMode = actMode;
if ( ac.defBinding == " " ) {
ac.defBinding = JoystickCls.BlendedInput;
ac.defBinding = Joystick.JoystickCls.BlendedInput;
m_currentMap.Add( ac ); // finally add it to the current map if it was bound
}
else if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -166,7 +166,7 @@ namespace SCJMapper_V2
ac.defBinding = attr["keyboard"];
ac.defActivationMode = actMode;
if ( ac.defBinding == " " ) {
ac.defBinding = KeyboardCls.BlendedInput;
ac.defBinding = Keyboard.KeyboardCls.BlendedInput;
m_currentMap.Add( ac ); // finally add it to the current map if it was bound
}
else if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -182,7 +182,7 @@ namespace SCJMapper_V2
ac.defBinding = attr["mouse"];
ac.defActivationMode = actMode;
if ( ac.defBinding == " " ) {
ac.defBinding = MouseCls.BlendedInput;
ac.defBinding = Mouse.MouseCls.BlendedInput;
m_currentMap.Add( ac ); // finally add it to the current map if it was bound
}
else if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -198,7 +198,7 @@ namespace SCJMapper_V2
ac.defBinding = attr["xboxpad"];
ac.defActivationMode = actMode;
if ( ac.defBinding == " " ) {
ac.defBinding = GamepadCls.BlendedInput;
ac.defBinding = Gamepad.GamepadCls.BlendedInput;
m_currentMap.Add( ac ); // finally add it to the current map if it was bound
}
else if ( !String.IsNullOrEmpty( ac.defBinding ) ) {

@ -7,7 +7,7 @@ using System.IO;
using SCJMapper_V2.CryXMLlib;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
/// <summary>

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.IO;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
public class SCLogExtract
{

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.IO;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
/// <summary>
/// Finds and returns the Mappings from SC Bundle

@ -5,7 +5,7 @@ using System.Text;
using System.IO;
using Microsoft.Win32;
namespace SCJMapper_V2
namespace SCJMapper_V2.SC
{
/// <summary>
/// Find the SC pathes and folders
@ -15,6 +15,8 @@ namespace SCJMapper_V2
private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType );
private static readonly AppSettings appSettings = new AppSettings( );
private static bool hasInformed = false; // prevent msgbox chains..
/// <summary>
/// Try to locate the launcher under "App Paths"
/// </summary>
@ -123,12 +125,18 @@ namespace SCJMapper_V2
log.Debug( "SCBasePath - Entry" );
appSettings.Reload( ); // local instance - reload as it might be changed outside
String scp = "";
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 );
string issue = string.Format( "Cannot find the user defined SC Installation Path !!\n\n" +
"Enter the folder where CIGLauncher.exe is located");
if ( !hasInformed ) System.Windows.Forms.MessageBox.Show( issue, "Cannot find the user defined SC Installation Path !!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation );
hasInformed = true;
return ""; // sorry path does not exist
}
}
@ -143,6 +151,14 @@ namespace SCJMapper_V2
scp = SCLauncherFile1;
if ( String.IsNullOrEmpty( scp ) ) {
log.Warn( "SCBasePath - cannot find any valid SC path" );
// Issue a warning here to let the user know
string issue = string.Format( "Cannot find the SC Installation Path !!\n\n" +
"Use Settings to provide the path manually (don't forget to Check the Box left of the path to use it)\n\n" +
"Enter the folder where CIGLauncher.exe is located");
if ( !hasInformed ) System.Windows.Forms.MessageBox.Show( issue, "Cannot find SC Installation Path !!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation );
hasInformed = true;
return ""; // sorry did not found a thing..
}
}
@ -177,6 +193,7 @@ namespace SCJMapper_V2
/// Returns the SC Client path
/// AC 1.1.6: E:\G\StarCitizen\StarCitizen\Public
/// SC 2x: alternatively use PTU path E:\G\StarCitizen\StarCitizen\Test
/// SC 2.2.2: alternatively search path in E:\G\StarCitizen\StarCitizen\Live (don't know but this was mentioned in CIGs relnotes lately)
/// </summary>
static public String SCClientPath
{
@ -187,14 +204,33 @@ namespace SCJMapper_V2
if ( String.IsNullOrEmpty( scp ) ) return ""; // no valid one can be found
//
scp = Path.Combine( scp, "StarCitizen" );
if ( appSettings.UsePTU )
scp = Path.Combine( scp, "Test" );
else
scp = Path.Combine( scp, "Public" );
string scpX = "";
if ( appSettings.UsePTU ) {
scpX = Path.Combine( scp, "Test" );
if ( Directory.Exists( scp ) ) return scpX;
} else {
scpX = Path.Combine( scp, "Public" );
if ( Directory.Exists( scp ) ) return scpX;
// SC 2.2.2+ did not found it so try Live now
scpX = Path.Combine( scp, "Live" );
if ( Directory.Exists( scp ) ) return scpX;
}
if ( Directory.Exists( scp ) ) return scp;
log.WarnFormat( "SCClientDataPath - StarCitizen\\Public or for PTU \\Test subfolder does not exist: {0}", scp );
log.WarnFormat( "SCClientDataPath - StarCitizen\\Public, StarCitizen\\Live or for PTU \\Test subfolder does not exist: {0}", scp );
// Issue a warning here to let the user know
string issue = string.Format( "Cannot find the SC Client Path !!\n\n" +
"Tried to look for:\n" +
"{0}\\Public or \n" +
"{0}\\Live or \n" +
"{0}\\Test (if PTU was enabled)\n\n" +
"The program cannot load or save in GameFolders\n\n" +
"Please submit a bug report, adding your complete SC game folder structure");
if (!hasInformed) System.Windows.Forms.MessageBox.Show( issue, "Cannot find SC Client Path !!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation );
hasInformed = true;
return "";
}
}

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SCJMapper_V2</RootNamespace>
<AssemblyName>SCJMapper</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
@ -40,6 +40,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
@ -49,6 +50,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Cassini_Logo_Icon.ico</ApplicationIcon>
@ -65,6 +67,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
@ -76,6 +79,7 @@
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Ionic.Zip.Reduced">
@ -122,6 +126,22 @@
<Compile Include="appConfiguration.cs" />
<Compile Include="AppSettings.cs" />
<Compile Include="DeviceCls.cs" />
<Compile Include="Table\DS_ActionMap.cs" />
<Compile Include="Table\DS_ActionMaps.cs">
<DependentUpon>DS_ActionMaps.xsd</DependentUpon>
</Compile>
<Compile Include="Table\DS_ActionMaps.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>DS_ActionMaps.xsd</DependentUpon>
</Compile>
<Compile Include="Table\FormTabEvents.cs" />
<Compile Include="Table\FormTable.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Table\FormTable.Designer.cs">
<DependentUpon>FormTable.cs</DependentUpon>
</Compile>
<Compile Include="Joystick\DeviceDeadzoneParameter.cs" />
<Compile Include="Gamepad\GamepadCls.cs" />
<Compile Include="Joystick\JsReassingList.cs" />
@ -206,6 +226,9 @@
<DependentUpon>Form1.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Table\FormTable.resx">
<DependentUpon>FormTable.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="OGL\FormJSCalCurve.resx">
<DependentUpon>FormJSCalCurve.cs</DependentUpon>
</EmbeddedResource>
@ -232,6 +255,17 @@
<DependentUpon>UC_GpadPanel.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.config" />
<None Include="Table\DS_ActionMaps.xsc">
<DependentUpon>DS_ActionMaps.xsd</DependentUpon>
</None>
<None Include="Table\DS_ActionMaps.xsd">
<SubType>Designer</SubType>
<Generator>MSDataSetGenerator</Generator>
<LastGenOutput>DS_ActionMaps.Designer.cs</LastGenOutput>
</None>
<None Include="Table\DS_ActionMaps.xss">
<DependentUpon>DS_ActionMaps.xsd</DependentUpon>
</None>
<None Include="graphics\SB_BigSight.dds">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SCJMapper-V2", "SCJMapper-V2.csproj", "{B5F8B339-E02E-4F6D-BF62-D776F165910F}"
EndProject
Global

@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SCJMapper_V2.Table
{
class DS_ActionMap
{
static public string ActionMapShown( string actionMap, int amCount )
{
string amShown = string.Format("{0,2:00}-{1}", amCount, actionMap);
return amShown;
}
static public string ActionMapFromAMShown( string actionMapShown )
{
string ret = actionMapShown.Substring(3); // must match the above formatting
return ret;
}
static public string ActionID( string actionMap, string acKey, int actionCommandIndex )
{
string acID = string.Format("{0}.{1}.{2}", actionMap, acKey, actionCommandIndex ); // make a unique key
return acID;
}
static public string ActionMap( string actionID )
{
string[] e = actionID.Split( new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
// we have actionmap.actionkey.nodeindex
string actionKey = e[0];
return actionKey;
}
static public string ActionMap( DS_ActionMaps.T_ActionRow acr )
{
return ActionMap( acr.ID_Action );
}
/// <summary>
/// decompose the Action from the ActionID string
/// matches the composing ActionIDShown
/// </summary>
/// <param name="actionID"></param>
/// <returns></returns>
static public string Action( string actionID )
{
string[] e =actionID.Split( new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
// we have actionmap.actionkey.nodeindex
string actionKey = e[1];
return actionKey.Substring( 1 );
}
static public string Action( DS_ActionMaps.T_ActionRow acr )
{
return Action( acr.ID_Action );
}
static public string ActionKey( string actionID )
{
string[] e = actionID.Split( new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
// we have actionmap.actionkey.nodeindex
string actionKey = e[1];
return actionKey;
}
static public string ActionKey( DS_ActionMaps.T_ActionRow acr )
{
return ActionKey( acr.ID_Action );
}
static public int ActionCommandIndex( string actionID )
{
string[] e =actionID.Split( new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
// we have actionmap.actionkey.nodeindex
int actionCommandIndex = int.Parse( e[2] );
return actionCommandIndex;
}
static public int ActionCommandIndex( DS_ActionMaps.T_ActionRow acr )
{
return ActionCommandIndex( acr.ID_Action );
}
static public string DevInput ( DS_ActionMaps.T_ActionRow acr )
{
if ( acr.Blended )
return DeviceCls.BlendedInput;
else
return acr.Usr_Binding;
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,11 @@
namespace SCJMapper_V2.Table
{
partial class DS_ActionMaps
{
partial class T_ActionDataTable
{
}
}
}

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!--<autogenerated>
This code was generated by a tool.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
</autogenerated>-->
<DataSetUISetting Version="1.00" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TableUISettings />
</DataSetUISetting>

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="DS_ActionMaps" targetNamespace="http://tempuri.org/DS_ActionMaps.xsd" xmlns:mstns="http://tempuri.org/DS_ActionMaps.xsd" xmlns="http://tempuri.org/DS_ActionMaps.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections />
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="DS_ActionMaps" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:EnableTableAdapterManager="true" msprop:Generator_DataSetName="DS_ActionMaps" msprop:Generator_UserDSName="DS_ActionMaps">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="T_ActionMap" msprop:Generator_TableClassName="T_ActionMapDataTable" msprop:Generator_TableVarName="tableT_ActionMap" msprop:Generator_RowChangedName="T_ActionMapRowChanged" msprop:Generator_TablePropName="T_ActionMap" msprop:Generator_RowDeletingName="T_ActionMapRowDeleting" msprop:Generator_RowChangingName="T_ActionMapRowChanging" msprop:Generator_RowEvHandlerName="T_ActionMapRowChangeEventHandler" msprop:Generator_RowDeletedName="T_ActionMapRowDeleted" msprop:Generator_RowClassName="T_ActionMapRow" msprop:Generator_UserTableName="T_ActionMap" msprop:Generator_RowEvArgName="T_ActionMapRowChangeEvent">
<xs:complexType>
<xs:sequence>
<xs:element name="ID_ActionMap" msdata:ReadOnly="true" msprop:Generator_ColumnVarNameInTable="columnID_ActionMap" msprop:Generator_ColumnPropNameInRow="ID_ActionMap" msprop:Generator_ColumnPropNameInTable="ID_ActionMapColumn" msprop:Generator_UserColumnName="ID_ActionMap" type="xs:string" default="&quot;&quot;" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="T_Action" msprop:Generator_TableClassName="T_ActionDataTable" msprop:Generator_TableVarName="tableT_Action" msprop:Generator_RowChangedName="T_ActionRowChanged" msprop:Generator_TablePropName="T_Action" msprop:Generator_RowDeletingName="T_ActionRowDeleting" msprop:Generator_RowChangingName="T_ActionRowChanging" msprop:Generator_RowEvHandlerName="T_ActionRowChangeEventHandler" msprop:Generator_RowDeletedName="T_ActionRowDeleted" msprop:Generator_RowClassName="T_ActionRow" msprop:Generator_UserTableName="T_Action" msprop:Generator_RowEvArgName="T_ActionRowChangeEvent">
<xs:complexType>
<xs:sequence>
<xs:element name="ID_Action" msdata:ReadOnly="true" msprop:Generator_ColumnVarNameInTable="columnID_Action" msprop:Generator_ColumnPropNameInRow="ID_Action" msprop:Generator_ColumnPropNameInTable="ID_ActionColumn" msprop:Generator_UserColumnName="ID_Action" type="xs:string" default="&quot;&quot;" />
<xs:element name="REF_ActionMap" msdata:ReadOnly="true" msdata:Caption="ActionMap" msprop:Generator_ColumnVarNameInTable="columnREF_ActionMap" msprop:Generator_ColumnPropNameInRow="REF_ActionMap" msprop:Generator_ColumnPropNameInTable="REF_ActionMapColumn" msprop:Generator_UserColumnName="REF_ActionMap" type="xs:string" default="&quot;&quot;" />
<xs:element name="ActionName" msdata:ReadOnly="true" msprop:Generator_ColumnVarNameInTable="columnActionName" msprop:Generator_ColumnPropNameInRow="ActionName" msprop:Generator_ColumnPropNameInTable="ActionNameColumn" msprop:Generator_UserColumnName="ActionName" type="xs:string" default="&quot;&quot;" />
<xs:element name="Device" msdata:ReadOnly="true" msprop:Generator_ColumnVarNameInTable="columnDevice" msprop:Generator_ColumnPropNameInRow="Device" msprop:Generator_ColumnPropNameInTable="DeviceColumn" msprop:Generator_UserColumnName="Device" type="xs:string" minOccurs="0" />
<xs:element name="Def_Binding" msdata:ReadOnly="true" msdata:Caption="Default Binding" msprop:Generator_ColumnVarNameInTable="columnDef_Binding" msprop:Generator_ColumnPropNameInRow="Def_Binding" msprop:Generator_ColumnPropNameInTable="Def_BindingColumn" msprop:Generator_UserColumnName="Def_Binding" type="xs:string" minOccurs="0" />
<xs:element name="Def_Modifier" msdata:ReadOnly="true" msdata:Caption="Default Act.Mode" msprop:Generator_ColumnVarNameInTable="columnDef_Modifier" msprop:Generator_ColumnPropNameInRow="Def_Modifier" msprop:Generator_ColumnPropNameInTable="Def_ModifierColumn" msprop:Generator_UserColumnName="Def_Modifier" type="xs:string" minOccurs="0" />
<xs:element name="AddBind" msdata:ReadOnly="true" msdata:Caption="addbind Cmd" msprop:Generator_ColumnVarNameInTable="columnAddBind" msprop:Generator_ColumnPropNameInRow="AddBind" msprop:Generator_ColumnPropNameInTable="AddBindColumn" msprop:Generator_UserColumnName="AddBind" type="xs:boolean" default="false" minOccurs="0" />
<xs:element name="Usr_Binding" msdata:Caption="User Binding" msprop:Generator_ColumnVarNameInTable="columnUsr_Binding" msprop:Generator_ColumnPropNameInRow="Usr_Binding" msprop:Generator_ColumnPropNameInTable="Usr_BindingColumn" msprop:Generator_UserColumnName="Usr_Binding" type="xs:string" minOccurs="0" />
<xs:element name="Usr_Modifier" msdata:Caption="User Act.Mode" msprop:Generator_ColumnVarNameInTable="columnUsr_Modifier" msprop:Generator_ColumnPropNameInRow="Usr_Modifier" msprop:Generator_ColumnPropNameInTable="Usr_ModifierColumn" msprop:Generator_UserColumnName="Usr_Modifier" type="xs:string" minOccurs="0" />
<xs:element name="Blended" msprop:Generator_ColumnVarNameInTable="columnBlended" msprop:Generator_ColumnPropNameInRow="Blended" msprop:Generator_ColumnPropNameInTable="BlendedColumn" msprop:Generator_UserColumnName="Blended" type="xs:boolean" default="false" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:T_ActionMap" />
<xs:field xpath="mstns:ID_ActionMap" />
</xs:unique>
<xs:unique name="T_Action_Constraint1" msdata:ConstraintName="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:T_Action" />
<xs:field xpath="mstns:ID_Action" />
</xs:unique>
</xs:element>
<xs:annotation>
<xs:appinfo>
<msdata:Relationship name="T_ActionMap_T_Action" msdata:parent="T_ActionMap" msdata:child="T_Action" msdata:parentkey="ID_ActionMap" msdata:childkey="REF_ActionMap" msprop:Generator_UserChildTable="T_Action" msprop:Generator_ChildPropName="GetT_ActionRows" msprop:Generator_UserRelationName="T_ActionMap_T_Action" msprop:Generator_RelationVarName="relationT_ActionMap_T_Action" msprop:Generator_UserParentTable="T_ActionMap" msprop:Generator_ParentPropName="T_ActionMapRow" />
</xs:appinfo>
</xs:annotation>
</xs:schema>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--<autogenerated>
This code was generated by a tool to store the dataset designer's layout information.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
</autogenerated>-->
<DiagramLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ex:showrelationlabel="False" ViewPortX="0" ViewPortY="0" xmlns:ex="urn:schemas-microsoft-com:xml-msdatasource-layout-extended" xmlns="urn:schemas-microsoft-com:xml-msdatasource-layout">
<Shapes>
<Shape ID="DesignTable:T_ActionMap" ZOrder="3" X="361" Y="205" Height="48" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="44" />
<Shape ID="DesignTable:T_Action" ZOrder="1" X="627" Y="270" Height="219" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="215" />
</Shapes>
<Connectors>
<Connector ID="DesignRelation:T_ActionMap_T_Action" ZOrder="2" LineWidth="11">
<RoutePoints>
<Point>
<X>494</X>
<Y>253</Y>
</Point>
<Point>
<X>494</X>
<Y>287</Y>
</Point>
<Point>
<X>627</X>
<Y>287</Y>
</Point>
</RoutePoints>
</Connector>
</Connectors>
</DiagramLayout>

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SCJMapper_V2.Table
{
/// <summary>
/// A driver custom event to callback for exposure
/// </summary>
public class EditRowEventArgs : EventArgs
{
public string Actionmap { get; private set; }
public string Actionkey { get; private set; }
public int Nodeindex { get; private set; }
public EditRowEventArgs( string actionmap, string actionkey, int nodeindex )
{
Actionmap = actionmap;
Actionkey = actionkey;
Nodeindex = nodeindex;
}
}
/// <summary>
/// A driver custom event to callback for exposure
/// </summary>
public class UpdateEditEventArgs : EventArgs
{
public UpdateEditEventArgs( )
{
}
}
}

@ -0,0 +1,374 @@
namespace SCJMapper_V2.Table
{
partial class FormTable
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if ( disposing && ( components != null ) ) {
components.Dispose( );
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent( )
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormTable));
this.DGV = new System.Windows.Forms.DataGridView();
this.dS_ActionMaps = new SCJMapper_V2.Table.DS_ActionMaps();
this.dSActionMapsBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.txFilterAction = new System.Windows.Forms.TextBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.panel2 = new System.Windows.Forms.Panel();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.panel1 = new System.Windows.Forms.Panel();
this.btCancelEdit = new System.Windows.Forms.Button();
this.chkEditBlend = new System.Windows.Forms.CheckBox();
this.btUpdateFromEdit = new System.Windows.Forms.Button();
this.btClrFilterUsrBinding = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.txFilterUsrBinding = new System.Windows.Forms.TextBox();
this.btClrFilterDefBinding = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.txFilterDefBinding = new System.Windows.Forms.TextBox();
this.btClrFilterAction = new System.Windows.Forms.Button();
this.chkKbd = new System.Windows.Forms.CheckBox();
this.chkMouse = new System.Windows.Forms.CheckBox();
this.chkGamepad = new System.Windows.Forms.CheckBox();
this.chkJoystick = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.DGV)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dS_ActionMaps)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dSActionMapsBindingSource)).BeginInit();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// DGV
//
this.DGV.AllowUserToAddRows = false;
this.DGV.AllowUserToDeleteRows = false;
this.DGV.AllowUserToOrderColumns = true;
dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.DGV.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
this.DGV.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
this.DGV.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DGV.Dock = System.Windows.Forms.DockStyle.Fill;
this.DGV.Location = new System.Drawing.Point(3, 3);
this.DGV.Name = "DGV";
this.DGV.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.DGV.Size = new System.Drawing.Size(438, 230);
this.DGV.TabIndex = 0;
this.DGV.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DGV_CellMouseDoubleClick);
this.DGV.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.DGV_CellValueChanged);
this.DGV.ColumnWidthChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.DGV_ColumnWidthChanged);
this.DGV.RowHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DGV_RowHeaderMouseClick);
//
// dS_ActionMaps
//
this.dS_ActionMaps.DataSetName = "Table.DS_ActionMaps";
this.dS_ActionMaps.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
//
// dSActionMapsBindingSource
//
this.dSActionMapsBindingSource.DataSource = this.dS_ActionMaps;
this.dSActionMapsBindingSource.Position = 0;
//
// txFilterAction
//
this.txFilterAction.Location = new System.Drawing.Point(93, 6);
this.txFilterAction.Name = "txFilterAction";
this.txFilterAction.Size = new System.Drawing.Size(109, 22);
this.txFilterAction.TabIndex = 1;
this.txFilterAction.TextChanged += new System.EventHandler(this.txFilterAction_TextChanged);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 300F));
this.tableLayoutPanel1.Controls.Add(this.DGV, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.panel2, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(1);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(744, 286);
this.tableLayoutPanel1.TabIndex = 2;
//
// panel2
//
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(447, 239);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(294, 44);
this.panel2.TabIndex = 2;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 1;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.panel1, 0, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(447, 3);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 2;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 209F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(294, 230);
this.tableLayoutPanel2.TabIndex = 3;
//
// panel1
//
this.panel1.Controls.Add(this.btCancelEdit);
this.panel1.Controls.Add(this.chkEditBlend);
this.panel1.Controls.Add(this.btUpdateFromEdit);
this.panel1.Controls.Add(this.btClrFilterUsrBinding);
this.panel1.Controls.Add(this.label3);
this.panel1.Controls.Add(this.txFilterUsrBinding);
this.panel1.Controls.Add(this.btClrFilterDefBinding);
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.txFilterDefBinding);
this.panel1.Controls.Add(this.btClrFilterAction);
this.panel1.Controls.Add(this.chkKbd);
this.panel1.Controls.Add(this.chkMouse);
this.panel1.Controls.Add(this.chkGamepad);
this.panel1.Controls.Add(this.chkJoystick);
this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.txFilterAction);
this.panel1.Location = new System.Drawing.Point(3, 3);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(288, 202);
this.panel1.TabIndex = 1;
//
// btCancelEdit
//
this.btCancelEdit.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btCancelEdit.ForeColor = System.Drawing.Color.DarkOliveGreen;
this.btCancelEdit.Location = new System.Drawing.Point(183, 170);
this.btCancelEdit.Name = "btCancelEdit";
this.btCancelEdit.Size = new System.Drawing.Size(97, 28);
this.btCancelEdit.TabIndex = 13;
this.btCancelEdit.Text = "Undo Edits";
this.btCancelEdit.UseVisualStyleBackColor = true;
this.btCancelEdit.Click += new System.EventHandler(this.btCancelEdit_Click);
//
// chkEditBlend
//
this.chkEditBlend.AutoSize = true;
this.chkEditBlend.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.chkEditBlend.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chkEditBlend.ForeColor = System.Drawing.Color.Firebrick;
this.chkEditBlend.Location = new System.Drawing.Point(184, 145);
this.chkEditBlend.Name = "chkEditBlend";
this.chkEditBlend.Size = new System.Drawing.Size(96, 17);
this.chkEditBlend.TabIndex = 12;
this.chkEditBlend.Text = "Edit Blending";
this.chkEditBlend.UseVisualStyleBackColor = true;
this.chkEditBlend.CheckedChanged += new System.EventHandler(this.chkEditBlend_CheckedChanged);
//
// btUpdateFromEdit
//
this.btUpdateFromEdit.Enabled = false;
this.btUpdateFromEdit.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btUpdateFromEdit.ForeColor = System.Drawing.Color.Firebrick;
this.btUpdateFromEdit.Location = new System.Drawing.Point(10, 169);
this.btUpdateFromEdit.Name = "btUpdateFromEdit";
this.btUpdateFromEdit.Size = new System.Drawing.Size(97, 30);
this.btUpdateFromEdit.TabIndex = 12;
this.btUpdateFromEdit.Text = "Accept Edits";
this.btUpdateFromEdit.UseVisualStyleBackColor = true;
this.btUpdateFromEdit.Click += new System.EventHandler(this.btUpdateFromEdit_Click);
//
// btClrFilterUsrBinding
//
this.btClrFilterUsrBinding.Location = new System.Drawing.Point(222, 60);
this.btClrFilterUsrBinding.Name = "btClrFilterUsrBinding";
this.btClrFilterUsrBinding.Size = new System.Drawing.Size(58, 23);
this.btClrFilterUsrBinding.TabIndex = 11;
this.btClrFilterUsrBinding.Text = "Clear";
this.btClrFilterUsrBinding.UseVisualStyleBackColor = true;
this.btClrFilterUsrBinding.Click += new System.EventHandler(this.btClrFilterUsrBinding_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(7, 65);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(80, 13);
this.label3.TabIndex = 10;
this.label3.Text = "Usr Bind Filter";
//
// txFilterUsrBinding
//
this.txFilterUsrBinding.Location = new System.Drawing.Point(93, 62);
this.txFilterUsrBinding.Name = "txFilterUsrBinding";
this.txFilterUsrBinding.Size = new System.Drawing.Size(109, 22);
this.txFilterUsrBinding.TabIndex = 9;
this.txFilterUsrBinding.TextChanged += new System.EventHandler(this.txFilterUsrBinding_TextChanged);
//
// btClrFilterDefBinding
//
this.btClrFilterDefBinding.Location = new System.Drawing.Point(222, 32);
this.btClrFilterDefBinding.Name = "btClrFilterDefBinding";
this.btClrFilterDefBinding.Size = new System.Drawing.Size(58, 23);
this.btClrFilterDefBinding.TabIndex = 8;
this.btClrFilterDefBinding.Text = "Clear";
this.btClrFilterDefBinding.UseVisualStyleBackColor = true;
this.btClrFilterDefBinding.Click += new System.EventHandler(this.btClrFilterBinding_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 37);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(81, 13);
this.label2.TabIndex = 7;
this.label2.Text = "Def Bind Filter";
//
// txFilterDefBinding
//
this.txFilterDefBinding.Location = new System.Drawing.Point(93, 34);
this.txFilterDefBinding.Name = "txFilterDefBinding";
this.txFilterDefBinding.Size = new System.Drawing.Size(109, 22);
this.txFilterDefBinding.TabIndex = 6;
this.txFilterDefBinding.TextChanged += new System.EventHandler(this.txFilterBinding_TextChanged);
//
// btClrFilterAction
//
this.btClrFilterAction.Location = new System.Drawing.Point(222, 4);
this.btClrFilterAction.Name = "btClrFilterAction";
this.btClrFilterAction.Size = new System.Drawing.Size(58, 23);
this.btClrFilterAction.TabIndex = 5;
this.btClrFilterAction.Text = "Clear";
this.btClrFilterAction.UseVisualStyleBackColor = true;
this.btClrFilterAction.Click += new System.EventHandler(this.btClrFilterAction_Click);
//
// chkKbd
//
this.chkKbd.AutoSize = true;
this.chkKbd.Location = new System.Drawing.Point(222, 105);
this.chkKbd.Name = "chkKbd";
this.chkKbd.Size = new System.Drawing.Size(46, 17);
this.chkKbd.TabIndex = 4;
this.chkKbd.Text = "Kbd";
this.chkKbd.UseVisualStyleBackColor = true;
this.chkKbd.CheckedChanged += new System.EventHandler(this.chkKbd_CheckedChanged);
//
// chkMouse
//
this.chkMouse.AutoSize = true;
this.chkMouse.Location = new System.Drawing.Point(158, 105);
this.chkMouse.Name = "chkMouse";
this.chkMouse.Size = new System.Drawing.Size(61, 17);
this.chkMouse.TabIndex = 4;
this.chkMouse.Text = "Mouse";
this.chkMouse.UseVisualStyleBackColor = true;
this.chkMouse.CheckedChanged += new System.EventHandler(this.chkMouse_CheckedChanged);
//
// chkGamepad
//
this.chkGamepad.AutoSize = true;
this.chkGamepad.Location = new System.Drawing.Point(80, 105);
this.chkGamepad.Name = "chkGamepad";
this.chkGamepad.Size = new System.Drawing.Size(75, 17);
this.chkGamepad.TabIndex = 4;
this.chkGamepad.Text = "Gamepad";
this.chkGamepad.UseVisualStyleBackColor = true;
this.chkGamepad.CheckedChanged += new System.EventHandler(this.chkGamepad_CheckedChanged);
//
// chkJoystick
//
this.chkJoystick.AutoSize = true;
this.chkJoystick.Location = new System.Drawing.Point(10, 105);
this.chkJoystick.Name = "chkJoystick";
this.chkJoystick.Size = new System.Drawing.Size(65, 17);
this.chkJoystick.TabIndex = 3;
this.chkJoystick.Text = "Joystick";
this.chkJoystick.UseVisualStyleBackColor = true;
this.chkJoystick.CheckedChanged += new System.EventHandler(this.chkJoystick_CheckedChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(7, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(69, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Action Filter";
//
// FormTable
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(744, 286);
this.Controls.Add(this.tableLayoutPanel1);
this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(760, 320);
this.Name = "FormTable";
this.Text = "FormTable";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormTable_FormClosing);
this.LocationChanged += new System.EventHandler(this.FormTable_LocationChanged);
this.SizeChanged += new System.EventHandler(this.FormTable_SizeChanged);
((System.ComponentModel.ISupportInitialize)(this.DGV)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dS_ActionMaps)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dSActionMapsBindingSource)).EndInit();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView DGV;
private System.Windows.Forms.BindingSource dSActionMapsBindingSource;
private DS_ActionMaps dS_ActionMaps;
private System.Windows.Forms.TextBox txFilterAction;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button btClrFilterDefBinding;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txFilterDefBinding;
private System.Windows.Forms.Button btClrFilterAction;
private System.Windows.Forms.CheckBox chkKbd;
private System.Windows.Forms.CheckBox chkMouse;
private System.Windows.Forms.CheckBox chkGamepad;
private System.Windows.Forms.CheckBox chkJoystick;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btClrFilterUsrBinding;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txFilterUsrBinding;
private System.Windows.Forms.Button btUpdateFromEdit;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.CheckBox chkEditBlend;
private System.Windows.Forms.Button btCancelEdit;
}
}

@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SCJMapper_V2.Table
{
public partial class FormTable : Form
{
public FormTable( )
{
InitializeComponent( );
DS_AMaps = new DS_ActionMaps( ); // init once
m_bSrc.DataSource = DS_AMaps;
m_bSrc.DataMember = "T_Action";
m_bSrc.Filter = "ActionName LIKE '*view*'";
DGV.AutoGenerateColumns = true;
DGV.DataSource = m_bSrc;
DGV.MultiSelect = false;
DGV.Columns["ID_Action"].Visible = false;
DGV.AutoResizeColumns( DataGridViewAutoSizeColumnsMode.AllCells );
btUpdateFromEdit.Enabled = chkEditBlend.Checked;
DGV.Columns["Usr_Binding"].ReadOnly = true;
DGV.Columns["Usr_Modifier"].ReadOnly = true;
DGV.ReadOnly = !chkEditBlend.Checked;
}
public event EventHandler<EditRowEventArgs> EditActionEvent;
private void RaiseEditActionEvent( string actionmap, string actionkey, int nodeindex )
{
if ( EditActionEvent != null ) {
EditActionEvent( this, new EditRowEventArgs( actionmap, actionkey, nodeindex ) );
}
}
public event EventHandler<UpdateEditEventArgs> UpdateEditEvent;
private void RaiseUpdateEditEvent( )
{
if ( UpdateEditEvent != null ) {
UpdateEditEvent( this, new UpdateEditEventArgs( ) );
}
}
public Size LastSize { get; set; }
public Point LastLocation { get; set; }
public string LastColSize { get; set; }
private BindingSource m_bSrc = new BindingSource();
/// <summary>
/// Assign or retrieve the underlying DataSet
/// </summary>
public DS_ActionMaps DS_AMaps { get; private set; }
/// <summary>
/// Populate the view from the dataset
/// </summary>
public void Populate( )
{
DGV.SuspendLayout( );
// m_bSrc.ResetBindings( false );
if ( !string.IsNullOrEmpty( LastColSize ) ) {
string[] e = LastColSize.Split( new char [] {';'}, StringSplitOptions.RemoveEmptyEntries );
for ( int i = 0; i < e.Length; i++ ) {
DGV.Columns[i].Width = int.Parse( e[i] );
}
}
DGV.AllowUserToResizeColumns = true;
ComposeFilter( );
DGV.ResumeLayout( );
}
/// <summary>
/// Update a single row with given actionID (from DS_ActionMap)
/// Note: the dataset needs to be updated by the caller before
/// </summary>
/// <param name="actionID">ActionID of the row to update</param>
public void UpdateRow( string actionID )
{
if ( string.IsNullOrEmpty( actionID ) ) return; // nothing to do
// Populate( ); // cheap
}
/// <summary>
/// A row is set to be edited
/// resolve ID and callback to owner
/// </summary>
/// <param name="rowIndex"></param>
private void EditRow( int rowIndex )
{
string id = DGV.Rows[rowIndex].Cells["ID_Action"].Value.ToString();
// we have nn-actionmap.actionkey.nodeindex
string actionMap = DS_ActionMap.ActionMap(id);
string actionKey = DS_ActionMap.ActionKey(id);
int nodeIndex = DS_ActionMap.ActionCommandIndex(id);
RaiseEditActionEvent( actionMap, actionKey, nodeIndex );
}
private void ComposeFilter( )
{
string actFilter = string.Format( "(ActionName LIKE '*{0}*')", txFilterAction.Text );
string defBindFilter = string.Format( "(Def_Binding LIKE '*{0}*')", txFilterDefBinding.Text );
string usrBindFilter = string.Format( "(Usr_Binding LIKE '*{0}*')", txFilterUsrBinding.Text );
string deviceFilter = "";
if ( ( chkJoystick.Checked == false ) && ( chkGamepad.Checked == false ) && ( chkMouse.Checked == false ) && ( chkKbd.Checked == false ) ) {
// none checked means all
deviceFilter = "( Device LIKE '*' )";
} else {
deviceFilter = "( Device='X'"
+ ( ( chkJoystick.Checked ) ? string.Format( " OR Device = 'joystick'" ) : "" )
+ ( ( chkGamepad.Checked ) ? string.Format( " OR Device = 'xboxpad'" ) : "" )
+ ( ( chkMouse.Checked ) ? string.Format( " OR Device = 'mouse'" ) : "" )
+ ( ( chkKbd.Checked ) ? string.Format( " OR Device = 'keyboard'" ) : "" )
+ " )";
}
m_bSrc.Filter =
actFilter + " AND " + defBindFilter + " AND " + usrBindFilter + " AND " + deviceFilter;
}
private void txFilterAction_TextChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void txFilterBinding_TextChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void txFilterUsrBinding_TextChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void btClrFilterAction_Click( object sender, EventArgs e )
{
txFilterAction.Text = "";
}
private void btClrFilterBinding_Click( object sender, EventArgs e )
{
txFilterDefBinding.Text = "";
}
private void btClrFilterUsrBinding_Click( object sender, EventArgs e )
{
txFilterUsrBinding.Text = "";
}
private void chkJoystick_CheckedChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void chkGamepad_CheckedChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void chkMouse_CheckedChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void chkKbd_CheckedChanged( object sender, EventArgs e )
{
ComposeFilter( );
}
private void FormTable_FormClosing( object sender, FormClosingEventArgs e )
{
if ( e.CloseReason == CloseReason.UserClosing ) {
this.Hide( );
e.Cancel = true;
}
}
private void FormTable_LocationChanged( object sender, EventArgs e )
{
LastLocation = this.Location;
}
private void FormTable_SizeChanged( object sender, EventArgs e )
{
LastSize = this.Size;
}
private void DGV_ColumnWidthChanged( object sender, DataGridViewColumnEventArgs e )
{
string setting = "";
foreach ( DataGridViewColumn col in DGV.Columns ) {
setting += string.Format( "{0};", col.Width.ToString( ) );
}
LastColSize = setting;
}
private void DGV_RowHeaderMouseClick( object sender, DataGridViewCellMouseEventArgs e )
{
EditRow( e.RowIndex );
}
private void DGV_CellMouseDoubleClick( object sender, DataGridViewCellMouseEventArgs e )
{
EditRow( e.RowIndex );
}
private void btUpdateFromEdit_Click( object sender, EventArgs e )
{
RaiseUpdateEditEvent( ); // accept will be done after updating the main tree
}
private void chkEditBlend_CheckedChanged( object sender, EventArgs e )
{
btUpdateFromEdit.Enabled = chkEditBlend.Checked;
DGV.ReadOnly = !chkEditBlend.Checked;
}
private void btCancelEdit_Click( object sender, EventArgs e )
{
bool test = DS_AMaps.HasChanges( );
DS_AMaps.RejectChanges( );
//m_bSrc.ResetBindings( false );
}
private void DGV_CellValueChanged( object sender, DataGridViewCellEventArgs e )
{
if ( e.ColumnIndex == DGV.Columns["Blended"].Index ) {
if ( ( bool )DGV.Rows[e.RowIndex].Cells[DGV.Columns["Blended"].Index].Value == true )
DGV.Rows[e.RowIndex].Cells[DGV.Columns["Usr_Binding"].Index].Value = DeviceCls.BlendedInput;
else
DGV.Rows[e.RowIndex].Cells[DGV.Columns["Usr_Binding"].Index].Value = ""; // don't know anything else...
}
}
}
}

@ -0,0 +1,414 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="dS_ActionMaps.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="dSActionMapsBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>152, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAD4AAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANvc
3yTb2+Ak29viJNvb4iTb2+Mk29rlJNvb5iTb3OYk29zmJNvd5yTb3uck293nJNvd5yTb3egk29vgJNvb
3STb2+Ak29vhJNvb4STb2+Ak29vhJNvb4CTb298k29vgJNvb3yTb294k29vfJNvb3STb290k29veJNvb
3STb298k29vhJNvb5CTb2+Yk29vmJNvb5CTb2+Ik29viJNvb4STb294k29vbJNvb2yTb29sk29vbJNvb
2yTb29sk29vbJNvb3STb294k29vcJNvb3iTb294k29vfJNvb3yTb298k29vfJNvb3STb29sk29vbJNvb
2yTb29sk29vbJNvb3CQHCDn6BQU/+gUFRvoFBE36BQlW+gUTYfoFHGj6BR1q+gUjbvoFKnX6BSp0+gUp
cvoFKXP6BSh0+gUWVPoFBDD6BQU7+gUFQfoFBUn6BQVE+gUFR/oFBUP6BQU7+gUFP/oFBTz6BQU4+gUF
NvoFBS36BQUv+gUFM/oFBTb6BQVB+gUFUvoFBWL6BQdx+gUGcfoFBVv6BQVO+gUFTPoFBUb6BQU1+gUF
KPoFBRr6BQUQ+gUFDvoFBQj6BQUG+gUFDfoFBSH6BQUw+gUFK/oFBTP6BQU4+gUFOfoFBT36BQU++gUF
NvoFBSX6BQUR+gUFCPoFBQX6BQUF+gUFBfoFBQb6AABE/wAASv8AAFH/AApZ/wAWZv8AI2//ACh2/wAn
dv8AL33/ADWD/wA1gv8AMX7/ADN//wAwfP8AKHT/AANI/wAAP/8AAEf/AABR/wAATf8AAEr/AABM/wAA
T/8AAE3/AABD/wAAQf8AAD7/AAA9/wAAOv8AADz/AABC/wAAUP8AAGX/AAB2/wAOhP8ACYD/AABj/wAA
Vv8AAFH/AABM/wAAQv8AADP/AAAg/wAAD/8AAAb/AAAH/wAADP8AABP/AAAj/wAALP8AADH/AAA4/wAA
P/8AAEL/AABE/wAAP/8AAB//AAAF/wAABP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIDU/8AA1b/ABRh/wAk
bv8AMHj/ADR9/wA1gf8ANYH/ADiF/wA/if8AQor/AD2G/wA+h/8AOoT/ADaA/wAcZv8AAEz/AABU/wAA
Vv8AAFP/AABS/wAAVP8AAF3/AABZ/wAAT/8AAEr/AABK/wAAUP8AAEz/AABL/wAAVP8AAGX/AAB0/wAO
g/8AIJL/ABiL/wADcf8AAF7/AABV/wAATv8AAEj/AAA5/wAAI/8AABH/AAAH/wAADP8AABX/AAAk/wAA
Lv8AADb/AAA4/wAAOf8AADf/AAA5/wAAN/8AAC3/AAAM/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
Af8CC13/AA5f/wAhbP8ALXn/ADWA/wA5hP8AOob/AD6K/wBCjP8ASI//AEqS/wBFjf8AQIn/ADqD/wA3
gP8AMXv/AAZX/wAAVv8AAFP/AABS/wAAVP8AAFf/AABc/wAAW/8AAFj/AABX/wAAW/8AAGL/AABd/wAA
X/8AAmn/AAZ5/wAMgv8AHI7/AC2e/wAnl/8ACnv/AABl/wAAW/8AAFH/AABK/wAAPf8AACn/AAAd/wAA
Ev8AABH/AAAY/wAAKv8AADf/AAA8/wAAOP8AAC7/AAAe/wAAFv8AABD/AAAI/wAAAv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAH/Ahln/wAYaP8AHmz/AC55/wA2gv8AOIX/ADqG/wBBi/8AR5D/AEuS/wBM
lP8ASpP/AEKL/wA6hP8AN4L/ADeB/wAaY/8AAEz/AABW/wAAUf8AAFT/AABa/wAAXf8AAFz/AABe/wAG
bf8ABG7/AAZv/wAGbv8AB3P/ABaB/wAaiv8AH5L/AC2e/wBArf8AOan/AByM/wAHc/8AAWr/AABg/wAA
Wf8AAFb/AABG/wAAL/8AACP/AAAn/wAAM/8AADX/AAA5/wAAOP8AADr/AAA2/wAAH/8AAA//AAAC/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAB/wIYZ/8AFmn/ABlo/wAjb/8AMHv/ADSB/wA8
hv8ARI3/AEqT/wBNlf8ATZb/AEyT/wBEi/8APYb/ADuE/wA+hv8AM33/AAJJ/wAATv8AAFP/AABU/wAA
XP8AAF3/AABj/wAAZ/8ADHX/AA95/wATfP8AGIH/ABuE/wAmlP8ALJz/ADGi/wBArv8AVL3/AFC5/wAy
n/8AHIb/ABV//wAQev8AA2//AABn/wAAXv8AAEv/AABE/wAARf8AAEj/AAA//wAAPf8AADz/AABD/wAA
Pv8AACf/AAAW/wAACv8AAAf/AAAQ/wAADP8AAAP/AAAA/wAAAP8AAAD/AAAA/wAAAf8CHGv/AB1r/wAh
bf8AJ3D/ADF4/wAzfP8AOYD/AEKJ/wBJkv8AS5P/AE2U/wBNk/8ASY//AESM/wBGjP8ASI7/AESM/wAT
W/8AAEj/AABS/wAAXf8AAGH/AABn/wAAb/8AAnL/AAt8/wAQfv8AIYn/ACyV/wA1m/8AO6T/AESt/wBM
tf8AWL//AG3K/wBuyP8AULT/ADyd/wA3lv8ALpP/AByH/wAPe/8ACnX/AAlt/wAIZ/8ABGH/AAJb/wAB
WP8AAFb/AABQ/wAARf8AADb/AAAn/wAAH/8AABf/AAAV/wAAG/8AAAv/AAAB/wAAAP8AAAD/AAAA/wAA
AP8AAAH/Ai13/wAod/8AKXf/AC54/wA1fP8AO4H/ADuC/wBFif8AUJX/AFWX/wBZmf8AXJr/AFyY/wBZ
mP8AV5j/AFWY/wBRlv8AMHz/AABS/wAAXv8AAGf/AABt/wAAc/8ABXj/AA5+/wAUhf8AGoj/AC2V/wA7
of8ARKj/AFK0/wBjwf8Ab8v/AHnT/wCR3P8Ak9z/AHrN/wBmuv8AWrH/AE2p/wBAov8AO5v/ADiX/wA1
k/8ALYr/ACSA/wAVeP8ABnD/AAFi/wAAU/8AAEX/AAAw/wAAKv8AACf/AAAi/wAAGv8AABX/AAAE/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAB/wITQf8AEUD/ABRH/wAUTv8AGlX/ACJh/wAnav8AOHj/AFCK/wVj
mf8QcKL/EnWn/wxzpv8Gbab/AGSi/wBhoP8AXqD/AFWZ/wARc/8ACXT/ABF7/wATgP8AFYH/AB2K/wAg
jv8AI5H/ACeU/wA2nv8AQqb/AFWw/wBuxv8AUrv/ADKs/wBDs/8AcM//BJLb/wCD0/8AaMH/AHXF/wBw
wf8Abb3/AGu7/wBkuP8AWbD/AEql/wA2lf8AIYH/AA1z/wABZf8AAFL/AABE/wAAM/8AACz/AAAm/wAA
Jf8AACf/AAAv/wAAHf8AAAj/AAAA/wAAAP8AAAD/AAAA/wAAAf8BABP/AAAP/wAAF/8AACL/AAAt/wAA
PP8ADE//AClm/wBEfP8BWIz/BGOW/wRlmv8CWpf/AU2R/wBHk/8APY//AEaV/wBUnf8AUJz/AFWh/wBi
q/8AZq//AF6s/wBarP8AWK3/AFCq/wBQq/8AUq//AF60/wBww/8AQ63/ABaM/wEnmf8AP6r/Ale8/xOG
0v8KbsH/B2q1/wKZ0/8AoNr/AJrY/wCO0/8AgMr/AGq//wBSrv8APZz/ACqK/wAXeP8ABWf/AABZ/wAA
Tf8AAD7/AAA1/wAALf8AACn/AAAf/wAAG/8AABD/AAAE/wAAAP8AAAD/AAAA/wAAAP8AAAH/AQIH/wAA
B/8AAAz/AAAT/wAAHv8AATf/ABJR/wAmYf8AN3L/ADt4/wA1d/8AMHf/ADF6/wAtef8AMoD/ADaG/wBB
k/8ATJv/AF6n/wBys/8CicP/CpfO/w2Z0P8Jlc7/BZHN/wKNzf8Aicv/AIvM/wCOz/8AUKf/ADWS/wBi
tP8Hh87/AIjU/zW75/+Q7vv/auH3/1bZ9f9Kz/D/Ncft/xm36P8Fotz/AIrR/wB1xf8AXrb/AEyn/wA7
mf8AJ4j/ABZ3/wADa/8AAF3/AABQ/wAAQP8AAC//AAAj/wAAFP8AAA7/AAAF/wAADP8AABj/AAAK/wAA
AP8AAAD/AAAB/wICHP8AABz/AAAp/wABM/8ACj7/ABhS/wAgWv8AJGH/ACZn/wAhZP8AIWP/ACtt/wA7
ff8AQ4X/AFCP/wBbmv8AWZz/AFuf/wBco/8AVKL/AGWu/wN5u/8Ih8T/CpTL/w+e0/8Podb/CaDW/w+l
2/8Bcrv/AFWh/wBwt/8Ag8j/AJrZ/wKx5/9S2fT/5v7//8D1/v+g7Pv/geT5/2DX8/87xez/GLLj/wKg
2v8AjdL/AHzE/wBsuf8AW67/AEqf/wA5kv8AJYP/ABZz/wASbv8AClz/AAVG/wACOf8AASX/AAAQ/wAA
F/8AACT/AAAe/wAABf8AAAD/AAAA/wAAAf8BAiP/AAAo/wAAOv8AC0n/ABxZ/wAqZP8ALmf/ACNj/wAd
Yf8AJmX/ADFt/wA/ev8ATIj/AE2O/wBRkv8AYJ7/AnGr/wd7s/8MgLn/D4O9/wyFv/8Dg7//BonD/xmZ
zv8jpNb/KKnZ/yWs2/8Fi8v/BHm6/wuUy/8Qo9f/Hq3e/xm45/820/T/w/T8///////p/v7/sO/8/37g
9v9X0PD/Nb/o/xuv4f8En9j/AI/O/wB7wv8Aa7j/AF+w/wBVpv8ASZv/ADuR/wAxiP8AJnz/ABtx/wAQ
Zf8AB1f/AARN/wAAP/8AAkn/AAFC/wAALP8AABP/AAAC/wAAAf8AAAP/AQIZ/wAAKv8ABEL/ABtX/wAo
Y/8ALmf/AChh/wAeWv8AE1P/ABFV/wATWv8AFWH/ABpn/wAca/8AIXH/ADCA/wBNl/8BaKr/Bn65/xaR
xf8hmsz/HJvO/xyczv81rNj/R7je/1fB4/8tr9v/IaLQ/0G43f9BwOX/YdHu/4zo+f9x5fj/uvX9////
////////9v///7vy/P+C4Pb/Vc3u/zK85f8Tqdz/BZTS/wGGxv8AdL7/AGW0/wBdrv8ATqL/AESY/wA+
j/8ANoj/AC5+/wAldP8AGmn/AAxd/wAEVP8AAVL/AABM/wAAQP8AADP/AAAi/wAADP8AAAb/AgIM/wEB
Cv8AAB3/AAQ9/wAMS/8AFlL/ABlT/wASTP8ADkb/AA9J/wAOTf8ABkf/AAA7/wAARP8ABlj/ABhs/wAp
e/8APov/AFCb/wBfp/8AcbL/BoO9/xaSx/8uodD/SrHa/2PA4v9Etd7/PK/X/1m93/9vyuf/Ycjo/4XZ
8f9g1PH/feD2//b9/////////////+7+///B9P3/kOX5/2nW8v9Ox+v/Lrbk/xOm3P8Jntb/AI3N/wB6
v/8AbLX/AFWk/wBHmP8AOo7/ACyC/wAgdf8AFmr/AA5g/wAJVv8AA0j/AANK/wABRP8AADn/AAAx/wAA
K/8AACP/AAAZ/wICGf8BAB//AAA1/wAUU/8AHlv/AB9c/wAYVv8ABUX/AAE+/wABPv8AADb/AAAo/wAD
MP8ABUv/AApf/wAOZv8AEGj/ABxz/wAuhP8AQpL/AFSd/wBqq/8Lgrn/NJvJ/0+s1f8+p9P/QqfQ/3TC
4P+Ayub/gc7p/3/M5/990u3/XMrr/7zs+P/9////+v////T////Y+f7/sO/8/4ji9/9m1PL/SMXr/yay
4v8IoNf/ApXS/wCIy/8AfML/AG+5/wBeqP8AVJ7/AEuW/wBAif8ANHz/ACZv/wAbZf8AFlr/AAtH/wAH
O/8AAy//AAEn/wAAHv8AACD/AAAp/wAAMP8CAzX/Aixn/wAybP8AQHf/AEl//wBIgf8AN3P/ACFe/wAb
WP8AE1X/AAxP/wANUf8AEFz/AA5g/wAKX/8AC2H/ABxw/wAyhf8APo//AEqW/wBgov8OerL/LJDA/zCT
xv8pksP/UabP/3/B3/+Ozef/gszn/3TF4/+Z1uz/e87r/5TZ8P/p/P7/8v///+/////c+v7/wvP9/6Ho
+P932fP/Scbr/y+45f8Uq93/AJrU/wCJyv8AecD/AGu0/wBZpv8ATJj/AEWQ/wBAjP8AOIP/ADF5/wAs
cP8AKG3/ACRn/wAaYP8ADU//AAM//wABOP8AAjP/AAU7/wAIPf8AAi7/AQMe/wJYkP8AX5T/AGaX/wBr
nf8Ab6H/AGue/wBjlv8DZ5f/C2uc/wFPjP8ANnn/ACZv/wAfa/8AIW//ACNw/wAsdP8AO4D/AEaJ/wBa
mP8Jcaj/JYW3/zeWxP85k8L/Z6/P/4DB3/9qutz/OaHO/yyZyf+Ax+L/i9Tr/1jA5P9JvOT/WsHn/6fh
8v+m4PT/xvP8/7rw/f+T4fX/Zs3u/ze35P8TpNn/AJXQ/wCMzP8Ahcb/AH3B/wBos/8AVaL/AEaT/wA3
hP8ALnn/ACVv/wAgZv8AHGD/ACNm/wAhZv8AF1z/AApJ/wAEPv8AAz3/AANC/wACQ/8AA0D/AAI+/wIE
Nv8CVov/AFuP/wBhlv8AYZj/AGGY/wBil/8FaJr/HHqp/xlonP8CSon/AEqI/wBSj/8AWJP/AFuV/wBa
k/8AVo7/AFqR/wBHgf8AMGv/AlOI/x56qf9Mm8L/dLPT/4TC3f9Op87/EHiy/wBZnv8AXaD/F4i//xuM
xf8QgsL/AHG7/wBgt/8Aa7z/AG/B/ziZ0v+b3PL/jN/2/1HB5/8jqtz/CprS/wCBxP8Ab7n/AGaw/wBm
r/8AXav/AFWi/wBKl/8AOIX/ACly/wAeZv8AFFv/AA1S/wAPU/8ADVL/AAVH/wACQP8AATz/AAI6/wAC
Of8AADT/AAAw/wAAMv8CAzP/AluP/wBjkv8AbJr/AGyd/wBnmv8BYJT/GmmW/y5/p/8ocpr/JWiS/x5g
jv8XXYv/EF2L/wdcjP8GXoz/CGqV/wBEcv8ADDf/AClc/xpsmP9DkLb/cK/O/3O31P8/nMf/BVub/wAv
eP8AR4z/Bmqp/wBNmf8ARJP/ADuR/wAtif8AN5b/AE+o/wBetP8AW7L/E2qz/1as1f9Vv+T/KKjY/wiT
zf8Aer7/AFyp/wBHlf8AQI7/ADyM/wA+i/8APIf/ADV//wArdP8AHmb/ABFY/wAITP8ABkf/AApK/wAL
Sv8ACEX/AAI//wABNv8AAC7/AAAr/wAAKf8AACv/AgMu/wJck/8AZ5j/AHGd/wByn/8Abp//AGea/w5h
lf8cZpX/JWqS/zZ6mv9Ii6P/V5mp/2Kjr/9hoq3/hbK3/2+arf8AABD/ABRA/wFBb/8wf6H/Wp29/1yl
xv8lgrL/AEOC/wAVXP8AIGb/AC52/wpgov8BLn7/ABZp/wAIYf8AGnb/ADGF/wBYp/8AZrL/AGCy/wBF
mf8AQ5D/Qp/L/ziw2v8OlMv/AHy7/wBhp/8ASpP/ADOA/wAjcv8AGmb/ABpj/wAeZv8AHmP/ABpc/wAT
Vv8AC07/AAhL/wALTv8ACEj/AAlF/wAGQ/8ABD3/AAAw/wAAKP8AACL/AAAi/wIDKf8CWJL/AGeb/wBv
nv8AdKP/AXGi/w5qnP8acKD/G26f/xZfkv8PToP/DEp+/wxNf/8XXoj/PICa/4a1v/87U2P/AAAJ/wAZ
Rf8HUHj/MXqf/y2Bp/8HWo3/ACNh/wABPP8AAz3/ABVW/wAsdv8AE1D/AAlB/wAAN/8AAEb/AAZg/wAa
cP8APY//Alun/wFVpv8AMYX/BDB6/0ijy/83rNj/Do7G/wB1tP8AZKf/AFGZ/wA9if8AJHP/ABJe/wAG
Uf8AAkX/AAZH/wALSf8ACkf/AAtL/wAPVf8AD1X/AAVJ/wAGR/8AB0X/AAI9/wAANv8AACv/AAAg/wAA
HP8CAx//AVeQ/whpm/8ui7T/M4+4/yB9qv8aapz/GWeY/xhqmf8XZpX/FVuN/xZakf8SVI3/CU2G/wpU
iv8LVIf/AAQN/wAAB/8AHEX/DFt//xRpkP8BQXX/ABFE/wAAGf8AABv/AAAO/wAJL/8ACUD/AAAV/wAA
Cv8AABb/AAAo/wAAPP8ABFH/ABJt/wAjfv8ANoz/AAth/wIITf9JnMP/RbLd/yKbzf8LicL/A3u4/wBt
r/8AX6j/AEiW/wA9if8AI3D/ABJY/wAJTP8AB0f/AAZH/wAFR/8ACk//AApS/wAFTf8ABEn/AAJE/wAC
Q/8AADz/AAAu/wAAIv8AABv/AgMd/wVTj/8cbJz/VqLG/ziNuP8ieKP/FWWU/xNhk/8VY5L/FF6M/xBQ
gP8QS37/E1OJ/xRTiP8QVIb/BEZ+/wAACf8AAA//AB9L/wFNd/8BSHX/ABxR/wABKf8AAAH/AAAA/wAA
AP8AAAr/AAAC/wAAAP8AAAD/AAAF/wAGMv8AATf/AABF/wABV/8AEmv/ABZw/wAAQv8ZMGX/UbLa/0Kt
2P8wptP/HpzP/wuQyP8AgcD/AG6v/wBgp/8AWqH/AFOb/wBGjf8AMnz/ACl2/wATXP8ACVH/AAtT/wAQ
Wf8AGmD/ABhf/wARWP8ADFH/AABA/wAAOP8AADX/AAAv/wICL/8HUIr/FGCU/zqNtv8ziLb/Kn2m/xxy
nf8TYZD/FV6I/xVhjP8VXYz/EUx//w9Fef8IPnD/AjZg/wAWKv8AAAb/AAEa/wATQf8AGkn/ABM//wAm
U/8AF0f/AAAD/wAAAP8AAAP/AAAC/wAAAP8AAAD/AAAA/wAAB/8AAxb/AAEX/wAALf8AAED/AAJX/wAA
VP8IFFj/O5C8/z6o0/8zo8//HpbI/w2Oxf8Ci8T/AIC+/wBxr/8AaKr/AGut/wBprP8AYKf/AGCm/wBW
nv8AKnX/ABVe/wAUYP8AGWL/ACRp/wAqcv8AHGT/AAtQ/wAGS/8ADlP/AAxQ/wAITf8CC0//AkV+/whG
eP8aaZX/KoCs/yp8pP8oeqD/F2WO/xFSef8SVnz/F2CH/xdii/8OWYX/AS9R/wAFDf8AAAD/AAAA/wAA
Bv8AAA7/Aw8v/wI5Yv8AKVr/AAQr/wAAA/8AAAL/AAEG/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAX/AAgz/wMGVv8UMHj/KYKz/x+Nuv8Nfa//BXet/wBzq/8AdK3/AH64/wB0rf8AZKL/AGCi/wBu
rv8AcK//AGus/wBmp/8AX6D/AFab/wBIjv8ARY3/AC12/wAtcv8AIGb/ABJX/wAKSf8ABUP/AAxM/wAJ
S/8ACU3/AhNV/wJKif8AOW3/BUpz/xppk/8gc53/InKZ/xttkv8UWYD/EUx0/xFTd/8LV3v/Ai5F/wAB
A/8AAAD/AAAA/wAAAP8AAAD/BRIg/yttkf8CKVv/AAAg/wAACP8AAAD/AAcO/wAECv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAK/wADMv8GM3X/LpfC/y2YxP8Sfq7/AHGk/wBsov8AbqX/AG6m/wBp
pP8AZZ//AGGf/wBamv8AVZP/AFSO/wBSjv8AU5T/AE6P/wBMjf8AV5j/AEiJ/wA5ff8AMnP/ACNk/wAY
WP8ADEn/AAQ7/wACNv8ABDL/AAQp/wIFJv8CWJn/ADp2/wA6af8QU3z/F2CL/xVdh/8WYIT/F2SI/xFa
g/8DOVn/AA0X/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAUJ/x5kff9HncD/GkRz/wAAAP8AAAD/AAAA/wIS
IP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAf8AAAD/AAAC/wAPNf8AIF//KoO0/zqjz/8njLz/DXir/wBr
nv8AZpv/AGmh/wBrpf8AaaP/AGOc/wBdmf8AW5X/AFeQ/wBVjv8AVo//AFiW/wBbm/8AW5r/AFWW/wBQ
jv8AR4L/ADV3/wAlaf8AFlb/AAtA/wAGMP8ABDD/AAIv/wAAKv8CAi3/Aj96/wAuZf8AJ1f/BDhi/w9M
df8RT3j/Dkty/w9UeP8ENU7/AAQI/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAB/wcNEf8OLDr/L3mZ/zuI
ov8eUG3/Bhov/wIJEP8CERv/AAML/wAAAP8AAAD/AAAA/wAAAP8AAAX/AQkP/wIcNf8VSHj/NI27/z2g
zP8okcL/FICx/wRuov8AZpn/AGSY/wBnnf8AaqP/AGym/wBnn/8AZJv/AGOa/wBimP8BXpb/AVyW/wBa
lv8AV5P/AFKM/wBOh/8ATIb/AEiD/wA/ff8ANHT/ACtn/wAhXP8AGFj/AAxS/wACSv8AADz/AgMx/wIi
WP8AHE//AB9O/wAmVv8BOmT/Bj1o/wQsV/8AFCX/AAAA/wAAAP8AAAD/AAMJ/wABCP8GAgH/BgoL/wAD
CP8KJS3/ByU3/xYzSf8waoH/LnOW/0aMrv9Nian/OWuI/yJPbv8TLUL/Chgm/wkZIv8hQVb/O3CO/0aL
r/8+irH/P5O9/zWTvv8ki7v/GYK2/whwo/8AXpL/AFWK/wBPhv8AU4r/AFiR/wFYk/8AUo7/AE6I/wBN
h/8ATYn/AE+M/wBUjf8AVpL/AFaS/wBWjP8AVov/AFeM/wBTif8ASIH/ADt0/wApZf8AGFX/AA1E/wAE
NP8AACf/AAAa/wEBEv8CHlX/ABpR/wAeU/8AH1L/AB9I/wAaPv8ABhT/AAAA/wAAAP8DCxP/ABkv/wBE
b/8AQHL/Ay5X/wMLGP8AAAD/AAAA/wALFf8TRWP/JWqM/y54mf82fJ3/OH2c/z2Bof8+g6b/PYWp/zuB
p/87g6f/RpC1/0GMs/8ygqn/J3un/xpyo/8QbaP/CW2k/wVnoP8BU4z/AER7/wBCd/8AQXn/AEaB/wBR
iv8AWI7/AFiP/wBVjf8AU4v/AFOL/wBOiP8ASoX/AEmG/wBCgP8AN3P/AC9q/wAmX/8AHlX/ABNH/wAK
Pv8ABC//AAEY/wAABP8AAAD/AAAA/wAAAP8AAAD/AhlY/wAVT/8AEUL/AAg2/wACFv8AAAP/AAAA/wAA
AP8AAQH/CDha/wA8cf8APWT/ADJN/wAXIf8AAAD/AAMJ/wAZLv8ANlr/Bkxv/wtFaf8HPmb/BkJp/wNB
Z/8ERmz/B091/wxagf8WZYr/G2qP/xhskf8WbJX/D2qW/wdpl/8DZZn/AGGW/wBgmf8AWpf/AEeB/wA5
b/8ANGr/AC9o/wAuav8AL27/ACxq/wAmZP8AIF3/ABlW/wATUP8ADUX/AAhE/wAFRf8AA0X/AAA7/wAA
Mv8AACX/AAAd/wAAGf8AABv/AAAR/wAAAf8AAAD/AAAA/wAAAP8AAAD/AAAB/wIZYf8ACEf/AAEx/wAB
Nv8AACb/AAAM/wAAAP8ACSj/AAs6/wAIGf8AECn/AAYJ/wAAAP8AAAL/AA4k/wAiRP8ALlP/AC1R/wAr
Tf8AHz//ACBA/wAjRf8AJkf/ACtK/wAvUv8BNFn/AjRb/wIxXP8BL1//ASxg/wAqY/8AJWL/AB5b/wAY
W/8AFmX/ABFk/wAHRf8AAi//AAEn/wAALP8AAC//AAAz/wAANP8AADH/AAAu/wAAJ/8AACP/AAAe/wAA
Hv8AACD/AAAe/wAAGP8AABb/AAAU/wAADP8AAAb/AAAC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
Af8CJ3X/AA5c/wAGTP8ADlb/AApS/wAAHv8AAAD/AAYQ/wAJJf8AAAD/AAAA/wAABf8ACSb/ABVD/wAe
SP8AIUb/ACNK/wAkTP8AHT//AAAG/wAAAv8AAAL/AAAC/wAAAf8AAAT/AAAK/wAADv8AABP/AAAb/wAA
If8AACf/AAAl/wAAJ/8AADH/AABG/wAASP8AACv/AAAX/wAAFv8AABz/AAAh/wAAJv8AACj/AAAl/wAA
If8AAB3/AAAa/wAAGv8AABr/AAAX/wAAD/8AAAf/AAAB/wAABP8AAAL/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAH/AiJy/wAZa/8AF2f/ABdo/wAGOP8AAAD/AAED/wADGP8AAAD/AAAH/wAI
Kv8AE0n/ABxT/wAeUP8AHk//ACBN/wAiTf8AI1H/ABYz/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAv8AAAn/AAAN/wAADP8AABH/AAAf/wAANv8AADn/AAAg/wAAE/8AABf/AAAc/wAA
HP8AAB7/AAAf/wAAHv8AABz/AAAa/wAAHf8AAB7/AAAf/wAAIv8AAB7/AAAV/wAAC/8AAAb/AAAB/wAA
Af8AAAX/AAAC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAB/wIcbv8AFmn/ABFf/wATYv8DD0n/ChIe/wAB
AP8AEEH/AAtD/wAVUf8AGlz/ABpX/wAcUv8AH1T/AB9W/wAiV/8AI1X/ACFV/wALIP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAC/wAAEf8AACn/AAAu/wAA
Gf8AAA//AAAW/wAAIP8AAB//AAAa/wAAGv8AAB3/AAAb/wAAHf8AACr/AAAs/wAALP8AAC//AAAk/wAA
Hv8AABj/AAAN/wAAB/8AAAT/AAAE/wAAAv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAf8CEWf/AAlf/wAI
WP8AC1j/AxVc/wgZXP8AACL/AAYl/wAVXv8AG13/ABdY/wAVVP8AF1H/ABtT/wAdVP8AHlT/ABxQ/wAX
Sf8AAgv/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAv/AAAf/wAAI/8AAA//AAAG/wAAD/8AABn/AAAh/wAAGf8AABH/AAAQ/wAAEf8AAB7/AAAt/wAA
Lv8AADH/AAAn/wAAG/8AABT/AAAQ/wAAC/8AAAz/AAAJ/wAAB/8AAAH/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAH/AgRc/wAAU/8AAFD/AABN/wACTf8AAEX/AABC/wADQv8ADlL/ABFS/wAPUP8ADlD/ABFM/wAW
Tv8AF0z/ABZK/wAVSf8ACzH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAF/wAAGP8AABn/AAAD/wAAAP8AAAX/AAAN/wAAGP8AAA3/AAAD/wAA
AP8AAAr/AAAb/wAAFP8AABf/AAAk/wAAGP8AAAz/AAAJ/wAAB/8AAAb/AAAL/wAACP8AAAb/AAAD/wAA
Af8AAAD/AAAA/wAAAP8AAAD/AAAB/wAAQ/8AADv/AAAy/wAALv8AACr/AAAl/wAAKv8AADj/AABA/wAA
QP8AAEH/AABA/wAEQP8ABD//AAM7/wACOv8AAjX/AAAM/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAb/AAAG/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAv8AAAD/AAAA/wAACf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
Af8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8fIUnlHR9D5R0fPOUdHznlHR855R0f
PuUdH0blHR9M5R0fVOUdH1XlHR9S5R0fUuUeIVXlHiJU5R4gTuUeH0zlHR495RoaHOUaGhvlGhob5Roa
G+UaGhvlGhob5RoaG+UaGhvlGhob5RoaG+UaGhvlGhsc5RobHOUaGxzlGhsc5RobHOUaGxzlGhse5Rob
IeUaGxzlGhsb5RobHOUaGxvlGhsb5RobG+UaGxzlGhsc5RobG+UaGxvlGhob5R0hJuUbHB7lGhsb5Rob
HOUaGxzlGhsc5RobHOUaGx3lGhsc5RobHeUaGxzlGhsc5RobHOUaGxzlGhob5RoaG+UaGhvl9fb3DPX2
9wz19vcM9fb3DPX29wz19vgM9fb4DPX2+Az19vgM9fb4DPX2+Az19vgM9fb4DPX2+Az19vcM9fb3DPX1
9Qzz8/MM8/PzDPPz8wzz8/MM8/P0DPPz9Azz8/QM8/P0DPPz9Azz8/QM8/P0DPPz9Azz8/QM8/P0DPPz
9Azz8/QM8/P0DPP09Azz9PQM8/P0DPPz9Azz8/QM8/P0DPPz9Azz8/QM8/P0DPPz9Azz8/QM8/T0DPPz
9Az19/gM8/T1DPPz9Azz8/QM8/P0DPPz9Azz9PQM8/T0DPPz9Azz8/QM8/P0DPPz9Azz8/QM8/P0DPPz
9Azz8/QM8/PzDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAP//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////8=
</value>
</data>
</root>

@ -4,6 +4,12 @@ using System.Text;
using System.Xml;
using System.IO;
using SCJMapper_V2.SC;
using SCJMapper_V2.Keyboard;
using SCJMapper_V2.Mouse;
using SCJMapper_V2.Gamepad;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
/// <summary>
@ -335,7 +341,6 @@ namespace SCJMapper_V2
/// Updates an actionCommand with a new input (command)
/// </summary>
/// <param name="devInput">The input command</param>
/// <param name="actionCmd">The actionCommand to update</param>
public void UpdateCommandFromInput( String devInput, int accIndex ) // ActionCommandCls actionCmd )
{
//log.Debug( "UpdateCommandFromInput - Entry" );

@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCJMapper_V2.SC;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
/// <summary>
@ -153,6 +156,22 @@ namespace SCJMapper_V2
return newAc;
}
/// <summary>
/// Updates an actionCommand with a new input (command)
/// </summary>
/// <param name="devInput">The input command</param>
public void UpdateCommandFromInput( String devInput, ActionCls.ActionDevice actionDevice) // ActionCommandCls actionCmd )
{
// Apply the input to the ActionTree
this.DevInput = ActionCls.BlendInput( devInput, actionDevice );
if ( ActionCls.IsBlendedInput( this.DevInput ) || string.IsNullOrEmpty( devInput ) ) {
this.ActivationMode = new ActivationMode( ActivationMode.Default ); // reset activation mode if the input is empty
}
}
/// <summary>
/// Strange behavior of SC - needs a proper multitap to accept ActivationModes
/// </summary>

@ -4,6 +4,8 @@ using System.Text;
using System.Xml;
using System.IO;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
/// <summary>

@ -1,9 +1,23 @@
using System;

#define USE_DS_ACTIONMAPS
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.IO;
using System.Data;
using SCJMapper_V2.SC;
using SCJMapper_V2.Table;
using SCJMapper_V2.Keyboard;
using SCJMapper_V2.Mouse;
using SCJMapper_V2.Gamepad;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
@ -71,7 +85,7 @@ namespace SCJMapper_V2
/// <summary>
/// Clears a read but not longer known entry
/// </summary>
public void Clear_jsEntry(int index)
public void Clear_jsEntry( int index )
{
m_js[index] = "";
m_GUIDs[index] = "";
@ -136,7 +150,7 @@ namespace SCJMapper_V2
/// </summary>
public List<CheckBox> InvertCheckList
{
set {
set {
m_invertCB = value;
m_options.InvertCheckList = m_invertCB;
}
@ -161,7 +175,7 @@ namespace SCJMapper_V2
// create the Joystick assignments
Array.Resize( ref m_js, JoystickCls.JSnum_MAX + 1 );
Array.Resize( ref m_GUIDs, JoystickCls.JSnum_MAX + 1 );
for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) {
for ( int i = 0; i < JoystickCls.JSnum_MAX; i++ ) {
m_js[i] = ""; m_GUIDs[i] = "";
}
@ -195,7 +209,7 @@ namespace SCJMapper_V2
newMaps.m_options = this.m_options;
newMaps.m_modifiers = this.m_modifiers;
for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) {
for ( int i = 0; i < JoystickCls.JSnum_MAX; i++ ) {
newMaps.jsN[i] = this.jsN[i]; newMaps.jsNGUID[i] = this.jsNGUID[i];
}
@ -223,13 +237,81 @@ namespace SCJMapper_V2
} );
if ( ACM == null ) {
; // this.Add( newAcm ); // no, add new
}
else {
} else {
ACM.Merge( newAcm ); // yes, merge it
}
}
#if USE_DS_ACTIONMAPS // see and (un)define on top of file to allow for editing the DataSet entities
public void toDataSet( DS_ActionMaps dsa )
{
dsa.Clear( );
if ( dsa.HasChanges( ) ) dsa.T_ActionMap.AcceptChanges( );
int AMcount = 1;
foreach ( ActionMapCls am in this ) {
DS_ActionMaps.T_ActionMapRow amr = dsa.T_ActionMap.NewT_ActionMapRow();
string amShown = DS_ActionMap.ActionMapShown(am.name, AMcount++);
amr.ID_ActionMap = amShown;
dsa.T_ActionMap.AddT_ActionMapRow( amr );
foreach ( ActionCls ac in am ) {
int ilIndex = 0;
while ( ac.inputList.Count > ilIndex ) {
DS_ActionMaps.T_ActionRow ar = dsa.T_Action.NewT_ActionRow();
ar.ID_Action = DS_ActionMap.ActionID( am.name, ac.key, ac.inputList[ilIndex].NodeIndex ); // make a unique key
ar.AddBind = ( ilIndex > 0 ); // all but the first are addbinds
ar.REF_ActionMap = amShown;
ar.ActionName = ac.name;
ar.Device = ac.device;
ar.Def_Binding = ac.defBinding;
ar.Def_Modifier = ac.defActivationMode.Name;
ar.Usr_Binding = ac.inputList[ilIndex].DevInput;
ar.Usr_Modifier = ac.inputList[ilIndex].ActivationMode.Name;
ar.Blended = DeviceCls.IsBlendedInput( ac.inputList[ilIndex].Input );
dsa.T_Action.AddT_ActionRow( ar );
ilIndex++;
}
}// each Action
}// each ActionMap
// finally
if ( dsa.HasChanges( ) )
dsa.AcceptChanges( );
}
public void updateDataSet( DS_ActionMaps dsa, string actionID )
{
foreach ( ActionMapCls am in this ) {
DS_ActionMaps.T_ActionMapRow amr = dsa.T_ActionMap.NewT_ActionMapRow();
foreach ( ActionCls ac in am ) {
int ilIndex = 0;
while ( ac.inputList.Count > ilIndex ) {
if ( actionID == DS_ActionMap.ActionID( am.name, ac.key, ac.inputList[ilIndex].NodeIndex ) ) {
DS_ActionMaps.T_ActionRow ar =dsa.T_Action.FindByID_Action(actionID);
ar.Usr_Binding = ac.inputList[ilIndex].DevInput;
ar.Usr_Modifier = ac.inputList[ilIndex].ActivationMode.Name;
ar.Blended = DeviceCls.IsBlendedInput( ac.inputList[ilIndex].Input );
ar.AcceptChanges( );
return;
}
ilIndex++;
}
}// each Action
}// each ActionMap
}
#endif
/// <summary>
/// Dump the ActionMaps as partial XML nicely formatted
/// </summary>
@ -248,7 +330,7 @@ namespace SCJMapper_V2
r += String.Format( " profileName=\"{0}\" \n", fileName.Replace( SCMappings.c_MapStartsWith, "" ) ); //AC2 add profilename
// now the devices (our addition)
for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) {
for ( int i = 0; i < JoystickCls.JSnum_MAX; i++ ) {
if ( !String.IsNullOrEmpty( jsN[i] ) ) r += String.Format( "\tjs{0}=\"{1}\" ", i + 1, jsN[i] );
if ( !String.IsNullOrEmpty( jsNGUID[i] ) ) r += String.Format( "js{0}G=\"{1}\" \n", i + 1, jsNGUID[i] );
}
@ -265,12 +347,12 @@ namespace SCJMapper_V2
dr.devType = KeyboardCls.DeviceClass; dr.instNo = 1; m_uiCustHeader.AddInstances( dr );
dr.devType = MouseCls.DeviceClass; dr.instNo = 1; m_uiCustHeader.AddInstances( dr );
// do we use Gamepad ??
if ( GamepadCls.RegisteredDevices>0 ) {
if ( GamepadCls.RegisteredDevices > 0 ) {
dr.devType = GamepadCls.DeviceClass; dr.instNo = 1; m_uiCustHeader.AddInstances( dr );
}
// all Joysticks
for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) {
for ( int i = 0; i < JoystickCls.JSnum_MAX; i++ ) {
if ( !String.IsNullOrEmpty( jsN[i] ) ) {
dr.devType = JoystickCls.DeviceClass; dr.instNo = i + 1; m_uiCustHeader.AddInstances( dr );
}
@ -325,12 +407,11 @@ namespace SCJMapper_V2
if ( version == "0" ) version = ACM_VERSION; // update from legacy to actual version
// get the joystick mapping if there is one
for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) {
for ( int i = 0; i < JoystickCls.JSnum_MAX; i++ ) {
jsN[i] = reader[String.Format( "js{0}", i + 1 )];
jsNGUID[i] = reader[String.Format( "js{0}G", i + 1 )];
}
}
else {
} else {
return false;
}
}
@ -341,30 +422,25 @@ namespace SCJMapper_V2
while ( !reader.EOF ) { //!String.IsNullOrEmpty( x ) ) {
if ( reader.Name.ToLowerInvariant() == "actionmap" ) {
if ( reader.Name.ToLowerInvariant( ) == "actionmap" ) {
String x = reader.ReadOuterXml( );
ActionMapCls acm = new ActionMapCls( );
if ( acm.fromXML( x ) ) {
this.Merge( acm ); // merge list
}
}
else if ( reader.Name.ToLowerInvariant( ) == "customisationuiheader" ) {
} else if ( reader.Name.ToLowerInvariant( ) == "customisationuiheader" ) {
String x = reader.ReadOuterXml( );
m_uiCustHeader.fromXML( x );
}
else if ( reader.Name.ToLowerInvariant( ) == "deviceoptions" ) {
} else if ( reader.Name.ToLowerInvariant( ) == "deviceoptions" ) {
String x = reader.ReadOuterXml( );
m_deviceOptions.fromXML( x );
}
else if ( reader.Name.ToLowerInvariant( ) == "options" ) {
} else if ( reader.Name.ToLowerInvariant( ) == "options" ) {
String x = reader.ReadOuterXml( );
m_options.fromXML( x );
}
else if ( reader.Name.ToLowerInvariant( ) == "modifiers" ) {
} else if ( reader.Name.ToLowerInvariant( ) == "modifiers" ) {
String x = reader.ReadOuterXml( );
m_modifiers.fromXML( x );
}
else {
} else {
reader.Read( );
}

@ -4,7 +4,15 @@ using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using SCJMapper_V2.Properties;
using SCJMapper_V2.SC;
using SCJMapper_V2.Table;
using SCJMapper_V2.Keyboard;
using SCJMapper_V2.Mouse;
using SCJMapper_V2.Gamepad;
using SCJMapper_V2.Joystick;
namespace SCJMapper_V2
{
@ -30,8 +38,7 @@ namespace SCJMapper_V2
public TreeView Ctrl
{
get { return m_ctrl; }
set
{
set {
m_ctrl = value;
// copy props needed
m_MasterTree.Font = m_ctrl.Font; // assign font to master tree as well
@ -102,8 +109,7 @@ namespace SCJMapper_V2
public Boolean CanAssignBinding
{
get
{
get {
if ( Ctrl.SelectedNode == null ) return false;
else return ( Ctrl.SelectedNode.Level == 1 ) || ( Ctrl.SelectedNode.Level == 2 );
}
@ -111,8 +117,7 @@ namespace SCJMapper_V2
public Boolean CanBlendBinding
{
get
{
get {
if ( Ctrl.SelectedNode == null ) return false;
else return ( Ctrl.SelectedNode.Level == 1 );
}
@ -120,8 +125,7 @@ namespace SCJMapper_V2
public Boolean CanClearBinding
{
get
{
get {
if ( Ctrl.SelectedNode == null ) return false;
else return ( Ctrl.SelectedNode.Level == 1 ) && IsMappedAction;
}
@ -130,8 +134,7 @@ namespace SCJMapper_V2
public Boolean CanAddBinding
{
get
{
get {
if ( Ctrl.SelectedNode == null ) return false;
else return ( Ctrl.SelectedNode.Level == 1 ) && IsMappedAction;
}
@ -139,8 +142,7 @@ namespace SCJMapper_V2
public Boolean CanDelBinding
{
get
{
get {
if ( Ctrl.SelectedNode == null ) return false;
else return ( Ctrl.SelectedNode.Level == 2 );
}
@ -148,8 +150,7 @@ namespace SCJMapper_V2
public Boolean IsMappedAction
{
get
{
get {
if ( ( Ctrl.SelectedNode.Level == 0 ) || ( Ctrl.SelectedNode.Level > 2 ) ) return false; // not on node
if ( Ctrl.SelectedNode == null ) return false; // no node selected
if ( Ctrl.SelectedNode.Parent == null ) return false; // ERROR EXIT
@ -233,8 +234,7 @@ namespace SCJMapper_V2
/// </summary>
public List<CheckBox> InvertCheckList
{
set
{
set {
if ( ActionMaps != null ) ActionMaps.InvertCheckList = value; // just propagate if possible
else {
log.Error( "ActionTree-InvertCheckList: Program error - ActionMaps not yet created" );
@ -260,8 +260,7 @@ namespace SCJMapper_V2
// could be a gamepad then
if ( ActionTreeNode.CommandFromNodeText( nodeText ).Contains( "xi_" ) ) {
return m_gamepad;
}
else return null; // nope...
} else return null; // nope...
}
}
return null;
@ -289,8 +288,7 @@ namespace SCJMapper_V2
// must update the devices and instances for inversion before dumping the XML
UpdateDeviceInformation( );
return ActionMaps.toXML( fileName ); // just propagate if possible
}
else {
} else {
log.Error( "ActionTree-toXML: Program error - ActionMaps not yet created" );
return "";
}
@ -369,8 +367,7 @@ namespace SCJMapper_V2
foreach ( ActionTreeNode stn in tn.Nodes ) {
if ( ( stn.Tag != null ) && ( ( Boolean )stn.Tag == true ) ) {
; // don't create it i.e hide it - though you cannot hide TreeViewNodes at all...
}
else {
} 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
@ -484,8 +481,7 @@ namespace SCJMapper_V2
cn.ImageKey = devID; cn.BackColor = Color.White; // some stuff does not work properly...
if ( ActivationMode.IsDefault( defActivationModeName ) ) {
cn.NodeFont = FontAction;
}
else {
} else {
cn.NodeFont = FontActionActivated;
}
Array.Resize( ref cnl, cnl.Length + 1 ); cnl[cnl.Length - 1] = cn;
@ -508,8 +504,7 @@ namespace SCJMapper_V2
cn.Command = ac.defBinding; cn.BackColor = JoystickCls.JsNColor( jNum );
}
}
}
else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Gamepad ) {
} else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Gamepad ) {
acc.DevID = GamepadCls.DeviceID;
if ( applyDefaults ) {
if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -517,8 +512,7 @@ namespace SCJMapper_V2
cn.Command = ac.defBinding; cn.BackColor = GamepadCls.XiColor( );
}
}
}
else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Keyboard ) {
} else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Keyboard ) {
acc.DevID = KeyboardCls.DeviceID;
if ( applyDefaults ) {
if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -526,8 +520,7 @@ namespace SCJMapper_V2
cn.Command = ac.defBinding; cn.BackColor = KeyboardCls.KbdColor( );
}
}
}
else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Mouse ) { // 20151220BM: add mouse device (from AC 2.0 defaultProfile usage)
} else if ( ac.actionDevice == ActionCls.ActionDevice.AD_Mouse ) { // 20151220BM: add mouse device (from AC 2.0 defaultProfile usage)
acc.DevID = MouseCls.DeviceID;
if ( applyDefaults ) {
if ( !String.IsNullOrEmpty( ac.defBinding ) ) {
@ -539,7 +532,7 @@ namespace SCJMapper_V2
}
}//for
tn = new ActionTreeNode( acm.name, cnl ); tn.Name = acm.name; tn.Action = acm.name; // name it to find it..
tn = new ActionTreeNode( acm.name, cnl ); tn.Name = acm.name; tn.Action = acm.name; // name it to find it..
tn.ImageIndex = 0; tn.NodeFont = FontActionmap; // new Font( m_MasterTree.Font, FontStyle.Bold );
m_MasterTree.BackColor = Color.White; // fix for defect TreeView (cut off bold text)
m_MasterTree.Nodes.Add( tn ); // add to control
@ -587,8 +580,7 @@ namespace SCJMapper_V2
ActionCommandCls acc = ac.FindActionInputObject( ActionTreeNode.CommandFromNodeText( atn.Text ) ); if ( acc == null ) return am; // ERROR exit
am = new ActivationModes( ac.defActivationMode, acc.ActivationMode ); // policy: get the default first, then the attached one
return am;
}
else if ( Ctrl.SelectedNode.Level == 2 ) {
} else if ( Ctrl.SelectedNode.Level == 2 ) {
// this is a child of an action with further commands
ActionTreeNode patn = ( Ctrl.SelectedNode.Parent as ActionTreeNode ); // the parent treenode
ActionTreeNode atn = ( Ctrl.SelectedNode as ActionTreeNode ); // the treenode from a level 1
@ -621,14 +613,12 @@ namespace SCJMapper_V2
// 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 = new ActivationMode( ActivationMode.Default );
}
else {
} else {
acc.ActivationMode = ActivationModes.Instance.ActivationModeByName( newActivationModeName );
}
atn.UpdateAction( acc ); UpdateMasterNode( atn );
Dirty = true;
}
else if ( Ctrl.SelectedNode.Level == 2 ) {
} else if ( Ctrl.SelectedNode.Level == 2 ) {
// this is a child of an action with further commands
ActionTreeNode patn = ( Ctrl.SelectedNode.Parent as ActionTreeNode ); // the parent treenode from a level 2
ActionTreeNode atn = ( Ctrl.SelectedNode as ActionTreeNode ); // the treenode from a level 2
@ -639,8 +629,7 @@ namespace SCJMapper_V2
// 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 = new ActivationMode( ActivationMode.Default );
}
else {
} else {
acc.ActivationMode = ActivationModes.Instance.ActivationModeByName( newActivationModeName );
}
atn.UpdateAction( acc ); UpdateMasterNode( atn );
@ -674,11 +663,14 @@ namespace SCJMapper_V2
ac.UpdateCommandFromInput( ActionCls.DevInput( input, inKind ), acc.NodeIndex + 1 );
atn.UpdateAction( acc ); UpdateMasterNode( atn );
Dirty = true;
}
else if ( Ctrl.SelectedNode.Level == 2 ) {
} else if ( Ctrl.SelectedNode.Level == 2 ) {
// this is a child of an action with further commands
ActionTreeNode patn = ( Ctrl.SelectedNode.Parent as ActionTreeNode ); // the parent treenode from a level 2
ActionTreeNode atn = ( Ctrl.SelectedNode as ActionTreeNode ); // the treenode from a level 2
if ( string.IsNullOrEmpty( input ) )
atn.Action = "UNDEF"; // apply UNDEF
else
atn.Action = ""; // remove UNDEF
ActionCls ac = FindActionObject( patn.Parent.Name, patn.Name ); // the related action in an actionmap
if ( ac == null ) return false; // ERROR exit
if ( checkKind && ( ac.actionDevice != inKind ) ) return false; // ERROR exit
@ -696,16 +688,16 @@ namespace SCJMapper_V2
/// Find an action with name in a actionmap
/// </summary>
/// <param name="actionMap">The actionmap name</param>
/// <param name="action">The action</param>
/// <param name="actionKey">The action</param>
/// <param name="devInput">The input</param>
/// <returns>An actionCommand or null if not found</returns>
private ActionCommandCls FindActionInputObject( String actionMap, String action, String devInput )
private ActionCommandCls FindActionInputObject( String actionMap, String actionKey, String devInput )
{
log.Debug( "FindActionInputObject - Entry" );
//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 ( ACM != null ) ac = ACM.Find( delegate ( ActionCls _AC ) { return _AC.key == actionKey; } );
if ( ac != null ) acc = ac.inputList.Find( delegate ( ActionCommandCls _ACC ) { return _ACC.DevInput == devInput; } );
if ( acc == null ) {
log.Error( "FindActionInputObject - Action Input not found in tree" );
@ -718,16 +710,16 @@ namespace SCJMapper_V2
/// Find an action with name in a actionmap
/// </summary>
/// <param name="actionMap">The actionmap name</param>
/// <param name="action">The action</param>
/// <param name="actionKey">The action</param>
/// <param name="input">The input</param>
/// <returns>An actionCommand or null if not found</returns>
private ActionCommandCls FindActionInputObject( String actionMap, String action, int index )
private ActionCommandCls FindActionInputObject( ActionTree tree, String actionMap, String actionKey, int index )
{
log.Debug( "FindActionInputObject - Entry" );
//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; } );
ActionMapCls ACM = tree.ActionMaps.Find( delegate( ActionMapCls _ACM ) { return _ACM.name == actionMap; } );
if ( ACM != null ) ac = ACM.Find( delegate ( ActionCls _AC ) { return _AC.key == actionKey; } );
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" );
@ -747,7 +739,7 @@ namespace SCJMapper_V2
/// <returns>An action or null if not found</returns>
private ActionCls FindActionObject( String actionMap, String action )
{
log.Debug( "FindActionObject - Entry" );
//log.Debug( "FindActionObject - Entry" );
// Apply the input to the ActionTree
ActionCls ac = null;
ActionMapCls ACM = ActionMaps.Find( delegate( ActionMapCls acm ) { return acm.name == actionMap; } );
@ -802,23 +794,20 @@ namespace SCJMapper_V2
matn.UpdateAction( acc ); UpdateMasterNode( matn );
matn.Nodes.Clear( ); // clear add childs - those don't persist from newly loaded actionmaps
first = false;
}
else {
} 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
matin.UpdateAction( acc ); UpdateMasterNode( matin );
}
}
catch {
} catch {
; // key not found
}
Dirty = true;
} // foreach
}
}
catch {
} catch {
; // map key not found ??
}
}
@ -828,6 +817,42 @@ namespace SCJMapper_V2
}
/// <summary>
/// Find a control that contains the string and mark it
/// this method is applied to the GUI TreeView only
/// </summary>
/// <param name="m_MasterTree">The string to find</param>
public void FindAndSelectActionKey( String actionmap, String actionKey, int nodeIndex )
{
log.Debug( "FindAndSelectActionKey - Entry" );
foreach ( ActionTreeNode tn in Ctrl.Nodes ) {
if ( String.IsNullOrEmpty( actionmap ) || ( tn.Text == actionmap ) ) {
// have to search nodes of nodes
foreach ( ActionTreeNode stn in tn.Nodes ) {
if ( stn.Name == actionKey ) {
if ( nodeIndex < 0 ) {
Ctrl.SelectedNode = stn;
Ctrl.SelectedNode.EnsureVisible( );
} else {
// have to search nodes of nodes
int ni = 0;
foreach ( ActionTreeInputNode sstn in stn.Nodes ) {
if ( ni++ == nodeIndex ) {
Ctrl.SelectedNode = sstn;
Ctrl.SelectedNode.EnsureVisible( );
return; // exit all loops
}
}
}
return; // exit all loops
}
}
}
}
}
/// <summary>
/// Find a control that contains the string and mark it
/// this method is applied to the GUI TreeView only
@ -888,6 +913,28 @@ namespace SCJMapper_V2
}
/// <summary>
/// Find a control that contains the Action (exact match)
/// </summary>
/// <param name="actionmap">The actionmap to find the string</param>
/// <param name="text">The string to find</param>
public String FindActionKey( String actionmap, String actionKey )
{
log.Debug( "FindActionKey - Entry" );
foreach ( ActionTreeNode tn in Ctrl.Nodes ) {
if ( String.IsNullOrEmpty( actionmap ) || ( tn.Text == actionmap ) ) {
// have to search nodes of nodes
foreach ( ActionTreeNode stn in tn.Nodes ) {
if ( stn.Name == actionKey ) {
return stn.Text;
}
}
}
}
return "";
}
/// <summary>
/// Find a control that contains the Action (exact match)
/// </summary>
@ -991,22 +1038,100 @@ namespace SCJMapper_V2
/// </summary>
public String SelectedAction
{
get
{
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 ) {
} else if ( Ctrl.SelectedNode.Level == 2 ) {
ActionTreeNode matn = FindMasterAction( ( ActionTreeNode )Ctrl.SelectedNode.Parent ); // the parent treenode
return ActionTreeNode.ActionFromNodeText( matn.Text );
} else return "";
}
}
/// <summary>
/// Returns the ActionID (DS_ActionMap) of the selected item
/// </summary>
public String SelectedActionID
{
get {
if ( Ctrl.SelectedNode == null ) return "";
if ( ( Ctrl.SelectedNode.Level == 0 ) || ( Ctrl.SelectedNode.Level > 2 ) ) return ""; // ERROR exit
if ( Ctrl.SelectedNode.Parent == null ) return ""; // ERROR exit
// has a parent - must be level 1 or 2
if ( Ctrl.SelectedNode.Level == 1 ) {
// this is the main node with Action Cmd
ActionTreeNode atn = ( Ctrl.SelectedNode as ActionTreeNode ); // the treenode from a level 1
ActionCls ac = FindActionObject( atn.Parent.Name, atn.Name ); // the related action in an actionmap
if ( ac == null ) return ""; // ERROR exit
ActionCommandCls acc = ac.FindActionInputObject( ActionTreeNode.CommandFromNodeText( atn.Text ) );
if ( acc == null ) return ""; // ERROR exit
// have it - continue
string actionID = DS_ActionMap.ActionID(atn.Parent.Name,ac.key, acc.NodeIndex );
return actionID;
} else if ( Ctrl.SelectedNode.Level == 2 ) {
// this is a child of an action with further commands
ActionTreeNode patn = ( Ctrl.SelectedNode.Parent as ActionTreeNode ); // the parent treenode from a level 2
ActionTreeNode atn = ( Ctrl.SelectedNode as ActionTreeNode ); // the treenode from a level 2
ActionCls ac = FindActionObject( patn.Parent.Name, patn.Name ); // the related action in an actionmap
if ( ac == null ) return ""; // ERROR exit
ActionCommandCls acc = ac.FindActionInputObject( atn.Index );
if ( acc == null ) return ""; // ERROR exit
// have it - continue
string actionID = DS_ActionMap.ActionID(atn.Parent.Name,ac.key, acc.NodeIndex );
return actionID;
} else return "";
}
}
/// <summary>
/// Update from all edits in the dataset DS_ActionMaps
/// </summary>/// <param name="dsa">The dataset to update from</param>
/// <returns>returns a null if no changes have been found</returns>
public ActionTree UpdateFromDataSet( DS_ActionMaps dsa )
{
ActionTree nTree = new ActionTree( this.m_jsList, this.m_gamepad ); // just a copy
// full copy from 'this'
nTree.m_MasterTree = this.m_MasterTree;
nTree.m_ctrl = this.m_ctrl;
nTree.IgnoreMaps = this.IgnoreMaps;
nTree.m_Filter = this.m_Filter;
nTree.ActionMaps = this.ActionMaps.ReassignJsN( new JsReassingList( ) ); // re-use this method with no reassign for full copy of the tree
int countChanges = 0;
foreach ( DS_ActionMaps.T_ActionRow ar in dsa.T_Action ) {
if ( ar.RowState== System.Data.DataRowState.Modified ) {
countChanges++;
ActionCommandCls acc = FindActionInputObject(nTree, DS_ActionMap.ActionMap(ar), DS_ActionMap.ActionKey(ar), DS_ActionMap.ActionCommandIndex(ar));
if ( acc != null ) {
acc.UpdateCommandFromInput( ActionCls.DevInput( DS_ActionMap.DevInput( ar ), ActionCls.ADevice( ar.Device ) ), ActionCls.ADevice( ar.Device ) );
ar.Usr_Binding = acc.DevInput; // feedback the right one
} else {
; // DEBUG should not happen...
}
}
else return "";
}
// finally if there were any changes
if ( countChanges > 0 ) {
dsa.AcceptChanges( );
nTree.Dirty = true;
return nTree;
}
else {
return null;
}
}
/// <summary>
/// Reports a summary list of the mapped items
/// </summary>
@ -1037,14 +1162,12 @@ namespace SCJMapper_V2
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.PadRight( padDevice ), acc.Input.PadRight( padInput ) );
}
else {
} else {
rep = String.Format( " {0} + {1} _ {2}", ac.name.PadRight( padAction ), acc.DevID.PadRight( padDevice ), acc.Input.PadRight( padInput ) ); // my binding
}
if ( acc.ActivationMode == ActivationMode.Default ) {
rep += String.Format( " . [{1}] {0}\n", ac.defActivationMode.Name, ac.defActivationMode.MultiTap );
}
else {
} else {
rep += String.Format( " # [{1}] {0}\n", acc.ActivationMode.Name, acc.ActivationMode.MultiTap );
}

@ -164,6 +164,7 @@ namespace SCJMapper_V2
if ( String.IsNullOrEmpty( actionCmd.Input ) ) {
// new unmapped
this.Command = ""; this.BackColor = MyColors.UnassignedColor;
if ( this.Level == 2 ) this.Action = "UNDEF"; // apply UNDEF - 20160525 fix addbind not showing UNDEF if assigned
}
// blended mapped ones - can only get a Blend Background
else if ( actionCmd.Input == DeviceCls.BlendedInput ) {
@ -172,6 +173,7 @@ namespace SCJMapper_V2
else {
// mapped ( regular ones )
this.Command = actionCmd.DevInput;
if ( this.Level == 2 ) this.Action = ""; // remove UNDEF - 20160525 fix addbind not showing UNDEF if assigned
// background is along the input
this.BackColor = ActionCls.DeviceColor( actionCmd.DevInput );
}

@ -1,27 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="AppConfiguration" type="SCJMapper_V2.AppConfiguration, SCJMapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" />
<section name="AppConfiguration" type="SCJMapper_V2.AppConfiguration, SCJMapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
<!-- This is the minimal change that detects a movement of an axis (Joystick, Gamepad, Mouse)
default are 150,500,150 - you may change it to get the detection less sensitive -->
<AppConfiguration jsSenseLimit="150" gpSenseLimit="500" msSenseLimit="150"
scActionmaps="default, multiplayer, singleplayer, invite, player, flycam,
<AppConfiguration jsSenseLimit="150" gpSenseLimit="500" msSenseLimit="150" scActionmaps="default, multiplayer, singleplayer, invite, player, flycam,
vehicle_general, vehicle_driver, vehicle_gunner,
spaceship_general, spaceship_view, spaceship_movement, spaceship_targeting, spaceship_turret, spaceship_weapons, spaceship_missiles,
spaceship_defensive, spaceship_auto_weapons, spaceship_power, spaceship_radar, spaceship_hud, zero_gravity_general, zero_gravity_eva, IFCS_controls" />
spaceship_defensive, spaceship_auto_weapons, spaceship_power, spaceship_radar, spaceship_hud, zero_gravity_general, zero_gravity_eva, IFCS_controls"/>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0" />
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>

@ -1,10 +1,10 @@
SC Joystick Mapper V 2.22 - Build 56 BETA
(c) Cassini, StandardToaster - 11-March-2016
SC Joystick Mapper V 2.23 - Build 57 BETA
(c) Cassini, StandardToaster - 27-May-2016
Contains 9 files:
SCJMapper.exe The program (V2.22)
SCJMapper.exe.config Program config (V2.22) - MUST be in the same folder as the Exe file
SCJMapper.exe The program (V2.23)
SCJMapper.exe.config Program config (V2.23) - 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.22beta.pdf Quick Guide
SCJMapper_QGuide V2.23beta.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.23 - BETA Build 57
- update - Using .Net 4.5.2 Now (seems to handle some scaling issues WinForm apps)
- update - Try to find the SC path also as StarCitizen\Live (instead of Public) was mentioned for SC2.2.2 onwards ???
- fix - addbind UNDEF removed when assigned
- improvement - Issue a infobox if the Client folder cannot be found
(please submit the complete folder structure of your installation as bug report ...)
- add - a table display for mappings
- some internal stuff (namespaces etc)
- update - doc SCJMapper_QGuide V2.23beta.pdf
V 2.22 - BETA Build 56
- fix - try again to fix Win10 scaling issues for some PCs (hidden assignment area)
- improvement - actions with a profile modifier attached will show underlined in the action tree

Binary file not shown.
Loading…
Cancel
Save