2013-04-28 13:56:29 +00:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
2014-05-16 13:40:21 +00:00
|
|
|
|
using BizHawk.Client.Common;
|
2014-06-24 17:30:14 +00:00
|
|
|
|
using BizHawk.Emulation.Common;
|
2014-05-16 13:40:21 +00:00
|
|
|
|
|
2013-11-03 03:54:37 +00:00
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
2013-04-28 13:56:29 +00:00
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
public sealed class AnalogStickPanel : Panel
|
2013-04-28 13:56:29 +00:00
|
|
|
|
{
|
2013-06-09 23:54:19 +00:00
|
|
|
|
public int X = 0;
|
|
|
|
|
public int Y = 0;
|
2013-11-16 14:35:42 +00:00
|
|
|
|
public bool HasValue = false;
|
2013-08-26 21:35:50 +00:00
|
|
|
|
|
2014-06-22 17:41:13 +00:00
|
|
|
|
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; } }
|
|
|
|
|
|
2014-06-24 17:48:25 +00:00
|
|
|
|
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 = new Pen(Brushes.Black);
|
|
|
|
|
private readonly Pen BluePen = new Pen(Brushes.Blue);
|
|
|
|
|
private readonly Pen GrayPen = new Pen(Brushes.LightGray);
|
|
|
|
|
|
|
|
|
|
private readonly Bitmap Dot = new Bitmap(7, 7);
|
|
|
|
|
private readonly Bitmap GrayDot = new Bitmap(7, 7);
|
2013-04-28 13:56:29 +00:00
|
|
|
|
|
2014-06-22 16:30:24 +00:00
|
|
|
|
public AnalogStickPanel()
|
2013-04-28 13:56:29 +00:00
|
|
|
|
{
|
2013-05-04 19:04:23 +00:00
|
|
|
|
Size = new Size(129, 129);
|
2013-04-28 13:56:29 +00:00
|
|
|
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
|
|
|
SetStyle(ControlStyles.UserPaint, true);
|
|
|
|
|
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
|
|
|
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
|
|
|
|
SetStyle(ControlStyles.Opaque, true);
|
2013-05-04 19:04:23 +00:00
|
|
|
|
BackColor = Color.Gray;
|
2013-04-28 13:56:29 +00:00
|
|
|
|
Paint += AnalogControlPanel_Paint;
|
2013-05-04 19:04:23 +00:00
|
|
|
|
BorderStyle = BorderStyle.Fixed3D;
|
2013-06-09 23:54:19 +00:00
|
|
|
|
|
|
|
|
|
// Draw the dot into a bitmap
|
2014-06-24 17:48:25 +00:00
|
|
|
|
Graphics g = Graphics.FromImage(Dot);
|
2013-06-09 23:54:19 +00:00
|
|
|
|
g.Clear(Color.Transparent);
|
2014-06-24 17:48:25 +00:00
|
|
|
|
g.FillRectangle(RedBrush, 2, 0, 3, 7);
|
|
|
|
|
g.FillRectangle(RedBrush, 1, 1, 5, 5);
|
|
|
|
|
g.FillRectangle(RedBrush, 0, 2, 7, 3);
|
2014-05-16 13:40:21 +00:00
|
|
|
|
|
2014-06-24 17:48:25 +00:00
|
|
|
|
Graphics gg = Graphics.FromImage(GrayDot);
|
2014-05-16 13:40:21 +00:00
|
|
|
|
gg.Clear(Color.Transparent);
|
|
|
|
|
gg.FillRectangle(Brushes.Gray, 2, 0, 3, 7);
|
|
|
|
|
gg.FillRectangle(Brushes.Gray, 1, 1, 5, 5);
|
|
|
|
|
gg.FillRectangle(Brushes.Gray, 0, 2, 7, 3);
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int RealToGFX(int val)
|
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
return (val + 128) / 2;
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 17:41:13 +00:00
|
|
|
|
private int GFXToReal(int val, bool isX) // isX is a hack
|
2013-05-04 19:04:23 +00:00
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
var max = isX ? MaxX : MaxY;
|
|
|
|
|
var min = isX ? MinX : MinY;
|
|
|
|
|
|
2013-06-09 23:54:19 +00:00
|
|
|
|
int ret = (val * 2);
|
2014-06-22 17:41:13 +00:00
|
|
|
|
if (ret > max)
|
2014-05-16 13:40:21 +00:00
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
ret = max;
|
2014-05-16 13:40:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 17:41:13 +00:00
|
|
|
|
if (ret < min)
|
2014-05-16 13:40:21 +00:00
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
ret = min;
|
2014-05-16 13:40:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-10 23:25:31 +00:00
|
|
|
|
return ret;
|
2013-04-28 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 16:30:24 +00:00
|
|
|
|
protected override void OnMouseClick(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SetAnalog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetAnalog()
|
|
|
|
|
{
|
|
|
|
|
int? xn = HasValue ? X : (int?)null;
|
|
|
|
|
int? yn = HasValue ? Y : (int?)null;
|
2014-06-22 17:41:13 +00:00
|
|
|
|
Global.StickyXORAdapter.SetFloat(XName, xn);
|
|
|
|
|
Global.StickyXORAdapter.SetFloat(YName, yn);
|
2014-06-22 16:30:24 +00:00
|
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-28 13:56:29 +00:00
|
|
|
|
private void AnalogControlPanel_Paint(object sender, PaintEventArgs e)
|
|
|
|
|
{
|
2013-05-04 19:04:23 +00:00
|
|
|
|
unchecked
|
|
|
|
|
{
|
|
|
|
|
//Background
|
2014-06-24 17:48:25 +00:00
|
|
|
|
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);
|
2014-06-22 17:41:13 +00:00
|
|
|
|
|
|
|
|
|
if (Global.MovieSession != null && Global.MovieSession.Movie != null && // For the desinger
|
2014-06-24 17:30:14 +00:00
|
|
|
|
Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsFinished &&
|
|
|
|
|
Global.Emulator.Frame > 1)
|
2014-05-16 13:40:21 +00:00
|
|
|
|
{
|
2014-06-24 17:30:14 +00:00
|
|
|
|
var input = Global.MovieSession.Movie.GetInputState(Global.Emulator.Frame - 2);
|
2014-05-16 13:40:21 +00:00
|
|
|
|
|
2014-06-24 17:48:25 +00:00
|
|
|
|
var x = (int)input.GetFloat(XName);
|
|
|
|
|
var y = (int)input.GetFloat(YName);
|
2014-05-16 13:40:21 +00:00
|
|
|
|
|
2014-06-24 17:48:25 +00:00
|
|
|
|
e.Graphics.DrawLine(GrayPen, 64, 63, RealToGFX(x), 127 - RealToGFX(y));
|
|
|
|
|
e.Graphics.DrawImage(GrayDot, RealToGFX(x) - 3, 127 - RealToGFX(y) - 3);
|
2014-05-16 13:40:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-04 19:04:23 +00:00
|
|
|
|
//Line
|
2013-08-26 21:35:50 +00:00
|
|
|
|
if (HasValue)
|
|
|
|
|
{
|
2014-06-24 17:48:25 +00:00
|
|
|
|
e.Graphics.DrawLine(BluePen, 64, 63, RealToGFX(X), 127 - RealToGFX(Y));
|
|
|
|
|
e.Graphics.DrawImage(Dot, RealToGFX(X) - 3, 127 - RealToGFX(Y) - 3);
|
2013-08-26 21:35:50 +00:00
|
|
|
|
}
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 21:35:50 +00:00
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
2013-05-04 19:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
X = GFXToReal(e.X - 64, true);
|
|
|
|
|
Y = GFXToReal(-(e.Y - 63), false);
|
2013-08-26 21:35:50 +00:00
|
|
|
|
HasValue = true;
|
2014-06-22 16:30:24 +00:00
|
|
|
|
SetAnalog();
|
2013-08-26 21:35:50 +00:00
|
|
|
|
}
|
2014-06-22 16:30:24 +00:00
|
|
|
|
else if (e.Button == MouseButtons.Right)
|
2013-08-26 21:35:50 +00:00
|
|
|
|
{
|
|
|
|
|
Clear();
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh();
|
2013-11-16 03:27:43 +00:00
|
|
|
|
base.OnMouseMove(e);
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 21:35:50 +00:00
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseUp(e);
|
2014-06-22 17:41:13 +00:00
|
|
|
|
Capture = false;
|
2013-08-26 21:35:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void WndProc(ref Message m)
|
|
|
|
|
{
|
|
|
|
|
if (m.Msg == 0x007B) //WM_CONTEXTMENU
|
|
|
|
|
{
|
|
|
|
|
//dont let parent controls get this.. we handle the right mouse button ourselves
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-06-22 16:30:24 +00:00
|
|
|
|
|
2013-08-26 21:35:50 +00:00
|
|
|
|
base.WndProc(ref m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
2013-05-04 19:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
2014-06-22 17:41:13 +00:00
|
|
|
|
X = GFXToReal(e.X - 64, true);
|
|
|
|
|
Y = GFXToReal(-(e.Y - 63), false);
|
2013-08-26 21:35:50 +00:00
|
|
|
|
HasValue = true;
|
|
|
|
|
}
|
2013-11-16 03:27:43 +00:00
|
|
|
|
if (e.Button == MouseButtons.Right)
|
2013-08-26 21:35:50 +00:00
|
|
|
|
{
|
|
|
|
|
Clear();
|
2013-05-04 19:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh();
|
2013-04-28 13:56:29 +00:00
|
|
|
|
}
|
2013-05-20 01:53:02 +00:00
|
|
|
|
|
2013-08-26 21:35:50 +00:00
|
|
|
|
|
2014-06-01 19:51:35 +00:00
|
|
|
|
public void Clear()
|
2013-08-26 21:35:50 +00:00
|
|
|
|
{
|
|
|
|
|
X = Y = 0;
|
|
|
|
|
HasValue = false;
|
2014-06-01 19:51:35 +00:00
|
|
|
|
Refresh();
|
2013-08-26 21:35:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-24 17:30:14 +00:00
|
|
|
|
public void Set(IController controller)
|
|
|
|
|
{
|
|
|
|
|
var newX = (int)controller.GetFloat(XName);
|
|
|
|
|
var newY = (int)controller.GetFloat(YName);
|
|
|
|
|
var changed = newX != X || newY != Y;
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
SetPosition(newX, newY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-16 03:27:43 +00:00
|
|
|
|
public void SetPosition(int xval, int yval)
|
2013-05-20 01:53:02 +00:00
|
|
|
|
{
|
2013-11-16 03:27:43 +00:00
|
|
|
|
X = xval;
|
|
|
|
|
Y = yval;
|
2013-08-26 21:35:50 +00:00
|
|
|
|
HasValue = true;
|
2013-05-20 01:53:02 +00:00
|
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|
2013-08-03 13:22:54 +00:00
|
|
|
|
|
2014-06-22 17:41:13 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
2013-04-28 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|