rework virtual pad analog widget to support n64 and psx simultaneously
This commit is contained in:
parent
125a16ec67
commit
0787a3be47
|
@ -85,9 +85,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
Name = button.Name,
|
||||
Location = UIHelper.Scale(button.Location),
|
||||
Size = UIHelper.Scale(new Size(button.MaxValue + 79, button.MaxValue + 9)), // TODO: don't use hardcoded values here, at least make them defaults in the AnalogStick object itself
|
||||
RangeX = button.MaxValue,
|
||||
RangeY = button.MaxValue // TODO ability to pass in a different Y max
|
||||
Size = UIHelper.Scale(new Size(127 + 79, 127 + 9)),
|
||||
RangeX = new float[] { button.MinValue, button.MidValue, button.MaxValue },
|
||||
RangeY = new float[] { button.MinValueSec, button.MidValueSec, button.MaxValueSec },
|
||||
});
|
||||
break;
|
||||
case PadSchema.PadInputType.TargetedPair:
|
||||
|
|
|
@ -109,9 +109,9 @@
|
|||
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.Size = new System.Drawing.Size(47, 13);
|
||||
this.MaxLabel.TabIndex = 27;
|
||||
this.MaxLabel.Text = "Max";
|
||||
this.MaxLabel.Text = "Range%";
|
||||
//
|
||||
// MaxXNumeric
|
||||
//
|
||||
|
@ -161,9 +161,8 @@
|
|||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.AnalogStick.BackColor = System.Drawing.Color.Gray;
|
||||
this.AnalogStick.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
|
||||
this.AnalogStick.ClearCallback = null;
|
||||
this.AnalogStick.Location = new System.Drawing.Point(3, 3);
|
||||
this.AnalogStick.MaxX = 127;
|
||||
this.AnalogStick.MaxY = 127;
|
||||
this.AnalogStick.Name = "AnalogStick";
|
||||
this.AnalogStick.ReadOnly = false;
|
||||
this.AnalogStick.Size = new System.Drawing.Size(129, 129);
|
||||
|
|
|
@ -17,32 +17,33 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
InitializeComponent();
|
||||
AnalogStick.ClearCallback = ClearCallback;
|
||||
RangeX = 127;
|
||||
RangeY = 127;
|
||||
}
|
||||
|
||||
public int RangeX { get; set; }
|
||||
public int RangeY { get; set; }
|
||||
public float[] RangeX = new float[] { -128f, 0.0f, 127f };
|
||||
public float[] RangeY = new float[] { -128f, 0.0f, 127f };
|
||||
|
||||
|
||||
private void VirtualPadAnalogStick_Load(object sender, EventArgs e)
|
||||
{
|
||||
AnalogStick.Name = Name;
|
||||
AnalogStick.XName = Name;
|
||||
AnalogStick.YName = Name.Replace("X", "Y"); // TODO: allow schema to dictate this but this is a convenient default
|
||||
AnalogStick.MaxX = RangeX;
|
||||
AnalogStick.MaxY = RangeY;
|
||||
AnalogStick.SetRangeX(RangeX);
|
||||
AnalogStick.SetRangeY(RangeY);
|
||||
|
||||
ManualX.Minimum = AnalogStick.MinX;
|
||||
ManualX.Maximum = AnalogStick.MaxX;
|
||||
ManualX.Minimum = (decimal)RangeX[0];
|
||||
ManualX.Maximum = (decimal)RangeX[2];
|
||||
|
||||
ManualY.Minimum = AnalogStick.MinY;
|
||||
ManualY.Maximum = AnalogStick.MaxY;
|
||||
ManualY.Minimum = (decimal)RangeX[0];
|
||||
ManualY.Maximum = (decimal)RangeX[2];
|
||||
|
||||
MaxXNumeric.Maximum = RangeX;
|
||||
MaxXNumeric.Value = RangeX;
|
||||
MaxXNumeric.Minimum = 1;
|
||||
MaxXNumeric.Maximum = 100;
|
||||
MaxXNumeric.Value = 100;
|
||||
|
||||
MaxYNumeric.Maximum = RangeY;
|
||||
MaxYNumeric.Value = RangeY; // Note: these trigger change events that change the analog stick too
|
||||
MaxYNumeric.Minimum = 1;
|
||||
MaxYNumeric.Maximum = 100;
|
||||
MaxYNumeric.Value = 100; // Note: these trigger change events that change the analog stick too
|
||||
}
|
||||
|
||||
#region IVirtualPadControl Implementation
|
||||
|
@ -233,8 +234,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (!_programmaticallyUpdatingNumerics)
|
||||
{
|
||||
AnalogStick.MaxX = (int)MaxXNumeric.Value;
|
||||
AnalogStick.MaxY = (int)MaxYNumeric.Value;
|
||||
//blehh,... this damn feature
|
||||
AnalogStick.SetUserRange((float)MaxXNumeric.Value, (float)MaxYNumeric.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System.Drawing;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
|
||||
//Just because this code was mostly rewritten, dont think it isnt still awful
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -48,31 +50,140 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private IController _previous = null;
|
||||
|
||||
public int MaxX
|
||||
float UserRangePercentageX = 100, UserRangePercentageY = 100;
|
||||
|
||||
public void SetUserRange(float rx, float ry)
|
||||
{
|
||||
get { return _maxX; }
|
||||
set
|
||||
{
|
||||
_maxX = value;
|
||||
CheckMax();
|
||||
}
|
||||
UserRangePercentageX = rx;
|
||||
UserRangePercentageY = ry;
|
||||
Rerange();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public int MaxY
|
||||
public void SetRangeX(float[] range)
|
||||
{
|
||||
get { return _maxY; }
|
||||
set
|
||||
{
|
||||
_maxY = value;
|
||||
CheckMax();
|
||||
}
|
||||
for (int i = 0; i < 3; i++) ActualRangeX[i] = range[i];
|
||||
Rerange();
|
||||
}
|
||||
|
||||
private int _maxX = 127;
|
||||
private int _maxY = 127;
|
||||
public void SetRangeY(float[] range)
|
||||
{
|
||||
for (int i = 0; i < 3; i++) ActualRangeY[i] = range[i];
|
||||
Rerange();
|
||||
}
|
||||
|
||||
public int MinX { get { return 0 - MaxX - 1; } }
|
||||
public int MinY { get { return 0 - MaxY - 1; } }
|
||||
public float[] RangeX = new float[] { -128f, 0.0f, 127f };
|
||||
public float[] RangeY = new float[] { -128f, 0.0f, 127f };
|
||||
public float[] ActualRangeX = new float[] { -128f, 0.0f, 127f };
|
||||
public float[] ActualRangeY = new float[] { -128f, 0.0f, 127f };
|
||||
|
||||
float flipx = 1, flipy = 1;
|
||||
|
||||
void Rerange()
|
||||
{
|
||||
//baseline:
|
||||
//Array.Copy(ActualRangeX, RangeX, 3);
|
||||
//Array.Copy(ActualRangeY, RangeY, 3);
|
||||
|
||||
float rx = ActualRangeX[2] - ActualRangeX[0];
|
||||
float ry = ActualRangeY[2] - ActualRangeY[0];
|
||||
float midx = rx / 2 + ActualRangeX[0];
|
||||
float midy = ry / 2 + ActualRangeY[0];
|
||||
rx *= UserRangePercentageX / 100;
|
||||
ry *= UserRangePercentageY / 100;
|
||||
float minx = midx - rx / 2;
|
||||
float maxx = minx + rx;
|
||||
float miny = midy - ry / 2;
|
||||
float maxy = miny + ry;
|
||||
|
||||
if (minx > maxx)
|
||||
{
|
||||
float temp = minx;
|
||||
minx = maxx;
|
||||
maxx = temp;
|
||||
flipx = -1;
|
||||
}
|
||||
|
||||
if (miny > maxy)
|
||||
{
|
||||
float temp = miny;
|
||||
miny = maxy;
|
||||
maxy = temp;
|
||||
flipy = -1;
|
||||
}
|
||||
|
||||
//Range?[1] isn't really used
|
||||
RangeX[0] = minx;
|
||||
RangeX[2] = maxx;
|
||||
RangeY[0] = miny;
|
||||
RangeY[2] = maxy;
|
||||
|
||||
Clamp();
|
||||
}
|
||||
|
||||
//dont count on this working. it's never been tested.
|
||||
//but it kind of must be, or else nothing here would work...
|
||||
public float ScaleX = 0.5f;
|
||||
public float ScaleY = 0.5f;
|
||||
|
||||
int MinX { get { return (int)(RangeX[0]); } }
|
||||
int MinY { get { return (int)(RangeY[0]); } }
|
||||
int MaxX { get { return (int)(RangeX[2]); } }
|
||||
int MaxY { get { return (int)(RangeY[2]); } }
|
||||
int RangeSizeX { get { return (int)(MaxX - MinX + 1); } }
|
||||
int RangeSizeY { get { return (int)(MaxY - MinY + 1); } }
|
||||
|
||||
int PixelSizeX { get { return (int)(RangeSizeX * ScaleX); } }
|
||||
int PixelSizeY { get { return (int)(RangeSizeY * ScaleY); } }
|
||||
int PixelMinX { get { return (Size.Width - PixelSizeX) / 2; } }
|
||||
int PixelMinY { get { return (Size.Height - PixelSizeY) / 2; } }
|
||||
int PixelMidX { get { return PixelMinX + PixelSizeX / 2; } }
|
||||
int PixelMidY { get { return PixelMinY + PixelSizeY / 2; } }
|
||||
int PixelMaxX { get { return PixelMinX + PixelSizeX - 1; } }
|
||||
int PixelMaxY { get { return PixelMinY + PixelSizeY - 1; } }
|
||||
|
||||
private int RealToGfxX(int val)
|
||||
{
|
||||
int v = val;
|
||||
if (flipx == -1)
|
||||
v = (MaxX - val) + MinX;
|
||||
v = (int)(((float)v - MinX) * ScaleX);
|
||||
v += PixelMinX;
|
||||
return v;
|
||||
}
|
||||
|
||||
private int RealToGfxY(int val)
|
||||
{
|
||||
int v = val;
|
||||
if (flipy == -1)
|
||||
v = (MaxY - val) + MinY;
|
||||
v = (int)(((float)v - MinY) * ScaleY);
|
||||
v += PixelMinY;
|
||||
return v;
|
||||
}
|
||||
|
||||
private int GfxToRealX(int val)
|
||||
{
|
||||
val -= PixelMinX;
|
||||
float v = ((float)val / ScaleX + MinX);
|
||||
if (v < MinX) v = MinX;
|
||||
if (v > MaxX) v = MaxX;
|
||||
if (flipx == -1)
|
||||
v = (MaxX - v) + MinX;
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
private int GfxToRealY(int val)
|
||||
{
|
||||
val -= PixelMinY;
|
||||
float v;
|
||||
v = ((float)val / ScaleY + MinY);
|
||||
if (v < MinX) v = MinX;
|
||||
if (v > MaxX) v = MaxX;
|
||||
if(flipy == -1)
|
||||
v = (MaxY - v) + MinY;
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
private readonly Brush WhiteBrush = Brushes.White;
|
||||
private readonly Brush GrayBrush = Brushes.LightGray;
|
||||
|
@ -98,7 +209,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public AnalogStickPanel()
|
||||
{
|
||||
Size = new Size(MaxX + 1, MaxY + 1);
|
||||
Size = new Size(PixelSizeX + 1, PixelSizeY + 1);
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
||||
|
@ -126,30 +237,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private int RealToGfx(int val)
|
||||
{
|
||||
return (val + MaxX) / 2;
|
||||
}
|
||||
|
||||
private int GfxToReal(int val, bool isX) // isX is a hack
|
||||
{
|
||||
var max = isX ? MaxX : MaxY;
|
||||
var min = isX ? MinX : MinY;
|
||||
|
||||
var ret = (val * 2);
|
||||
if (ret > max)
|
||||
{
|
||||
ret = max;
|
||||
}
|
||||
|
||||
if (ret < min)
|
||||
{
|
||||
ret = min;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void SetAnalog()
|
||||
{
|
||||
var xn = HasValue ? X : (int?)null;
|
||||
|
@ -160,35 +247,33 @@ namespace BizHawk.Client.EmuHawk
|
|||
Refresh();
|
||||
}
|
||||
|
||||
private int MidX { get { return (int)((MaxX + 0.5) / 2); } }
|
||||
private int MidY { get { return (int)((MaxY + 0.5) / 2); } }
|
||||
|
||||
private void AnalogControlPanel_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
// Background
|
||||
e.Graphics.Clear(Color.Black);
|
||||
e.Graphics.FillRectangle(GrayBrush, 0, 0, MaxX, MaxY);
|
||||
e.Graphics.FillEllipse(ReadOnly ? OffWhiteBrush : WhiteBrush, 0, 0, MaxX - 1, MaxY - 3);
|
||||
e.Graphics.DrawEllipse(BlackPen, 0, 0, MaxX - 1, MaxY - 3);
|
||||
e.Graphics.DrawLine(BlackPen, MidX, 0, MidX, MaxY);
|
||||
e.Graphics.DrawLine(BlackPen, 0, MidY, MaxX, MidY);
|
||||
|
||||
e.Graphics.FillRectangle(GrayBrush, PixelMinX, PixelMinY, PixelMaxX - PixelMinX, PixelMaxY- PixelMinY);
|
||||
e.Graphics.FillEllipse(ReadOnly ? OffWhiteBrush : WhiteBrush, PixelMinX, PixelMinY, PixelMaxX - PixelMinX - 2, PixelMaxY - PixelMinY - 3);
|
||||
e.Graphics.DrawEllipse(BlackPen, PixelMinX, PixelMinY, PixelMaxX - PixelMinX - 2, PixelMaxY - PixelMinY - 3);
|
||||
e.Graphics.DrawLine(BlackPen, PixelMidX, 0, PixelMidX, PixelMaxY);
|
||||
e.Graphics.DrawLine(BlackPen, 0, PixelMidY, PixelMaxX, PixelMidY);
|
||||
|
||||
// Previous frame
|
||||
if (_previous != null)
|
||||
{
|
||||
var pX = (int)_previous.GetFloat(XName);
|
||||
var pY = (int)_previous.GetFloat(YName);
|
||||
e.Graphics.DrawLine(GrayPen, MidX, MidY, RealToGfx(pX), MaxY - RealToGfx(pY));
|
||||
e.Graphics.DrawImage(GrayDot, RealToGfx(pX) - 3, MaxY - RealToGfx(pY) - 3);
|
||||
e.Graphics.DrawLine(GrayPen, PixelMidX, PixelMidY, RealToGfxX(pX), RealToGfxY(pY));
|
||||
e.Graphics.DrawImage(GrayDot, RealToGfxX(pX) - 3, RealToGfxY(MaxY) - RealToGfxY(pY) - 3);
|
||||
}
|
||||
|
||||
// Line
|
||||
if (HasValue)
|
||||
{
|
||||
e.Graphics.DrawLine(BluePen, MidX, MidY, RealToGfx(X), MaxY - RealToGfx(Y));
|
||||
e.Graphics.DrawImage(ReadOnly ? GrayDot : Dot, RealToGfx(X) - 3, MaxY - RealToGfx(Y) - 3);
|
||||
e.Graphics.DrawLine(BluePen, PixelMidX, PixelMidY, RealToGfxX(X), RealToGfxY(Y));
|
||||
e.Graphics.DrawImage(ReadOnly ? GrayDot : Dot, RealToGfxX(X) - 3, RealToGfxY(Y) - 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,8 +284,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
X = GfxToReal(e.X - MidX, true);
|
||||
Y = GfxToReal(-(e.Y - MidY), false);
|
||||
X = GfxToRealX(e.X);
|
||||
Y = GfxToRealY(e.Y);
|
||||
Clamp();
|
||||
HasValue = true;
|
||||
SetAnalog();
|
||||
}
|
||||
|
@ -237,8 +323,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
X = GfxToReal(e.X - MidX, true);
|
||||
Y = GfxToReal(-(e.Y - MidY), false);
|
||||
X = GfxToRealX(e.X);
|
||||
Y = GfxToRealY(e.Y);
|
||||
Clamp();
|
||||
HasValue = true;
|
||||
}
|
||||
if (e.Button == MouseButtons.Right)
|
||||
|
@ -282,12 +369,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
X = xval;
|
||||
Y = yval;
|
||||
Clamp();
|
||||
HasValue = true;
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CheckMax()
|
||||
private void Clamp()
|
||||
{
|
||||
if (X > MaxX)
|
||||
{
|
||||
|
@ -306,8 +394,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
Y = MinY;
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
new PadSchema.ButtonScema
|
||||
{
|
||||
Name = "P" + controller + " X Axis",
|
||||
MinValue = -128,
|
||||
MidValue = 0,
|
||||
MaxValue = 127,
|
||||
MinValueSec = 127,
|
||||
MidValueSec = 0,
|
||||
MaxValueSec = -128,
|
||||
DisplayName = "",
|
||||
Location = new Point(6, 14),
|
||||
Type = PadSchema.PadInputType.AnalogStick
|
||||
|
|
|
@ -164,7 +164,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
new PadSchema.ButtonScema
|
||||
{
|
||||
Name = "P" + controller + " LStick X",
|
||||
MaxValue = 127,
|
||||
MinValue = 0,
|
||||
MidValue = 128,
|
||||
MaxValue = 255,
|
||||
MinValueSec = 0,
|
||||
MidValueSec = 128,
|
||||
MaxValueSec = 255,
|
||||
DisplayName = "",
|
||||
Location = new Point(3, 120),
|
||||
Type = PadSchema.PadInputType.AnalogStick
|
||||
|
@ -172,7 +177,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
new PadSchema.ButtonScema
|
||||
{
|
||||
Name = "P" + controller + " RStick X",
|
||||
MaxValue = 127,
|
||||
MinValue = 0,
|
||||
MidValue = 128,
|
||||
MaxValue = 255,
|
||||
MinValueSec = 0,
|
||||
MidValueSec = 128,
|
||||
MaxValueSec = 255,
|
||||
DisplayName = "",
|
||||
Location = new Point(210, 120),
|
||||
Type = PadSchema.PadInputType.AnalogStick
|
||||
|
|
|
@ -31,7 +31,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
public Size TargetSize { get; set; } // Specifically for TargetedPair, specifies the screen size
|
||||
public string[] SecondaryNames { get; set; } // Any other buttons necessary to operate (such as the Y axis)
|
||||
public int MaxValue { get; set; } // For non-boolean values, specifies the maximum value the button allows
|
||||
public int MidValue { get; set; } // For non-boolean values, specifies the mid (zero) value for the button
|
||||
public int MinValue { get; set; } // For non-boolean values, specifies the minimum value the button allows
|
||||
public int MaxValueSec { get; set; }
|
||||
public int MidValueSec { get; set; }
|
||||
public int MinValueSec { get; set; }
|
||||
public object OwnerEmulator { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue