From a248e2d99b4066d89ff90e08e30668645cae9e3e Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 22 Jun 2014 17:41:13 +0000 Subject: [PATCH] Virtual Pads - analog stick should be done now (including max X,Y constraints) --- .../BizHawk.Client.EmuHawk.csproj | 9 + .../tools/VirtualPads/VirtualPad.cs | 2 +- .../VirtualPads/controls/AnalogSticklPanel.cs | 134 ++++++++---- .../VirtualPadAnalogStick.Designer.cs | 196 ++++++++++++++++++ .../controls/VirtualPadAnalogStick.cs | 120 +++++++++++ .../controls/VirtualPadAnalogStick.resx | 120 +++++++++++ .../tools/VirtualPads/schema/N64Schema.cs | 2 +- 7 files changed, 540 insertions(+), 43 deletions(-) create mode 100644 BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.Designer.cs create mode 100644 BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs create mode 100644 BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.resx diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index bf384a4f7c..ef38e2dda1 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -883,6 +883,12 @@ Component + + UserControl + + + VirtualPadAnalogStick.cs + Component @@ -1222,6 +1228,9 @@ TI83KeyPad.cs + + VirtualPadAnalogStick.cs + VirtualPad.cs diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs index f0ee21f6ae..e3e6351e7e 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs @@ -45,7 +45,7 @@ namespace BizHawk.Client.EmuHawk }); break; case PadSchema.PadInputType.AnalogStick: - Controls.Add(new AnalogStickPanel + Controls.Add(new VirtualPadAnalogStick { Name = button.Name, Location = button.Location diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/AnalogSticklPanel.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/AnalogSticklPanel.cs index 6c79554214..e4af7dccf4 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/AnalogSticklPanel.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/AnalogSticklPanel.cs @@ -5,19 +5,48 @@ using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - public sealed class AnalogStickPanel : Panel, IVirtualPadControl + public sealed class AnalogStickPanel : Panel { public int X = 0; public int Y = 0; public bool HasValue = false; - private readonly Brush _white_brush = Brushes.White; - private readonly Brush _black_brush = Brushes.Black; - private readonly Brush _gray_brush = Brushes.LightGray; - private readonly Brush _red_brush = Brushes.Red; - private readonly Brush _blue_brush = Brushes.DarkBlue; - private readonly Pen _black_pen; - private readonly Pen _blue_pen; + public string XName = string.Empty; + public string YName = string.Empty; + + public int MaxX + { + get { return _maxX; } + set + { + _maxX = value; + CheckMax(); + } + } + + public int MaxY + { + get { return _maxY; } + set + { + _maxY = value; + CheckMax(); + } + } + + private int _maxX = 127; + private int _maxY = 127; + + private int MinX { get { return 0 - MaxX; } } + private int MinY { get { return 0 - MaxY; } } + + private readonly Brush _whiteBrush = Brushes.White; + private readonly Brush _blackBrush = Brushes.Black; + private readonly Brush _grayBrush = Brushes.LightGray; + private readonly Brush _redBrush = Brushes.Red; + private readonly Brush _blueBrush = Brushes.DarkBlue; + private readonly Pen _blackPen; + private readonly Pen _bluePen; private readonly Bitmap dot = new Bitmap(7, 7); private readonly Bitmap graydot = new Bitmap(7, 7); @@ -32,19 +61,19 @@ namespace BizHawk.Client.EmuHawk SetStyle(ControlStyles.Opaque, true); BackColor = Color.Gray; Paint += AnalogControlPanel_Paint; - new Pen(_white_brush); - _black_pen = new Pen(_black_brush); - new Pen(_gray_brush); - new Pen(_red_brush); - _blue_pen = new Pen(_blue_brush); + new Pen(_whiteBrush); + _blackPen = new Pen(_blackBrush); + new Pen(_grayBrush); + new Pen(_redBrush); + _bluePen = new Pen(_blueBrush); BorderStyle = BorderStyle.Fixed3D; // Draw the dot into a bitmap Graphics g = Graphics.FromImage(dot); g.Clear(Color.Transparent); - g.FillRectangle(_red_brush, 2, 0, 3, 7); - g.FillRectangle(_red_brush, 1, 1, 5, 5); - g.FillRectangle(_red_brush, 0, 2, 7, 3); + g.FillRectangle(_redBrush, 2, 0, 3, 7); + g.FillRectangle(_redBrush, 1, 1, 5, 5); + g.FillRectangle(_redBrush, 0, 2, 7, 3); Graphics gg = Graphics.FromImage(graydot); gg.Clear(Color.Transparent); @@ -55,20 +84,23 @@ namespace BizHawk.Client.EmuHawk private int RealToGFX(int val) { - return (val + 128)/2; + return (val + 128) / 2; } - private int GFXToReal(int val) + private int GFXToReal(int val, bool isX) // isX is a hack { + var max = isX ? MaxX : MaxY; + var min = isX ? MinX : MinY; + int ret = (val * 2); - if (ret > Max) + if (ret > max) { - ret = Max; + ret = max; } - if (ret < Min) + if (ret < min) { - ret = Min; + ret = min; } return ret; @@ -83,8 +115,8 @@ namespace BizHawk.Client.EmuHawk { int? xn = HasValue ? X : (int?)null; int? yn = HasValue ? Y : (int?)null; - Global.StickyXORAdapter.SetFloat(Name, xn); - Global.StickyXORAdapter.SetFloat(Name.Replace("X", "Y"), yn); // Hack! + Global.StickyXORAdapter.SetFloat(XName, xn); + Global.StickyXORAdapter.SetFloat(YName, yn); Refresh(); } @@ -94,18 +126,19 @@ namespace BizHawk.Client.EmuHawk unchecked { //Background - e.Graphics.FillRectangle(_gray_brush, 0, 0, 128, 128); - e.Graphics.FillEllipse(_white_brush, 0, 0, 127, 127); - e.Graphics.DrawEllipse(_black_pen, 0, 0, 127, 127); - e.Graphics.DrawLine(_black_pen, 64, 0, 64, 127); - e.Graphics.DrawLine(_black_pen, 0, 63, 127, 63); + e.Graphics.FillRectangle(_grayBrush, 0, 0, 128, 128); + e.Graphics.FillEllipse(_whiteBrush, 0, 0, 127, 127); + e.Graphics.DrawEllipse(_blackPen, 0, 0, 127, 127); + e.Graphics.DrawLine(_blackPen, 64, 0, 64, 127); + e.Graphics.DrawLine(_blackPen, 0, 63, 127, 63); - if (Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsFinished) + if (Global.MovieSession != null && Global.MovieSession.Movie != null && // For the desinger + Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsFinished) { var input = Global.MovieSession.Movie.GetInputState(Global.Emulator.Frame - 1); - var x = input.GetFloat(Name); - var y = input.GetFloat(Name.Replace("X", "Y")); // Hack! + var x = input.GetFloat(XName); + var y = input.GetFloat(YName); var xx = RealToGFX((int)x); var yy = RealToGFX((int)y); @@ -117,7 +150,7 @@ namespace BizHawk.Client.EmuHawk //Line if (HasValue) { - e.Graphics.DrawLine(_blue_pen, 64, 63, RealToGFX(X), 127 - RealToGFX(Y)); + e.Graphics.DrawLine(_bluePen, 64, 63, RealToGFX(X), 127 - RealToGFX(Y)); e.Graphics.DrawImage(dot, RealToGFX(X) - 3, 127 - RealToGFX(Y) - 3); } } @@ -127,8 +160,8 @@ namespace BizHawk.Client.EmuHawk { if (e.Button == MouseButtons.Left) { - X = GFXToReal(e.X - 64); - Y = GFXToReal(-(e.Y - 63)); + X = GFXToReal(e.X - 64, true); + Y = GFXToReal(-(e.Y - 63), false); HasValue = true; SetAnalog(); } @@ -144,8 +177,7 @@ namespace BizHawk.Client.EmuHawk protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); - if (Capture) - Capture = false; + Capture = false; } @@ -164,8 +196,8 @@ namespace BizHawk.Client.EmuHawk { if (e.Button == MouseButtons.Left) { - X = GFXToReal(e.X - 64); - Y = GFXToReal(-(e.Y - 63)); + X = GFXToReal(e.X - 64, true); + Y = GFXToReal(-(e.Y - 63), false); HasValue = true; } if (e.Button == MouseButtons.Right) @@ -193,7 +225,27 @@ namespace BizHawk.Client.EmuHawk Refresh(); } - public static int Max = 127; - public static int Min = -127; + private void CheckMax() + { + if (X > MaxX) + { + X = MaxX; + } + else if (X < MinX) + { + X = MinX; + } + + if (Y > MaxY) + { + Y = MaxY; + } + else if (Y < MinY) + { + Y = MinY; + } + + Refresh(); + } } } diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.Designer.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.Designer.cs new file mode 100644 index 0000000000..c6a3467f80 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.Designer.cs @@ -0,0 +1,196 @@ +namespace BizHawk.Client.EmuHawk +{ + partial class VirtualPadAnalogStick + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.ManualX = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.ManualY = new System.Windows.Forms.NumericUpDown(); + this.MaxLabel = new System.Windows.Forms.Label(); + this.MaxXNumeric = new System.Windows.Forms.NumericUpDown(); + this.MaxYNumeric = new System.Windows.Forms.NumericUpDown(); + this.AnalogStick = new BizHawk.Client.EmuHawk.AnalogStickPanel(); + ((System.ComponentModel.ISupportInitialize)(this.ManualX)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ManualY)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaxXNumeric)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaxYNumeric)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(138, 7); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(14, 13); + this.label1.TabIndex = 23; + this.label1.Text = "X"; + // + // ManualX + // + this.ManualX.Location = new System.Drawing.Point(156, 3); + this.ManualX.Maximum = new decimal(new int[] { + 127, + 0, + 0, + 0}); + this.ManualX.Minimum = new decimal(new int[] { + 127, + 0, + 0, + -2147483648}); + this.ManualX.Name = "ManualX"; + this.ManualX.Size = new System.Drawing.Size(44, 20); + this.ManualX.TabIndex = 24; + this.ManualX.ValueChanged += new System.EventHandler(this.ManualX_ValueChanged); + this.ManualX.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ManualX_KeyUp); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(138, 33); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(14, 13); + this.label2.TabIndex = 26; + this.label2.Text = "Y"; + // + // ManualY + // + this.ManualY.Location = new System.Drawing.Point(156, 29); + this.ManualY.Maximum = new decimal(new int[] { + 127, + 0, + 0, + 0}); + this.ManualY.Minimum = new decimal(new int[] { + 127, + 0, + 0, + -2147483648}); + this.ManualY.Name = "ManualY"; + this.ManualY.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.ManualY.Size = new System.Drawing.Size(44, 20); + this.ManualY.TabIndex = 25; + this.ManualY.ValueChanged += new System.EventHandler(this.ManualY_ValueChanged); + this.ManualY.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ManualY_KeyUp); + // + // MaxLabel + // + this.MaxLabel.AutoSize = true; + this.MaxLabel.Location = new System.Drawing.Point(138, 72); + this.MaxLabel.Name = "MaxLabel"; + this.MaxLabel.Size = new System.Drawing.Size(27, 13); + this.MaxLabel.TabIndex = 27; + this.MaxLabel.Text = "Max"; + // + // MaxXNumeric + // + this.MaxXNumeric.Location = new System.Drawing.Point(138, 89); + this.MaxXNumeric.Maximum = new decimal(new int[] { + 127, + 0, + 0, + 0}); + this.MaxXNumeric.Minimum = new decimal(new int[] { + 127, + 0, + 0, + -2147483648}); + this.MaxXNumeric.Name = "MaxXNumeric"; + this.MaxXNumeric.Size = new System.Drawing.Size(44, 20); + this.MaxXNumeric.TabIndex = 28; + this.MaxXNumeric.ValueChanged += new System.EventHandler(this.MaxXNumeric_ValueChanged); + this.MaxXNumeric.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MaxXNumeric_KeyUp); + // + // MaxYNumeric + // + this.MaxYNumeric.Location = new System.Drawing.Point(138, 112); + this.MaxYNumeric.Maximum = new decimal(new int[] { + 127, + 0, + 0, + 0}); + this.MaxYNumeric.Minimum = new decimal(new int[] { + 127, + 0, + 0, + -2147483648}); + this.MaxYNumeric.Name = "MaxYNumeric"; + this.MaxYNumeric.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.MaxYNumeric.Size = new System.Drawing.Size(44, 20); + this.MaxYNumeric.TabIndex = 29; + this.MaxYNumeric.ValueChanged += new System.EventHandler(this.MaxYNumeric_ValueChanged); + this.MaxYNumeric.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MaxYNumeric_KeyUp); + // + // AnalogStick + // + this.AnalogStick.BackColor = System.Drawing.Color.Gray; + this.AnalogStick.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.AnalogStick.Location = new System.Drawing.Point(3, 3); + this.AnalogStick.Name = "AnalogStick"; + this.AnalogStick.Size = new System.Drawing.Size(129, 129); + this.AnalogStick.TabIndex = 0; + this.AnalogStick.MouseDown += new System.Windows.Forms.MouseEventHandler(this.AnalogStick_MouseDown); + this.AnalogStick.MouseMove += new System.Windows.Forms.MouseEventHandler(this.AnalogStick_MouseMove); + // + // VirtualPadAnalogStick + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.MaxYNumeric); + this.Controls.Add(this.MaxXNumeric); + this.Controls.Add(this.MaxLabel); + this.Controls.Add(this.label2); + this.Controls.Add(this.ManualY); + this.Controls.Add(this.ManualX); + this.Controls.Add(this.label1); + this.Controls.Add(this.AnalogStick); + this.Name = "VirtualPadAnalogStick"; + this.Size = new System.Drawing.Size(204, 136); + this.Load += new System.EventHandler(this.VirtualPadAnalogStick_Load); + ((System.ComponentModel.ISupportInitialize)(this.ManualX)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ManualY)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaxXNumeric)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaxYNumeric)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private AnalogStickPanel AnalogStick; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown ManualX; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.NumericUpDown ManualY; + private System.Windows.Forms.Label MaxLabel; + private System.Windows.Forms.NumericUpDown MaxXNumeric; + private System.Windows.Forms.NumericUpDown MaxYNumeric; + } +} diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs new file mode 100644 index 0000000000..b46049383f --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs @@ -0,0 +1,120 @@ +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.Client.EmuHawk +{ + public partial class VirtualPadAnalogStick : UserControl, IVirtualPadControl + { + public VirtualPadAnalogStick() + { + InitializeComponent(); + } + + private void VirtualPadAnalogStick_Load(object sender, EventArgs e) + { + AnalogStick.Name = Name; + AnalogStick.Name = Name.Replace("X", "Y"); // TODO: allow schema to dictate this but this is a convenient default + MaxXNumeric.Value = 127; + MaxYNumeric.Value = 127; // Note: these trigger change events that change the analog stick too + } + + public void Clear() + { + AnalogStick.Clear(); + ManualX.Value = 0; + ManualY.Value = 0; + } + + private void ManualX_ValueChanged(object sender, EventArgs e) + { + SetAnalogControlFromNumerics(); + } + + private void ManualX_KeyUp(object sender, KeyEventArgs e) + { + SetAnalogControlFromNumerics(); + } + + private void ManualY_KeyUp(object sender, KeyEventArgs e) + { + SetAnalogControlFromNumerics(); + } + + private void ManualY_ValueChanged(object sender, EventArgs e) + { + SetAnalogControlFromNumerics(); + } + + + private bool _programmaticallyUpdatingNumerics = false; + + private void SetAnalogControlFromNumerics() + { + if (!_programmaticallyUpdatingNumerics) + { + AnalogStick.X = (int)ManualX.Value; + AnalogStick.Y = (int)ManualY.Value; + AnalogStick.HasValue = true; + AnalogStick.Refresh(); + } + } + + private void SetNumericsFromAnalog() + { + if (AnalogStick.HasValue) + { + ManualX.Value = AnalogStick.X; + ManualY.Value = AnalogStick.Y; + } + } + + private void AnalogStick_MouseDown(object sender, MouseEventArgs e) + { + _programmaticallyUpdatingNumerics = true; + SetNumericsFromAnalog(); + _programmaticallyUpdatingNumerics = false; + } + + private void AnalogStick_MouseMove(object sender, MouseEventArgs e) + { + _programmaticallyUpdatingNumerics = true; + SetNumericsFromAnalog(); + _programmaticallyUpdatingNumerics = false; + } + + private void MaxXNumeric_ValueChanged(object sender, EventArgs e) + { + SetAnalogMaxFromNumerics(); + } + + private void MaxXNumeric_KeyUp(object sender, KeyEventArgs e) + { + SetAnalogMaxFromNumerics(); + } + + private void MaxYNumeric_ValueChanged(object sender, EventArgs e) + { + SetAnalogMaxFromNumerics(); + } + + private void MaxYNumeric_KeyUp(object sender, KeyEventArgs e) + { + SetAnalogMaxFromNumerics(); + } + + private void SetAnalogMaxFromNumerics() + { + if (!_programmaticallyUpdatingNumerics) + { + AnalogStick.MaxX = (int)MaxXNumeric.Value; + AnalogStick.MaxY = (int)MaxYNumeric.Value; + } + } + } +} diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.resx b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.resx new file mode 100644 index 0000000000..29dcb1b3a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/N64Schema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/N64Schema.cs index 8acac693ca..0c5d75f33f 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/N64Schema.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/N64Schema.cs @@ -9,7 +9,7 @@ namespace BizHawk.Client.EmuHawk return new PadSchema { IsConsole = false, - DefaultSize = new Size(200, 316), + DefaultSize = new Size(220, 316), Buttons = new[] { new PadSchema.ButtonScema