311 lines
6.0 KiB
C#
311 lines
6.0 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
using BizHawk.Client.Common;
|
|
using BizHawk.Emulation.Common;
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
{
|
|
public partial class VirtualPadTargetScreen : UserControl, IVirtualPadControl
|
|
{
|
|
private readonly Pen BlackPen = new Pen(Brushes.Black, 2);
|
|
private readonly Pen WhitePen = new Pen(Brushes.White, 2);
|
|
private readonly Pen GrayPen = new Pen(Brushes.Gray, 2);
|
|
private readonly Pen RedPen = new Pen(Brushes.Red, 2);
|
|
|
|
private bool _isProgrammicallyChangingNumerics;
|
|
private bool _isDragging;
|
|
private bool _readonly;
|
|
private bool _isSet; // The tool has to keep track of this because there is currently no way to know if a float button is being autoheld or just held
|
|
|
|
private int? _overrideX = null;
|
|
private int? _overrideY = null;
|
|
|
|
public VirtualPadTargetScreen()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void VirtualPadTargetScreen_Load(object sender, EventArgs e)
|
|
{
|
|
XNumeric.Maximum = TargetPanel.Width - 1;
|
|
YNumeric.Maximum = TargetPanel.Height - 1;
|
|
}
|
|
|
|
#region IVirtualPadControl Implementation
|
|
|
|
public void UpdateValues()
|
|
{
|
|
TargetPanel.Refresh();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
Global.StickyXORAdapter.Unset(XName);
|
|
Global.StickyXORAdapter.Unset(YName);
|
|
_overrideX = null;
|
|
_overrideY = null;
|
|
_isSet = false;
|
|
Refresh();
|
|
}
|
|
|
|
public void Set(IController controller)
|
|
{
|
|
var newX = controller.GetFloat(XName) / MultiplierX;
|
|
var newY = controller.GetFloat(YName) / MultiplierY;
|
|
|
|
var oldX = X / MultiplierX;
|
|
var oldY = Y / MultiplierY;
|
|
|
|
var changed = newX != oldX && newY != oldY;
|
|
|
|
XNumeric.Value = (int)newX;
|
|
YNumeric.Value = (int)newY;
|
|
|
|
_overrideX = (int)newX;
|
|
_overrideY = (int)newY;
|
|
|
|
if (changed)
|
|
{
|
|
Refresh();
|
|
}
|
|
|
|
_isSet = true;
|
|
}
|
|
|
|
public bool ReadOnly
|
|
{
|
|
get
|
|
{
|
|
return _readonly;
|
|
}
|
|
|
|
set
|
|
{
|
|
if (_readonly != value)
|
|
{
|
|
XNumeric.Enabled =
|
|
XLabel.Enabled =
|
|
YNumeric.Enabled =
|
|
YLabel.Enabled =
|
|
!value;
|
|
|
|
_readonly = value;
|
|
Refresh();
|
|
}
|
|
|
|
if (!_readonly)
|
|
{
|
|
_overrideX = null;
|
|
_overrideY = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
// Size of the extra controls to the right / bottom of the target panel at 96 DPI
|
|
private Size PaddingSize
|
|
{
|
|
get { return new Size(0, 30); }
|
|
}
|
|
|
|
public Size TargetSize
|
|
{
|
|
get { return TargetPanel.Size; }
|
|
set
|
|
{
|
|
TargetPanel.Size = value;
|
|
Size = UIHelper.Scale(value + PaddingSize);
|
|
}
|
|
}
|
|
|
|
// These are the value that a maximum x or y actually represent, used to translate from control X,Y to values the core expects
|
|
public int RangeX { get; set; }
|
|
public int RangeY { get; set; }
|
|
|
|
public float MultiplierX
|
|
{
|
|
get
|
|
{
|
|
if (RangeX > 0)
|
|
{
|
|
return RangeX / (float)TargetPanel.Width;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public float MultiplierY
|
|
{
|
|
get
|
|
{
|
|
if (RangeY > 0)
|
|
{
|
|
return RangeY / (float)TargetPanel.Height;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public void Bump(int? x, int? y)
|
|
{
|
|
if (x.HasValue)
|
|
{
|
|
X = X + x.Value;
|
|
}
|
|
|
|
if (y.HasValue)
|
|
{
|
|
Y = Y + y.Value;
|
|
}
|
|
|
|
Refresh();
|
|
}
|
|
|
|
public string XName { get; set; }
|
|
public string YName { get; set; }
|
|
|
|
public int X
|
|
{
|
|
get
|
|
{
|
|
return _overrideX ?? (int)(Global.StickyXORAdapter.GetFloat(XName) / MultiplierX);
|
|
}
|
|
|
|
set
|
|
{
|
|
if (value < 0)
|
|
{
|
|
XNumeric.Value = 0;
|
|
|
|
}
|
|
else if (value <= XNumeric.Maximum)
|
|
{
|
|
XNumeric.Value = value;
|
|
}
|
|
else
|
|
{
|
|
XNumeric.Value = XNumeric.Maximum;
|
|
}
|
|
|
|
Global.StickyXORAdapter.SetFloat(XName, (int)((float)XNumeric.Value * MultiplierX));
|
|
_isSet = true;
|
|
}
|
|
}
|
|
public int Y
|
|
{
|
|
get
|
|
{
|
|
return _overrideY ?? (int)(Global.StickyXORAdapter.GetFloat(YName) / MultiplierY);
|
|
}
|
|
|
|
set
|
|
{
|
|
if (value < 0)
|
|
{
|
|
YNumeric.Value = 0;
|
|
}
|
|
else if (value <= YNumeric.Maximum)
|
|
{
|
|
YNumeric.Value = value;
|
|
}
|
|
else
|
|
{
|
|
YNumeric.Value = YNumeric.Maximum;
|
|
}
|
|
|
|
Global.StickyXORAdapter.SetFloat(YName, (int)((float)YNumeric.Value * MultiplierY));
|
|
_isSet = true;
|
|
}
|
|
}
|
|
|
|
private void UpdatePanelFromNumeric()
|
|
{
|
|
if (!_isProgrammicallyChangingNumerics)
|
|
{
|
|
TargetPanel.Refresh();
|
|
}
|
|
}
|
|
|
|
private void TargetPanel_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
e.Graphics.DrawEllipse(
|
|
ReadOnly ? GrayPen : _isSet ? RedPen : BlackPen,
|
|
X - 10,
|
|
Y - 10,
|
|
21,
|
|
21);
|
|
|
|
e.Graphics.DrawLine(
|
|
ReadOnly ? GrayPen : BlackPen,
|
|
new Point(X, Y - 10),
|
|
new Point(X, Y + 10));
|
|
|
|
e.Graphics.DrawLine(
|
|
ReadOnly ? GrayPen : BlackPen,
|
|
new Point(X - 10, Y),
|
|
new Point(X + 10, Y));
|
|
|
|
e.Graphics.FillEllipse(
|
|
ReadOnly ? Brushes.Gray : Brushes.Red,
|
|
new Rectangle(X - 2, Y - 2, 4, 4));
|
|
}
|
|
|
|
private void XNumeric_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdatePanelFromNumeric();
|
|
}
|
|
|
|
private void XNumeric_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
UpdatePanelFromNumeric();
|
|
}
|
|
|
|
private void YNumeric_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdatePanelFromNumeric();
|
|
}
|
|
|
|
private void YNumeric_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
UpdatePanelFromNumeric();
|
|
}
|
|
|
|
private void TargetPanel_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left && !ReadOnly)
|
|
{
|
|
_isDragging = true;
|
|
X = e.X;
|
|
Y = e.Y;
|
|
TargetPanel.Refresh();
|
|
}
|
|
}
|
|
|
|
private void TargetPanel_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if (_isDragging && !ReadOnly)
|
|
{
|
|
_isProgrammicallyChangingNumerics = true;
|
|
X = e.X;
|
|
Y = e.Y;
|
|
_isProgrammicallyChangingNumerics = false;
|
|
TargetPanel.Refresh();
|
|
}
|
|
}
|
|
|
|
private void TargetPanel_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
_isDragging = false;
|
|
TargetPanel.Refresh();
|
|
}
|
|
}
|
|
}
|
|
}
|