more analog controller config stuff, not done yet

This commit is contained in:
goyuken 2013-07-24 01:38:52 +00:00
parent 66f4e10e9e
commit 686960da75
9 changed files with 445 additions and 26 deletions

View File

@ -166,6 +166,15 @@
<Compile Include="config\AutofireConfig.Designer.cs">
<DependentUpon>AutofireConfig.cs</DependentUpon>
</Compile>
<Compile Include="config\ControllerConfig\AnalogBindControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="config\ControllerConfig\AnalogBindControl.Designer.cs">
<DependentUpon>AnalogBindControl.cs</DependentUpon>
</Compile>
<Compile Include="config\ControllerConfig\AnalogBindPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="config\ControllerConfig\ControllerConfigPanel.cs">
<SubType>UserControl</SubType>
</Compile>
@ -582,6 +591,9 @@
<EmbeddedResource Include="AVOut\VideoWriterChooserForm.resx">
<DependentUpon>VideoWriterChooserForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="config\ControllerConfig\AnalogBindControl.resx">
<DependentUpon>AnalogBindControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="config\ControllerConfig\ControllerConfigPanel.resx">
<DependentUpon>ControllerConfigPanel.cs</DependentUpon>
</EmbeddedResource>

View File

@ -692,7 +692,7 @@ namespace BizHawk.MultiClient
public const int NESNoiseMax = 247;
public const int NESDMCMax = 167;
public class AnalogBind
public struct AnalogBind
{
/// <summary>the physical stick that we're bound to</summary>
public string Value;

View File

@ -163,7 +163,8 @@ namespace BizHawk.MultiClient
private readonly WorkingDictionary<string, bool> LastState = new WorkingDictionary<string, bool>();
private readonly WorkingDictionary<string, bool> UnpressState = new WorkingDictionary<string, bool>();
private readonly HashSet<string> IgnoreKeys = new HashSet<string>(new[] { "LeftShift", "RightShift", "LeftControl", "RightControl", "LeftAlt", "RightAlt" });
private readonly List<Tuple<string, float>> FloatValues = new List<Tuple<string, float>>();
private readonly WorkingDictionary<string, float> FloatValues = new WorkingDictionary<string, float>();
private readonly WorkingDictionary<string, float> FloatDeltas = new WorkingDictionary<string, float>();
void HandleButton(string button, bool newState)
{
@ -257,10 +258,11 @@ namespace BizHawk.MultiClient
public List<Tuple<string, float>> GetFloats()
{
List<Tuple<string, float>> FloatValuesCopy;
List<Tuple<string, float>> FloatValuesCopy = new List<Tuple<string,float>>();
lock (FloatValues)
{
FloatValuesCopy = new List<Tuple<string, float>>(FloatValues);
foreach (var kvp in FloatValues)
FloatValuesCopy.Add(new Tuple<string, float>(kvp.Key, kvp.Value));
}
return FloatValuesCopy;
}
@ -289,7 +291,7 @@ namespace BizHawk.MultiClient
lock (FloatValues)
{
FloatValues.Clear();
//FloatValues.Clear();
//analyze xinput
for (int i = 0; i < GamePad360.Devices.Count; i++)
@ -299,7 +301,12 @@ namespace BizHawk.MultiClient
for (int b = 0; b < pad.NumButtons; b++)
HandleButton(xname + pad.ButtonName(b), pad.Pressed(b));
foreach (var sv in pad.GetFloats())
FloatValues.Add(new Tuple<string,float>(xname + sv.Item1, sv.Item2));
{
string n = xname = sv.Item1;
float f = sv.Item2;
FloatDeltas[n] += Math.Abs(f - FloatValues[n]);
FloatValues[n] = f;
}
}
//analyze joysticks
@ -311,7 +318,15 @@ namespace BizHawk.MultiClient
for (int b = 0; b < pad.NumButtons; b++)
HandleButton(jname + pad.ButtonName(b), pad.Pressed(b));
foreach (var sv in pad.GetFloats())
FloatValues.Add(new Tuple<string, float>(jname + sv.Item1, sv.Item2));
{
string n = jname + sv.Item1;
float f = sv.Item2;
//if (n == "J5 RotationZ")
// System.Diagnostics.Debugger.Break();
FloatDeltas[n] += Math.Abs(f - FloatValues[n]);
FloatValues[n] = f;
}
}
}
@ -333,6 +348,28 @@ namespace BizHawk.MultiClient
}
#endif
public void StartListeningForFloatEvents()
{
lock (this)
{
FloatDeltas.Clear();
}
}
public string GetNextFloatEvent()
{
lock (this)
{
foreach (var kvp in FloatDeltas)
{
// need to wiggle the stick a bit
if (kvp.Value >= 20000.0f)
return kvp.Key;
}
}
return null;
}
public void Update()
{
//TODO - for some reason, we may want to control when the next event processing step happens

View File

@ -0,0 +1,120 @@
namespace BizHawk.MultiClient.config.ControllerConfig
{
partial class AnalogBindControl
{
/// <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 Component 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();
this.textBox1 = new System.Windows.Forms.TextBox();
this.labelButtonName = new System.Windows.Forms.Label();
this.trackBarSensitivity = new System.Windows.Forms.TrackBar();
this.labelSensitivity = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.buttonBind = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.trackBarSensitivity)).BeginInit();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(3, 3);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
//
// labelButtonName
//
this.labelButtonName.AutoSize = true;
this.labelButtonName.Location = new System.Drawing.Point(109, 6);
this.labelButtonName.Name = "labelButtonName";
this.labelButtonName.Size = new System.Drawing.Size(54, 13);
this.labelButtonName.TabIndex = 1;
this.labelButtonName.Text = "Bindname";
//
// trackBarSensitivity
//
this.trackBarSensitivity.LargeChange = 2000;
this.trackBarSensitivity.Location = new System.Drawing.Point(169, 3);
this.trackBarSensitivity.Maximum = 2000;
this.trackBarSensitivity.Minimum = -2000;
this.trackBarSensitivity.Name = "trackBarSensitivity";
this.trackBarSensitivity.Size = new System.Drawing.Size(104, 42);
this.trackBarSensitivity.SmallChange = 1000;
this.trackBarSensitivity.TabIndex = 2;
this.trackBarSensitivity.TickFrequency = 1000;
this.trackBarSensitivity.ValueChanged += new System.EventHandler(this.trackBarSensitivity_ValueChanged);
//
// labelSensitivity
//
this.labelSensitivity.AutoSize = true;
this.labelSensitivity.Location = new System.Drawing.Point(3, 26);
this.labelSensitivity.Name = "labelSensitivity";
this.labelSensitivity.Size = new System.Drawing.Size(95, 13);
this.labelSensitivity.TabIndex = 3;
this.labelSensitivity.Text = "Sensitivity: 5 billion";
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// buttonBind
//
this.buttonBind.Location = new System.Drawing.Point(279, 1);
this.buttonBind.Name = "buttonBind";
this.buttonBind.Size = new System.Drawing.Size(75, 23);
this.buttonBind.TabIndex = 4;
this.buttonBind.Text = "Bind!";
this.buttonBind.UseVisualStyleBackColor = true;
this.buttonBind.Click += new System.EventHandler(this.buttonBind_Click);
//
// AnalogBindControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.buttonBind);
this.Controls.Add(this.labelSensitivity);
this.Controls.Add(this.trackBarSensitivity);
this.Controls.Add(this.labelButtonName);
this.Controls.Add(this.textBox1);
this.Name = "AnalogBindControl";
this.Size = new System.Drawing.Size(387, 43);
((System.ComponentModel.ISupportInitialize)(this.trackBarSensitivity)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label labelButtonName;
private System.Windows.Forms.TrackBar trackBarSensitivity;
private System.Windows.Forms.Label labelSensitivity;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button buttonBind;
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BizHawk.MultiClient.config.ControllerConfig
{
public partial class AnalogBindControl : UserControl
{
private AnalogBindControl()
{
InitializeComponent();
}
public Config.AnalogBind Bind;
bool listening = false;
public AnalogBindControl(string ButtonName, Config.AnalogBind Bind)
: this()
{
this.Bind = Bind;
labelButtonName.Text = ButtonName;
trackBarSensitivity.Value = (int)(Bind.Mult * 1000.0f);
textBox1.Text = Bind.Value;
}
private void timer1_Tick(object sender, EventArgs e)
{
string bindval = Input.Instance.GetNextFloatEvent();
if (bindval != null)
{
timer1.Stop();
listening = false;
Bind.Value = bindval;
textBox1.Text = Bind.Value;
buttonBind.Text = "Bind!";
}
}
private void buttonBind_Click(object sender, EventArgs e)
{
if (listening)
{
timer1.Stop();
listening = false;
buttonBind.Text = "Bind!";
}
else
{
Input.Instance.StartListeningForFloatEvents();
listening = true;
buttonBind.Text = "Cancel!";
timer1.Start();
}
}
private void trackBarSensitivity_ValueChanged(object sender, EventArgs e)
{
Bind.Mult = trackBarSensitivity.Value / 1000.0f;
labelSensitivity.Text = string.Format("Sensitivity: {0}", Bind.Mult);
}
}
}

View File

@ -0,0 +1,123 @@
<?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="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace BizHawk.MultiClient.config.ControllerConfig
{
class AnalogBindPanel : UserControl
{
Dictionary<string, Config.AnalogBind> RealConfigObject;
public AnalogBindPanel(Dictionary<string, Config.AnalogBind> RealConfigObject, List<string> RealConfigButtons = null)
:base()
{
this.RealConfigObject = RealConfigObject;
LoadSettings(RealConfigButtons ?? (IEnumerable<string>)RealConfigObject.Keys);
}
void LoadSettings(IEnumerable<string> ButtonList)
{
SuspendLayout();
int x = 4;
int y = 4;
foreach (string ButtonName in ButtonList)
{
var ctrl = new AnalogBindControl(ButtonName, RealConfigObject[ButtonName]);
ctrl.Location = new Point(x, y);
y += ctrl.Height + 4;
if (Width < ctrl.Width + 8)
Width = ctrl.Width + 8;
Controls.Add(ctrl);
}
ResumeLayout();
}
}
}

View File

@ -41,6 +41,7 @@
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.buttonLoadDefaults = new System.Windows.Forms.Button();
this.buttonSaveAllDefaults = new System.Windows.Forms.Button();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.tabControl1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
@ -50,6 +51,7 @@
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(3, 3);
this.tabControl1.Name = "tabControl1";
@ -184,6 +186,15 @@
this.buttonSaveAllDefaults.UseVisualStyleBackColor = true;
this.buttonSaveAllDefaults.Click += new System.EventHandler(this.buttonSaveAllDefaults_Click);
//
// tabPage3
//
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(486, 438);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Analog Controls";
this.tabPage3.UseVisualStyleBackColor = true;
//
// NewControllerConfig
//
this.AcceptButton = this.buttonOK;
@ -225,5 +236,6 @@
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button buttonLoadDefaults;
private System.Windows.Forms.Button buttonSaveAllDefaults;
private System.Windows.Forms.TabPage tabPage3;
}
}

View File

@ -39,19 +39,34 @@ namespace BizHawk.MultiClient.config
buttonSaveAllDefaults.Hide();
}
static void LoadToPanel(Control dest, ControllerDefinition def, Dictionary<string, Dictionary<string, string>> settingsblock)
delegate Control PanelCreator<T>(Dictionary<string, T> settings, List<string> buttons, Size size);
Control CreateNormalPanel(Dictionary<string, string> settings, List<string> buttons, Size size)
{
Dictionary<string, string> settings;
if (!settingsblock.TryGetValue(def.Name, out settings))
var cp = new ControllerConfigPanel {Dock = DockStyle.Fill};
cp.LoadSettings(settings, buttons, size.Width, size.Height);
return cp;
}
Control CreateAnalogPanel(Dictionary<string, Config.AnalogBind> settings, List<string> buttons, Size size)
{
var acp = new config.ControllerConfig.AnalogBindPanel(settings, buttons);
return acp;
}
static void LoadToPanel<T>(Control dest, string ControllerName, IEnumerable<string> ControllerButtons, Dictionary<string, Dictionary<string, T>> settingsblock, T defaultvalue, PanelCreator<T> createpanel)
{
Dictionary<string, T> settings;
if (!settingsblock.TryGetValue(ControllerName, out settings))
{
settings = new Dictionary<string, string>();
settingsblock[def.Name] = settings;
settings = new Dictionary<string, T>();
settingsblock[ControllerName] = settings;
}
// check to make sure that the settings object has all of the appropriate boolbuttons
foreach (string button in def.BoolButtons)
foreach (string button in ControllerButtons)
{
if (!settings.Keys.Contains(button))
settings[button] = "";
settings[button] = defaultvalue;
}
if (settings.Keys.Count == 0)
@ -78,9 +93,7 @@ namespace BizHawk.MultiClient.config
if (buckets[0].Count == settings.Keys.Count)
{
// everything went into bucket 0, so make no tabs at all
var cp = new ControllerConfigPanel {Dock = DockStyle.Fill};
dest.Controls.Add(cp);
cp.LoadSettings(settings, null, dest.Width, dest.Height);
dest.Controls.Add(createpanel(settings, null, dest.Size));
}
else
{
@ -93,19 +106,14 @@ namespace BizHawk.MultiClient.config
if (buckets[i].Count > 0)
{
tt.TabPages.Add("Player " + i);
var cp = new ControllerConfigPanel {Dock = DockStyle.Fill};
tt.TabPages[pageidx].Controls.Add(cp);
cp.LoadSettings(settings, buckets[i], tt.Width, tt.Height);
tt.TabPages[pageidx].Controls.Add(createpanel(settings, buckets[i], tt.Size));
pageidx++;
}
}
if (buckets[0].Count > 0)
{
tt.TabPages.Add("Console");
var cp = new ControllerConfigPanel {Dock = DockStyle.Fill};
tt.TabPages[pageidx].Controls.Add(cp);
cp.LoadSettings(settings, buckets[0], tt.Width, tt.Height);
tt.TabPages[pageidx].Controls.Add(createpanel(settings, buckets[0], tt.Size));
pageidx++;
}
}
@ -116,8 +124,9 @@ namespace BizHawk.MultiClient.config
{
ControllerType = def.Name;
SuspendLayout();
LoadToPanel(tabPage1, def, Global.Config.AllTrollers);
LoadToPanel(tabPage2, def, Global.Config.AllTrollersAutoFire);
LoadToPanel(tabPage1, def.Name, def.BoolButtons, Global.Config.AllTrollers, "", CreateNormalPanel);
LoadToPanel(tabPage2, def.Name, def.BoolButtons, Global.Config.AllTrollersAutoFire, "", CreateNormalPanel);
LoadToPanel(tabPage3, def.Name, def.FloatControls, Global.Config.AllTrollersAnalog, new Config.AnalogBind("", 1.0f), CreateAnalogPanel);
Text = def.Name + " Configuration";
checkBoxUDLR.Checked = Global.Config.AllowUD_LR;