Refactor FloatRange creation and usage

effectively resolves #1200
* Replaced floats in FloatRange with ints (would have used shorts but
SubGBHawk/SubNesHawk use an axis to hack in cycle count or something), added
both Range<int> and Range<float> auto-properties
* Added bool field IsReversed to FloatRange
* Added enum AxisPairOrientation and factory method using it
* Cleaned up usages of FloatRange fields and properties
* Added new properties to PadSchema.ButtonSchema for type
PadInputType.AnalogStick (to hold the two FloatRanges) and used
ControllerDefinitions from cores to dedup these ranges in the schemata
* Made VirtualPadAnalogStick work properly: both the direction and bounds are
correctly set from the controller schemata, the polar conversion measures angles
consistently (though I think it might not work outside -128..127 e.g. for PSX),
and I didn't break the sensitivity override, plus negative percentages might
work now but I didn't allow those
* Renamed FloatRange to AxisRange, but did not rename related symbols
This commit is contained in:
YoshiRulz 2020-03-13 15:40:36 +10:00
parent 84ef5039ee
commit e12b5d8137
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
38 changed files with 256 additions and 373 deletions

View File

@ -28,7 +28,7 @@ namespace BizHawk.Client.Common
private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>(); private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>();
private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>(); private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>();
private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>(); private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>();
private readonly Dictionary<string, ControllerDefinition.FloatRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.FloatRange>(); private readonly Dictionary<string, ControllerDefinition.AxisRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.AxisRange>();
private readonly Dictionary<string, AnalogBind> _floatBinds = new Dictionary<string, AnalogBind>(); private readonly Dictionary<string, AnalogBind> _floatBinds = new Dictionary<string, AnalogBind>();
/// <summary>don't do this</summary> /// <summary>don't do this</summary>
@ -79,7 +79,7 @@ namespace BizHawk.Client.Common
// zero 09-mar-2015 - not sure if adding + 1 here is correct.. but... maybe? // zero 09-mar-2015 - not sure if adding + 1 here is correct.. but... maybe?
float output; float output;
if (range.Max < range.Min) if (range.IsReversed)
{ {
output = (((input * multiplier) + 10000.0f) * (range.Min - range.Max + 1) / 20000.0f) + range.Max; output = (((input * multiplier) + 10000.0f) * (range.Min - range.Max + 1) / 20000.0f) + range.Max;
} }
@ -90,22 +90,8 @@ namespace BizHawk.Client.Common
// zero 09-mar-2015 - at this point, we should only have integers, since that's all 100% of consoles ever see // zero 09-mar-2015 - at this point, we should only have integers, since that's all 100% of consoles ever see
// if this becomes a problem we can add flags to the range and update GUIs to be able to display floats // if this becomes a problem we can add flags to the range and update GUIs to be able to display floats
output = (int)output;
float lowerBound = Math.Min(range.Min, range.Max); _floatButtons[outKey] = output.ConstrainWithin(range.FloatRange);
float upperBound = Math.Max(range.Min, range.Max);
if (output < lowerBound)
{
output = lowerBound;
}
if (output > upperBound)
{
output = upperBound;
}
_floatButtons[outKey] = output;
} }
} }
} }

View File

@ -90,7 +90,7 @@ namespace BizHawk.Client.Common
{ {
int val; int val;
int i = _source.Definition.FloatControls.IndexOf(button); int i = _source.Definition.FloatControls.IndexOf(button);
int mid = (int)_source.Definition.FloatRanges[i].Mid; var mid = _source.Definition.FloatRanges[i].Mid;
if (createEmpty) if (createEmpty)
{ {

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -338,9 +339,9 @@ namespace BizHawk.Client.EmuHawk
if (column.Type == ColumnType.Float) if (column.Type == ColumnType.Float)
{ {
// feos: this could be cached, but I don't notice any slowdown this way either // feos: this could be cached, but I don't notice any slowdown this way either
ControllerDefinition.FloatRange range = ControllerType.FloatRanges ControllerDefinition.AxisRange range = ControllerType.FloatRanges
[ControllerType.FloatControls.IndexOf(columnName)]; [ControllerType.FloatControls.IndexOf(columnName)];
if (text == range.Mid.ToString()) if (text == ((float) range.Mid).ToString())
{ {
text = ""; text = "";
} }
@ -1190,29 +1191,7 @@ namespace BizHawk.Client.EmuHawk
return; return;
} }
float value = _floatPaintState + increment; var value = (_floatPaintState + increment).ConstrainWithin(ControllerType.FloatRanges[ControllerType.FloatControls.IndexOf(_floatEditColumn)].FloatRange);
ControllerDefinition.FloatRange range = ControllerType.FloatRanges
[ControllerType.FloatControls.IndexOf(_floatEditColumn)];
// Range for N64 Y axis has max -128 and min 127. That should probably be fixed in ControllerDefinition.cs.
// SuuperW: I really don't think changing it would break anything, but adelikat isn't so sure.
float rMax = range.Max;
float rMin = range.Min;
if (rMax < rMin)
{
rMax = range.Min;
rMin = range.Max;
}
if (value > rMax)
{
value = rMax;
}
else if (value < rMin)
{
value = rMin;
}
CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, value); CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, value);
_floatTypedValue = value.ToString(); _floatTypedValue = value.ToString();
@ -1285,23 +1264,13 @@ namespace BizHawk.Client.EmuHawk
float prev = value; float prev = value;
string prevTyped = _floatTypedValue; string prevTyped = _floatTypedValue;
ControllerDefinition.FloatRange range = ControllerType.FloatRanges var range = ControllerType.FloatRanges[ControllerType.FloatControls.IndexOf(_floatEditColumn)];
[ControllerType.FloatControls.IndexOf(_floatEditColumn)]; var (rMin, rMax) = range.FloatRange;
float rMax = range.Max;
float rMin = range.Min;
// Range for N64 Y axis has max -128 and min 127. That should probably be fixed ControllerDefinition.cs, but I'll put a quick fix here anyway.
if (rMax < rMin)
{
rMax = range.Min;
rMin = range.Max;
}
// feos: typing past max digits overwrites existing value, not touching the sign // feos: typing past max digits overwrites existing value, not touching the sign
// but doesn't handle situations where the range is like -50 through 100, where minimum is negative and has less digits // but doesn't handle situations where the range is like -50 through 100, where minimum is negative and has less digits
// it just uses 3 as maxDigits there too, leaving room for typing impossible values (that are still ignored by the game and then clamped) // it just uses 3 as maxDigits there too, leaving room for typing impossible values (that are still ignored by the game and then clamped)
int maxDigits = range.MaxDigits(); int maxDigits = range.MaxDigits;
int curDigits = _floatTypedValue.Length; int curDigits = _floatTypedValue.Length;
string curMinus; string curMinus;
if (_floatTypedValue.StartsWith("-")) if (_floatTypedValue.StartsWith("-"))

View File

@ -427,10 +427,10 @@ namespace BizHawk.Client.EmuHawk
int digits; int digits;
if (ControllerType.FloatControls.Contains(kvp.Key)) if (ControllerType.FloatControls.Contains(kvp.Key))
{ {
ControllerDefinition.FloatRange range = ControllerType.FloatRanges ControllerDefinition.AxisRange range = ControllerType.FloatRanges
[ControllerType.FloatControls.IndexOf(kvp.Key)]; [ControllerType.FloatControls.IndexOf(kvp.Key)];
type = ColumnType.Float; type = ColumnType.Float;
digits = Math.Max(kvp.Value.Length, range.MaxDigits()); digits = Math.Max(kvp.Value.Length, range.MaxDigits);
} }
else else
{ {

View File

@ -78,8 +78,8 @@ namespace BizHawk.Client.EmuHawk
SecondaryName = (button.SecondaryNames != null && button.SecondaryNames.Any()) ? button.SecondaryNames[0] : "", SecondaryName = (button.SecondaryNames != null && button.SecondaryNames.Any()) ? button.SecondaryNames[0] : "",
Location = UIHelper.Scale(button.Location), Location = UIHelper.Scale(button.Location),
Size = UIHelper.Scale(new Size(180 + 79, 200 + 9)), Size = UIHelper.Scale(new Size(180 + 79, 200 + 9)),
RangeX = new float[] { button.MinValue, button.MidValue, button.MaxValue }, RangeX = button.AxisRange ?? throw new Exception(),
RangeY = new float[] { button.MinValueSec, button.MidValueSec, button.MaxValueSec }, RangeY = button.SecondaryAxisRange ?? throw new Exception()
}); });
break; break;
case PadSchema.PadInputType.TargetedPair: case PadSchema.PadInputType.TargetedPair:

View File

@ -11,22 +11,8 @@ namespace BizHawk.Client.EmuHawk
{ {
public partial class VirtualPadAnalogStick : UserControl, IVirtualPadControl public partial class VirtualPadAnalogStick : UserControl, IVirtualPadControl
{ {
/// <summary>for coordinate transformation when non orthogonal (like PSX for example)</summary>
private int rangeAverageX;
/// <inheritdoc cref="rangeAverageX"/>
private int rangeAverageY;
private Range<int> _rangeX = AnalogStickPanel.DefaultRange;
private Range<int> _rangeY = AnalogStickPanel.DefaultRange;
private bool _readonly; private bool _readonly;
private bool _reverseX;
private bool _reverseY;
private bool _updatingFromAnalog; private bool _updatingFromAnalog;
private bool _updatingFromPolar; private bool _updatingFromPolar;
@ -44,45 +30,25 @@ namespace BizHawk.Client.EmuHawk
manualTheta.ValueChanged += PolarNumeric_Changed; manualTheta.ValueChanged += PolarNumeric_Changed;
} }
public float[] RangeX public ControllerDefinition.AxisRange RangeX { get; set; }
{
set
{
if (value.Length != 3) throw new ArgumentException("must be float[3]", nameof(value));
#if false
_midX = (int) value[1];
#endif
_reverseX = value[2] < value[0];
_rangeX = _reverseX ? ((int) value[2]).RangeTo((int) value[0]) : ((int) value[0]).RangeTo((int) value[2]);
}
}
public float[] RangeY public ControllerDefinition.AxisRange RangeY { get; set; }
{
set
{
if (value.Length != 3) throw new ArgumentException("must be float[3]", nameof(value));
#if false
_midY = (int) value[1];
#endif
_reverseY = value[2] < value[0];
_rangeY = _reverseY ? ((int) value[2]).RangeTo((int) value[0]) : ((int) value[0]).RangeTo((int) value[2]);
}
}
public string? SecondaryName { get; set; } public string? SecondaryName { get; set; }
private void VirtualPadAnalogStick_Load(object sender, EventArgs e) private void VirtualPadAnalogStick_Load(object sender, EventArgs e)
{ {
AnalogStick.XName = AnalogStick.Name = Name; AnalogStick.Init(
AnalogStick.SetRangeX(_rangeX); Name,
AnalogStick.YName = !string.IsNullOrEmpty(SecondaryName) ? SecondaryName : Name.Replace("X", "Y"); RangeX,
AnalogStick.SetRangeY(_rangeY); !string.IsNullOrEmpty(SecondaryName) ? SecondaryName : Name.Replace("X", "Y"),
RangeY
);
ManualX.Minimum = _rangeX.Start; ManualX.Minimum = RangeX.Min;
ManualX.Maximum = _rangeX.EndInclusive; ManualX.Maximum = RangeX.Max;
ManualY.Minimum = _rangeY.Start; ManualY.Minimum = RangeY.Min;
ManualY.Maximum = _rangeY.EndInclusive; ManualY.Maximum = RangeY.Max;
MaxXNumeric.Minimum = 1; MaxXNumeric.Minimum = 1;
MaxXNumeric.Maximum = 100; MaxXNumeric.Maximum = 100;
MaxYNumeric.Minimum = 1; MaxYNumeric.Minimum = 1;
@ -91,9 +57,6 @@ namespace BizHawk.Client.EmuHawk
// these trigger Change events that set the analog stick's values too // these trigger Change events that set the analog stick's values too
MaxXNumeric.Value = 100; MaxXNumeric.Value = 100;
MaxYNumeric.Value = 100; MaxYNumeric.Value = 100;
rangeAverageX = (_rangeX.Start + _rangeX.EndInclusive) / 2;
rangeAverageY = (_rangeY.Start + _rangeY.EndInclusive) / 2;
} }
public void UpdateValues() public void UpdateValues()
@ -168,14 +131,19 @@ namespace BizHawk.Client.EmuHawk
public void SetPrevious(IController previous) => AnalogStick.SetPrevious(previous); public void SetPrevious(IController previous) => AnalogStick.SetPrevious(previous);
private (ushort R, ushort Θ) RectToPolarHelper(int x, int y) => PolarRectConversion.RectToPolarLookup(
(sbyte) (RangeX.IsReversed ? RangeX.Mid - x : x - RangeX.Mid),
(sbyte) (RangeY.IsReversed ? RangeY.Mid - y : y - RangeY.Mid)
);
private void ManualXY_ValueChanged(object sender, EventArgs e) private void ManualXY_ValueChanged(object sender, EventArgs e)
{ {
if (_updatingFromAnalog || _updatingFromPolar) return; if (_updatingFromAnalog || _updatingFromPolar) return;
_updatingFromXY = true; _updatingFromXY = true;
var x = (sbyte) ManualX.Value; var x = (int) ManualX.Value;
var y = (sbyte) ManualY.Value; var y = (int) ManualY.Value;
var (r, θ) = PolarRectConversion.RectToPolarLookup(x, y); var (r, θ) = RectToPolarHelper(x, y);
SetAnalog(x, y); SetAnalog(x, y);
SetPolar(r, θ); SetPolar(r, θ);
@ -183,7 +151,7 @@ namespace BizHawk.Client.EmuHawk
} }
private void MaxManualXY_ValueChanged(object sender, EventArgs e) private void MaxManualXY_ValueChanged(object sender, EventArgs e)
=> AnalogStick.SetUserRange(_reverseX ? -MaxXNumeric.Value : MaxXNumeric.Value, _reverseY ? -MaxYNumeric.Value : MaxYNumeric.Value); => AnalogStick.SetUserRange((int) MaxXNumeric.Value, (int) MaxYNumeric.Value);
private void PolarNumeric_Changed(object sender, EventArgs e) private void PolarNumeric_Changed(object sender, EventArgs e)
{ {
@ -191,8 +159,8 @@ namespace BizHawk.Client.EmuHawk
_updatingFromPolar = true; _updatingFromPolar = true;
var (x, y) = PolarRectConversion.PolarToRectLookup((ushort) manualR.Value, (ushort) manualTheta.Value); var (x, y) = PolarRectConversion.PolarToRectLookup((ushort) manualR.Value, (ushort) manualTheta.Value);
var x1 = (rangeAverageX + x).ConstrainWithin(_rangeX); var x1 = (RangeX.IsReversed ? RangeX.Mid - x : RangeX.Mid + x).ConstrainWithin(RangeX.Range);
var y1 = (rangeAverageY + y).ConstrainWithin(_rangeY); var y1 = (RangeY.IsReversed ? RangeY.Mid - y : RangeY.Mid + y).ConstrainWithin(RangeY.Range);
SetAnalog(x1, y1); SetAnalog(x1, y1);
SetXY(x1, y1); SetXY(x1, y1);
@ -227,9 +195,9 @@ namespace BizHawk.Client.EmuHawk
if (AnalogStick.HasValue) if (AnalogStick.HasValue)
{ {
var x = AnalogStick.X - rangeAverageX; var x = AnalogStick.X;
var y = AnalogStick.Y - rangeAverageY; var y = AnalogStick.Y;
var (r, θ) = PolarRectConversion.RectToPolarLookup((sbyte) x, (sbyte) y); var (r, θ) = RectToPolarHelper(x, y);
SetPolar(r, θ); SetPolar(r, θ);
SetXY(x, y); SetXY(x, y);
} }

View File

@ -37,59 +37,53 @@ namespace BizHawk.Client.EmuHawk
public bool HasValue; public bool HasValue;
public bool ReadOnly { private get; set; } public bool ReadOnly { private get; set; }
public string XName = string.Empty; public string XName { get; private set; } = string.Empty;
public string YName = string.Empty; public string YName { get; private set; } = string.Empty;
private IController _previous; private IController _previous;
private sbyte _userRangePercentageX = 100; private int _userRangePercentageX = 100;
private sbyte _userRangePercentageY = 100; private int _userRangePercentageY = 100;
public void SetUserRange(decimal rx, decimal ry) public void SetUserRange(int rx, int ry)
{ {
_userRangePercentageX = (sbyte) rx; _userRangePercentageX = rx.ConstrainWithin(PercentRange);
_userRangePercentageY = (sbyte) ry; _userRangePercentageY = ry.ConstrainWithin(PercentRange);
Rerange(); Rerange();
Refresh(); Refresh();
} }
public void SetRangeX(Range<int> range) public void Init(string nameX, ControllerDefinition.AxisRange rangeX, string nameY, ControllerDefinition.AxisRange rangeY)
{ {
_actualRangeX = range; Name = XName = nameX;
_fullRangeX = rangeX;
YName = nameY;
_fullRangeY = rangeY;
Rerange(); Rerange();
} }
public void SetRangeY(Range<int> range) private Range<int> _rangeX = 0.RangeTo(0);
{ private Range<int> _rangeY = 0.RangeTo(0);
_actualRangeY = range; private ControllerDefinition.AxisRange _fullRangeX;
Rerange(); private ControllerDefinition.AxisRange _fullRangeY;
}
private Range<int> _rangeX = DefaultRange;
private Range<int> _rangeY = DefaultRange;
private Range<int> _actualRangeX = DefaultRange;
private Range<int> _actualRangeY = DefaultRange;
private bool _reverseX; private bool _reverseX;
private bool _reverseY; private bool _reverseY;
private void Rerange() private void Rerange()
{ {
_reverseX = _userRangePercentageX < 0; _reverseX = _fullRangeX.IsReversed ^ _userRangePercentageX < 0;
_reverseY = _userRangePercentageY < 0; _reverseY = _fullRangeY.IsReversed ^ _userRangePercentageY < 0;
var midX = (_actualRangeX.Start + _actualRangeX.EndInclusive) / 2.0; _rangeX = (_fullRangeX.Mid - (_fullRangeX.Mid - _fullRangeX.Min) * _userRangePercentageX / 100)
var halfRangeX = (_reverseX ? -1 : 1) * (_actualRangeX.EndInclusive - _actualRangeX.Start) * _userRangePercentageX / 200.0; .RangeTo(_fullRangeX.Mid + (_fullRangeX.Max - _fullRangeX.Mid) * _userRangePercentageX / 100);
_rangeX = ((int) (midX - halfRangeX)).RangeTo((int) (midX + halfRangeX)); _rangeY = (_fullRangeY.Mid - (_fullRangeY.Mid - _fullRangeY.Min) * _userRangePercentageY / 100)
.RangeTo(_fullRangeY.Mid + (_fullRangeY.Max - _fullRangeY.Mid) * _userRangePercentageY / 100);
var midY = (_actualRangeY.Start + _actualRangeY.EndInclusive) / 2.0; _x = _x.ConstrainWithin(_rangeX);
var halfRangeY = (_reverseY ? -1 : 1) * (_actualRangeY.EndInclusive - _actualRangeY.Start) * _userRangePercentageY / 200.0; _y = _y.ConstrainWithin(_rangeY);
_rangeY = ((int) (midY - halfRangeY)).RangeTo((int) (midY + halfRangeY)); SetAnalog();
// re-constrain after changing ranges
X = X;
Y = Y;
} }
/// <remarks> /// <remarks>
@ -104,7 +98,7 @@ namespace BizHawk.Client.EmuHawk
/// </remarks> /// </remarks>
private int MaybeReversedInX(int i) => _reverseX ? _rangeX.Start + _rangeX.EndInclusive - i : i; private int MaybeReversedInX(int i) => _reverseX ? _rangeX.Start + _rangeX.EndInclusive - i : i;
/// <inheritdoc cref="MaybeReversedInX"/> /// <inheritdoc cref="MaybeReversedInX"/>
private int MaybeReversedInY(int i) => _reverseY ? _rangeY.Start + _rangeY.EndInclusive - i : i; private int MaybeReversedInY(int i) => _reverseY ? i : _rangeY.Start + _rangeY.EndInclusive - i;
private int PixelSizeX => (int)(_rangeX.Count() * ScaleX); private int PixelSizeX => (int)(_rangeX.Count() * ScaleX);
private int PixelSizeY => (int)(_rangeY.Count() * ScaleY); private int PixelSizeY => (int)(_rangeY.Count() * ScaleY);
@ -286,6 +280,6 @@ namespace BizHawk.Client.EmuHawk
Refresh(); Refresh();
} }
internal static readonly Range<int> DefaultRange = (-128).RangeTo(127); private static readonly Range<int> PercentRange = 0.RangeTo(100);
} }
} }

View File

@ -185,6 +185,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema TurboController(int controller) private static PadSchema TurboController(int controller)
{ {
var controllerDefRanges = new ColecoTurboController(controller).Definition.FloatRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -194,12 +195,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} Disc X", Name = $"P{controller} Disc X",
MinValue = -127, AxisRange = controllerDefRanges[0],
MidValue = 0, SecondaryAxisRange = controllerDefRanges[1],
MaxValue = 127,
MinValueSec = 127,
MidValueSec = 0,
MaxValueSec = -127,
DisplayName = "", DisplayName = "",
Location = new Point(6, 14), Location = new Point(6, 14),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -283,6 +283,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema AnalogController(int controller) private static PadSchema AnalogController(int controller)
{ {
var controllerDefRanges = new FakeAnalogController(controller).Definition.FloatRanges;
return new PadSchema return new PadSchema
{ {
DisplayName = $"Player {controller}", DisplayName = $"Player {controller}",
@ -407,12 +408,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} Disc X", Name = $"P{controller} Disc X",
MinValue = -127, AxisRange = controllerDefRanges[0],
MidValue = 0, SecondaryAxisRange = controllerDefRanges[1],
MaxValue = 127,
MinValueSec = 127,
MidValueSec = 0,
MaxValueSec = -127,
DisplayName = "", DisplayName = "",
Location = new Point(1, 121), Location = new Point(1, 121),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -24,6 +24,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema StandardController(int controller) private static PadSchema StandardController(int controller)
{ {
var controllerDefRanges = N64Input.N64ControllerDefinition.FloatRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -135,12 +136,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} X Axis", Name = $"P{controller} X Axis",
MinValue = -128, AxisRange = controllerDefRanges[0],
MidValue = 0, SecondaryAxisRange = controllerDefRanges[1],
MaxValue = 127,
MinValueSec = 127,
MidValueSec = 0,
MaxValueSec = -128,
DisplayName = "", DisplayName = "",
Location = new Point(6, 14), Location = new Point(6, 14),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -46,6 +46,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema DualShockController(int controller) private static PadSchema DualShockController(int controller)
{ {
var stickRanges = Octoshock.DualShockStickRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -176,12 +177,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} LStick X", Name = $"P{controller} LStick X",
MinValue = 0, AxisRange = stickRanges[0],
MidValue = 128, SecondaryAxisRange = stickRanges[1],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 128,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(3, 120), Location = new Point(3, 120),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick
@ -189,12 +186,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} RStick X", Name = $"P{controller} RStick X",
MinValue = 0, AxisRange = stickRanges[0],
MidValue = 128, SecondaryAxisRange = stickRanges[1],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 128,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(260, 120), Location = new Point(260, 120),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -2,6 +2,8 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public class PadSchema public class PadSchema
@ -40,6 +42,10 @@ namespace BizHawk.Client.EmuHawk
public object OwnerEmulator { get; set; } public object OwnerEmulator { get; set; }
public Orientation Orientation { get; set; } // For Single Float controls public Orientation Orientation { get; set; } // For Single Float controls
// for Analog Stick controls
public ControllerDefinition.AxisRange? AxisRange { get; set; }
public ControllerDefinition.AxisRange? SecondaryAxisRange { get; set; }
} }
} }
} }

View File

@ -175,6 +175,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema ThreeDeeController(int controller) private static PadSchema ThreeDeeController(int controller)
{ {
var axisRanges = SaturnusControllerDeck.ThreeDeeAxisRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -266,12 +267,8 @@ namespace BizHawk.Client.EmuHawk
{ {
Name = $"P{controller} Stick Horizontal", Name = $"P{controller} Stick Horizontal",
SecondaryNames = new[] { $"P{controller} Stick Vertical" }, SecondaryNames = new[] { $"P{controller} Stick Vertical" },
MinValue = 0, AxisRange = axisRanges[0],
MidValue = 127, SecondaryAxisRange = axisRanges[1],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 127,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(6, 74), Location = new Point(6, 74),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick
@ -440,6 +437,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema MissionControl(int controller) private static PadSchema MissionControl(int controller)
{ {
var axisRanges = SaturnusControllerDeck.MissionAxisRanges;
return new PadSchema return new PadSchema
{ {
DisplayName = "Mission", DisplayName = "Mission",
@ -514,12 +512,8 @@ namespace BizHawk.Client.EmuHawk
{ {
Name = $"P{controller} Stick Horizontal", Name = $"P{controller} Stick Horizontal",
SecondaryNames = new[] { $"P{controller} Stick Vertical" }, SecondaryNames = new[] { $"P{controller} Stick Vertical" },
MinValue = 0, AxisRange = axisRanges[0],
MidValue = 127, SecondaryAxisRange = axisRanges[1],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 127,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(185, 13), Location = new Point(185, 13),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick
@ -541,6 +535,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema DualMissionControl(int controller) private static PadSchema DualMissionControl(int controller)
{ {
var axisRanges = SaturnusControllerDeck.DualMissionAxisRanges;
return new PadSchema return new PadSchema
{ {
DisplayName = "Dual Mission", DisplayName = "Dual Mission",
@ -552,12 +547,8 @@ namespace BizHawk.Client.EmuHawk
{ {
Name = $"P{controller} Left Stick Horizontal", Name = $"P{controller} Left Stick Horizontal",
SecondaryNames = new[] { $"P{controller} Left Stick Vertical" }, SecondaryNames = new[] { $"P{controller} Left Stick Vertical" },
MinValue = 0, AxisRange = axisRanges[3],
MidValue = 127, SecondaryAxisRange = axisRanges[4],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 127,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(58, 13), Location = new Point(58, 13),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick
@ -577,12 +568,8 @@ namespace BizHawk.Client.EmuHawk
{ {
Name = $"P{controller} Right Stick Horizontal", Name = $"P{controller} Right Stick Horizontal",
SecondaryNames = new[] { $"P{controller} Right Stick Vertical" }, SecondaryNames = new[] { $"P{controller} Right Stick Vertical" },
MinValue = 0, AxisRange = axisRanges[0],
MidValue = 127, SecondaryAxisRange = axisRanges[1],
MaxValue = 255,
MinValueSec = 0,
MidValueSec = 127,
MaxValueSec = 255,
DisplayName = "", DisplayName = "",
Location = new Point(400, 13), Location = new Point(400, 13),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -212,6 +212,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema Mouse(int controller) private static PadSchema Mouse(int controller)
{ {
var controllerDefRanges = new SnesMouseController().Definition.FloatRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -221,12 +222,8 @@ namespace BizHawk.Client.EmuHawk
new PadSchema.ButtonSchema new PadSchema.ButtonSchema
{ {
Name = $"P{controller} Mouse X", Name = $"P{controller} Mouse X",
MinValue = -128, AxisRange = controllerDefRanges[0],
MidValue = 0, SecondaryAxisRange = controllerDefRanges[1],
MaxValue = 127,
MinValueSec = 127,
MidValueSec = 0,
MaxValueSec = -128,
DisplayName = "", DisplayName = "",
Location = new Point(6, 14), Location = new Point(6, 14),
Type = PadSchema.PadInputType.AnalogStick Type = PadSchema.PadInputType.AnalogStick

View File

@ -107,6 +107,7 @@ namespace BizHawk.Client.EmuHawk
private static PadSchema AnalogController(int controller) private static PadSchema AnalogController(int controller)
{ {
var controllerDefRanges = new AnalogControls(controller).Definition.FloatRanges;
return new PadSchema return new PadSchema
{ {
IsConsole = false, IsConsole = false,
@ -145,12 +146,8 @@ namespace BizHawk.Client.EmuHawk
{ {
Name = $"P{controller} Stick X", Name = $"P{controller} Stick X",
Location = new Point(2, 80), Location = new Point(2, 80),
MinValue = 127, AxisRange = controllerDefRanges[0],
MidValue = 0, SecondaryAxisRange = controllerDefRanges[1],
MaxValue = -128,
MinValueSec = -128,
MidValueSec = 0,
MaxValueSec = 127,
Type = PadSchema.PadInputType.AnalogStick, Type = PadSchema.PadInputType.AnalogStick,
SecondaryNames = new[] SecondaryNames = new[]
{ {

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using BizHawk.Common;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
{ {
/// <summary> /// <summary>
@ -45,7 +47,7 @@ namespace BizHawk.Emulation.Common
/// Gets a list of all float ranges for each float control (must be one to one with FloatControls) /// Gets a list of all float ranges for each float control (must be one to one with FloatControls)
/// FloatRanges include the min/max/default values /// FloatRanges include the min/max/default values
/// </summary> /// </summary>
public List<FloatRange> FloatRanges { get; } = new List<FloatRange>(); public List<AxisRange> FloatRanges { get; set; } = new List<AxisRange>();
/// <summary> /// <summary>
/// Gets the axis constraints that apply artificial constraints to float values /// Gets the axis constraints that apply artificial constraints to float values
@ -100,44 +102,50 @@ namespace BizHawk.Emulation.Common
} }
} }
public struct FloatRange public readonly struct AxisRange
{ {
public readonly float Min; public readonly bool IsReversed;
public readonly float Max;
/// <summary> public readonly int Max;
/// default position
/// </summary>
public readonly float Mid;
public FloatRange(float min, float mid, float max) /// <remarks>used as default/neutral/unset</remarks>
public readonly int Mid;
public readonly int Min;
public Range<float> FloatRange => ((float) Min).RangeTo(Max);
/// <value>maximum decimal digits analog input can occupy with no-args ToString</value>
/// <remarks>does not include the extra char needed for a minus sign</remarks>
public int MaxDigits => Math.Max(Math.Abs(Min).ToString().Length, Math.Abs(Max).ToString().Length);
public Range<int> Range => Min.RangeTo(Max);
public AxisRange(int min, int mid, int max, bool isReversed = false)
{ {
Min = min; const string ReversedBoundsExceptionMessage = nameof(AxisRange) + " must not have " + nameof(max) + " < " + nameof(min) + ". pass " + nameof(isReversed) + ": true to ctor instead, or use " + nameof(CreateAxisRangePair);
Mid = mid; if (max < min) throw new ArgumentOutOfRangeException(nameof(max), max, ReversedBoundsExceptionMessage);
IsReversed = isReversed;
Max = max; Max = max;
Mid = mid;
Min = min;
} }
}
/// <summary>for terse construction</summary> public static List<AxisRange> CreateAxisRangePair(int min, int mid, int max, AxisPairOrientation pDir) => new List<AxisRange>
/// <exception cref="ArgumentException">length <paramref name="f"/> is not <c>3</c></exception> {
public static implicit operator FloatRange(float[] f) new AxisRange(min, mid, max, ((byte) pDir & 2) != 0),
{ new AxisRange(min, mid, max, ((byte) pDir & 1) != 0)
if (f.Length != 3) };
{
throw new ArgumentException();
}
return new FloatRange(f[0], f[1], f[2]); /// <summary>represents the direction of <c>(+, +)</c></summary>
} /// <remarks>docs of individual controllers are being collected in comments of https://github.com/TASVideos/BizHawk/issues/1200</remarks>
public enum AxisPairOrientation : byte
/// <summary> {
/// Gets maximum decimal digits analog input can occupy. Discards negative sign and possible fractional part (analog devices don't use floats anyway). RightAndUp = 0,
/// </summary> RightAndDown = 1,
public int MaxDigits() LeftAndUp = 2,
{ LeftAndDown = 3
return Math.Max(
Math.Abs((int)Min).ToString().Length,
Math.Abs((int)Max).ToString().Length);
}
} }
public enum AxisConstraintType public enum AxisConstraintType

View File

@ -121,7 +121,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
.Select(b => $"P{PortNum} " + b) .Select(b => $"P{PortNum} " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Paddle X 1" , "P" + PortNum + " Paddle X 2" }, FloatControls = { "P" + PortNum + " Paddle X 1" , "P" + PortNum + " Paddle X 2" },
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } } FloatRanges = { new ControllerDefinition.AxisRange(-127, 0, 127), new ControllerDefinition.AxisRange(-127, 0, 127) }
}; };
} }
@ -238,7 +238,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
.Select(b => $"P{PortNum} " + b) .Select(b => $"P{PortNum} " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Wheel X 1", "P" + PortNum + " Wheel X 2" }, FloatControls = { "P" + PortNum + " Wheel X 1", "P" + PortNum + " Wheel X 2" },
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } } FloatRanges = { new ControllerDefinition.AxisRange(-127, 0, 127), new ControllerDefinition.AxisRange(-127, 0, 127) }
}; };
} }

View File

@ -276,7 +276,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " X", "P" + PortNum + " Y" }, FloatControls = { "P" + PortNum + " X", "P" + PortNum + " Y" },
FloatRanges = { new[] { 1.0f, 160, 320.0f }, new[] { 1.0f, 121, 242.0f } } FloatRanges = { new ControllerDefinition.AxisRange(1, 160, 320), new ControllerDefinition.AxisRange(1, 121, 242) }
}; };
} }

View File

@ -65,11 +65,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Belogic
{ {
"P1 Mouse X", "P1 Mouse Y" "P1 Mouse X", "P1 Mouse Y"
}, },
FloatRanges = FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
{
new[] { -127f, 0f, 127f },
new[] { -127f, 0f, 127f }
}
}; };
private static readonly string[] PadBits = private static readonly string[] PadBits =

View File

@ -136,7 +136,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" }, FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" },
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } } FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
}; };
} }
@ -241,7 +241,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" }, FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" },
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } } FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
}; };
} }

View File

@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Stick X", "P" + PortNum + " Stick Y" }, FloatControls = { "P" + PortNum + " Stick X", "P" + PortNum + " Stick Y" },
FloatRanges = { new[] { -128.0f, 0, 127.0f }, new[] { -128.0f, 0, 127.0f } } FloatRanges = ControllerDefinition.CreateAxisRangePair(-128, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp)
}; };
} }

View File

@ -145,7 +145,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" }, FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" },
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } } FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
}; };
} }

View File

@ -140,11 +140,7 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
{ {
BoolButtons = { "0Mouse Left", "0Mouse Right" }, BoolButtons = { "0Mouse Left", "0Mouse Right" },
FloatControls = { "0X", "0Y" }, FloatControls = { "0X", "0Y" },
FloatRanges = FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
{
new[] { -127f, 0f, 127f },
new[] { -127f, 0f, 127f }
}
}; };
public ControllerDefinition Definition => _definition; public ControllerDefinition Definition => _definition;

View File

@ -4,6 +4,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
{ {
public static class GBA public static class GBA
{ {
private static readonly ControllerDefinition.AxisRange TiltRange = new ControllerDefinition.AxisRange(-32767, 0, 32767);
public static readonly ControllerDefinition GBAController = new ControllerDefinition public static readonly ControllerDefinition GBAController = new ControllerDefinition
{ {
Name = "GBA Controller", Name = "GBA Controller",
@ -13,14 +15,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
}, },
FloatControls = FloatControls =
{ {
"Tilt X", "Tilt Y", "Tilt Z", "Light Sensor" "Tilt X", "Tilt Y", "Tilt Z",
"Light Sensor"
}, },
FloatRanges = FloatRanges =
{ {
new[] { -32767f, 0f, 32767f }, TiltRange, TiltRange, TiltRange,
new[] { -32767f, 0f, 32767f }, new ControllerDefinition.AxisRange(0, 100, 200),
new[] { -32767f, 0f, 32767f },
new[] { 0f, 100f, 200f },
} }
}; };
} }

View File

@ -118,7 +118,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Tilt X", "P" + PortNum + " Tilt Y" }, FloatControls = { "P" + PortNum + " Tilt X", "P" + PortNum + " Tilt Y" },
FloatRanges = { new[] { -45.0f, 0, 45.0f }, new[] { -45.0f, 0, 45.0f } } FloatRanges = ControllerDefinition.CreateAxisRangePair(-45, 0, 45, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
}; };
} }

View File

@ -1,9 +1,12 @@
using BizHawk.Emulation.Common; using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.N64.NativeApi; using BizHawk.Emulation.Cores.Nintendo.N64.NativeApi;
namespace BizHawk.Emulation.Cores.Nintendo.N64 namespace BizHawk.Emulation.Cores.Nintendo.N64
{ {
internal class N64Input public class N64Input
{ {
private readonly mupen64plusInputApi _api; private readonly mupen64plusInputApi _api;
public CoreComm CoreComm { get; } public CoreComm CoreComm { get; }
@ -13,6 +16,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
public bool ThisFrameInputPolled { get; set; } public bool ThisFrameInputPolled { get; set; }
public ControllerDefinition ControllerDefinition => N64ControllerDefinition; public ControllerDefinition ControllerDefinition => N64ControllerDefinition;
private static readonly List<ControllerDefinition.AxisRange> AnalogStickRanges = ControllerDefinition.CreateAxisRangePair(-128, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp);
public static readonly ControllerDefinition N64ControllerDefinition = new ControllerDefinition public static readonly ControllerDefinition N64ControllerDefinition = new ControllerDefinition
{ {
Name = "Nintendo 64 Controller", Name = "Nintendo 64 Controller",
@ -25,17 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
{ {
"P1 X Axis", "P1 Y Axis", "P1 X Axis", "P1 Y Axis",
}, },
FloatRanges = FloatRanges = AnalogStickRanges.Concat(AnalogStickRanges).Concat(AnalogStickRanges).Concat(AnalogStickRanges).ToList(), //TODO is this supposed to be duplicated? docs say FloatRanges.Count should equal FloatControls.Count --yoshi
{
new[] {-128.0f, 0.0f, 127.0f},
new[] {127.0f, 0.0f, -128.0f},
new[] {-128.0f, 0.0f, 127.0f},
new[] {127.0f, 0.0f, -128.0f},
new[] {-128.0f, 0.0f, 127.0f},
new[] {127.0f, 0.0f, -128.0f},
new[] {-128.0f, 0.0f, 127.0f},
new[] {127.0f, 0.0f, -128.0f}
},
AxisConstraints = AxisConstraints =
{ {
new ControllerDefinition.AxisConstraint { Class = "Natural Circle", Type = ControllerDefinition.AxisConstraintType.Circular, Params = new object[] {"P1 X Axis", "P1 Y Axis", 127.0f} } new ControllerDefinition.AxisConstraint { Class = "Natural Circle", Type = ControllerDefinition.AxisConstraintType.Circular, Params = new object[] {"P1 X Axis", "P1 Y Axis", 127.0f} }
@ -44,7 +39,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
private readonly IInputPollable _emuCore; private readonly IInputPollable _emuCore;
public N64Input(IInputPollable emuCore, mupen64plusApi core, CoreComm comm, N64SyncSettings.N64ControllerSettings[] controllerSettings) internal N64Input(IInputPollable emuCore, mupen64plusApi core, CoreComm comm, N64SyncSettings.N64ControllerSettings[] controllerSettings)
{ {
_emuCore = emuCore; _emuCore = emuCore;
_api = new mupen64plusInputApi(core); _api = new mupen64plusInputApi(core);

View File

@ -171,7 +171,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (using_reset_timing && ControllerDefinition.FloatControls.Count == 0) if (using_reset_timing && ControllerDefinition.FloatControls.Count == 0)
{ {
ControllerDefinition.FloatControls.Add("Reset Cycle"); ControllerDefinition.FloatControls.Add("Reset Cycle");
ControllerDefinition.FloatRanges.Add(new ControllerDefinition.FloatRange(0, 0, 500000)); ControllerDefinition.FloatRanges.Add(new ControllerDefinition.AxisRange(0, 0, 500000));
} }
// don't replace the magicSoundProvider on reset, as it's not needed // don't replace the magicSoundProvider on reset, as it's not needed

View File

@ -185,6 +185,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
Right.SyncState(ser); Right.SyncState(ser);
ser.EndSection(); ser.EndSection();
} }
internal static readonly ControllerDefinition.AxisRange ArkanoidPaddleRange = new ControllerDefinition.AxisRange(0, 80, 160);
internal static readonly List<ControllerDefinition.AxisRange> ZapperRanges = new List<ControllerDefinition.AxisRange> { new ControllerDefinition.AxisRange(0, 128, 255), new ControllerDefinition.AxisRange(0, 120, 239) };
} }
public class UnpluggedNES : INesPort public class UnpluggedNES : INesPort
@ -392,7 +396,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
BoolButtons = { "0Fire" }, BoolButtons = { "0Fire" },
FloatControls = { "0Paddle" }, FloatControls = { "0Paddle" },
FloatRanges = { new[] { 0.0f, 80.0f, 160.0f } } FloatRanges = { NesDeck.ArkanoidPaddleRange }
}; };
public void Strobe(StrobeInfo s, IController c) public void Strobe(StrobeInfo s, IController c)
@ -557,7 +561,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
BoolButtons = { "0Fire" }, BoolButtons = { "0Fire" },
FloatControls = { "0Zapper X", "0Zapper Y" }, FloatControls = { "0Zapper X", "0Zapper Y" },
FloatRanges = { new[] { 0.0f, 128.0f, 255.0f }, new[] { 0.0f, 120.0f, 239.0f } } FloatRanges = NesDeck.ZapperRanges
}; };
public void Strobe(StrobeInfo s, IController c) public void Strobe(StrobeInfo s, IController c)
@ -610,7 +614,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
BoolButtons = { "0Fire" }, BoolButtons = { "0Fire" },
FloatControls = { "0Zapper X", "0Zapper Y" }, FloatControls = { "0Zapper X", "0Zapper Y" },
FloatRanges = { new[] { 0.0f, 128.0f, 255.0f }, new[] { 0.0f, 120.0f, 239.0f } } FloatRanges = NesDeck.ZapperRanges
}; };
void Latch(IController c) void Latch(IController c)
@ -752,7 +756,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
BoolButtons = { "0Fire" }, BoolButtons = { "0Fire" },
FloatControls = { "0Paddle" }, FloatControls = { "0Paddle" },
FloatRanges = { new[] { 0.0f, 80.0f, 160.0f } } FloatRanges = { NesDeck.ArkanoidPaddleRange }
}; };
public void Strobe(StrobeInfo s, IController c) public void Strobe(StrobeInfo s, IController c)
@ -1012,7 +1016,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
BoolButtons = { "0Click", "0Touch" }, BoolButtons = { "0Click", "0Touch" },
FloatControls = { "0Pen X", "0Pen Y" }, FloatControls = { "0Pen X", "0Pen Y" },
FloatRanges = { new[] { 0.0f, 128.0f, 255.0f }, new[] { 0.0f, 120.0f, 239.0f } } FloatRanges = NesDeck.ZapperRanges // why would a tablet have the same resolution as a CRT monitor? --yoshi
}; };
bool resetting; bool resetting;

View File

@ -20,6 +20,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
Payload Payload
} }
/// <remarks>
/// problem: when you're in 240 line mode, the limit on Y needs to be 240. when you're in 224 mode, it needs to be 224.
/// perhaps the deck needs to account for this...
/// for reference Snes9x is always in 224 mode
/// </remarks>
public static readonly List<ControllerDefinition.AxisRange> LightGunRanges = new List<ControllerDefinition.AxisRange> { new ControllerDefinition.AxisRange(0, 128, 256), new ControllerDefinition.AxisRange(0, 0, 240) };
private static ILibsnesController Factory(ControllerType t, LibsnesCore.SnesSyncSettings ss) private static ILibsnesController Factory(ControllerType t, LibsnesCore.SnesSyncSettings ss)
{ {
switch (t) switch (t)
@ -284,11 +291,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
"0Mouse X", "0Mouse X",
"0Mouse Y" "0Mouse Y"
}, },
FloatRanges = FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
{
new[] { -127f, 0f, 127f },
new[] { -127f, 0f, 127f }
}
}; };
public ControllerDefinition Definition => _definition; public ControllerDefinition Definition => _definition;
@ -343,13 +346,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
"0Scope X", "0Scope X",
"0Scope Y" "0Scope Y"
}, },
FloatRanges = FloatRanges = LibsnesControllerDeck.LightGunRanges
{
// problem: when you're in 240 line mode, the limit on Y needs to be 240.
// when you're in 224 mode, it needs to be 224. perhaps the deck needs to account for this...
new[] { 0f, 128f, 256f },
new[] { 0f, 0f, 240f }
}
}; };
public ControllerDefinition Definition => _definition; public ControllerDefinition Definition => _definition;
@ -398,15 +395,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
"1Justifier X", "1Justifier X",
"1Justifier Y", "1Justifier Y",
}, },
FloatRanges = FloatRanges = LibsnesControllerDeck.LightGunRanges.Concat(LibsnesControllerDeck.LightGunRanges).ToList()
{
// problem: when you're in 240 line mode, the limit on Y needs to be 240.
// when you're in 224 mode, it needs to be 224. perhaps the deck needs to account for this...
new[] { 0f, 128f, 256f },
new[] { 0f, 0f, 240f },
new[] { 0f, 128f, 256f },
new[] { 0f, 0f, 240f }
}
}; };
public ControllerDefinition Definition => _definition; public ControllerDefinition Definition => _definition;

View File

@ -214,11 +214,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
"0Mouse X", "0Mouse X",
"0Mouse Y" "0Mouse Y"
}, },
FloatRanges = FloatRanges = ControllerDefinition.CreateAxisRangePair(-127, 0, 127, ControllerDefinition.AxisPairOrientation.RightAndUp) //TODO verify direction against hardware
{
new[] { -127f, 0f, 127f },
new[] { -127f, 0f, 127f }
}
}; };
public override ControllerDefinition Definition => _definition; public override ControllerDefinition Definition => _definition;
@ -240,12 +236,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
"0Scope X", "0Scope X",
"0Scope Y" "0Scope Y"
}, },
FloatRanges = FloatRanges = SNES.LibsnesControllerDeck.LightGunRanges
{
// snes9x is always in 224 mode
new[] { 0f, 128f, 256f },
new[] { 0f, 0f, 240f }
}
}; };
public override ControllerDefinition Definition => _definition; public override ControllerDefinition Definition => _definition;
@ -265,12 +256,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
"0Justifier X", "0Justifier X",
"0Justifier Y", "0Justifier Y",
}, },
FloatRanges = FloatRanges = SNES.LibsnesControllerDeck.LightGunRanges
{
// snes9x is always in 224 mode
new[] { 0f, 128f, 256f },
new[] { 0f, 0f, 240f },
}
}; };
public override ControllerDefinition Definition => _definition; public override ControllerDefinition Definition => _definition;

View File

@ -44,7 +44,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
ser.Register(_tracer); ser.Register(_tracer);
_GBCore.ControllerDefinition.FloatControls.Add("Input Cycle"); _GBCore.ControllerDefinition.FloatControls.Add("Input Cycle");
_GBCore.ControllerDefinition.FloatRanges.Add(new ControllerDefinition.FloatRange(0, 70224, 70224)); _GBCore.ControllerDefinition.FloatRanges.Add(new ControllerDefinition.AxisRange(0, 70224, 70224));
} }
public GBHawk.GBHawk _GBCore; public GBHawk.GBHawk _GBCore;

View File

@ -25,7 +25,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return SMSPaddleController; return SMSPaddleController;
case SmsSyncSettings.ControllerTypes.LightPhaser: case SmsSyncSettings.ControllerTypes.LightPhaser:
// scale the vertical to the display mode // scale the vertical to the display mode
SMSLightPhaserController.FloatRanges[1] = new ControllerDefinition.FloatRange(0, Vdp.FrameHeight / 2, Vdp.FrameHeight - 1); SMSLightPhaserController.FloatRanges[1] = new ControllerDefinition.AxisRange(0, Vdp.FrameHeight / 2, Vdp.FrameHeight - 1);
return SMSLightPhaserController; return SMSLightPhaserController;
case SmsSyncSettings.ControllerTypes.SportsPad: case SmsSyncSettings.ControllerTypes.SportsPad:

View File

@ -1,4 +1,7 @@
using BizHawk.Emulation.Common; using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Sega.MasterSystem namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{ {
@ -41,8 +44,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}, },
FloatRanges = FloatRanges =
{ {
new ControllerDefinition.FloatRange(0, 128, 255), new ControllerDefinition.AxisRange(0, 128, 255),
new ControllerDefinition.FloatRange(0, 128, 255) new ControllerDefinition.AxisRange(0, 128, 255)
} }
}; };
@ -60,11 +63,14 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}, },
FloatRanges = FloatRanges =
{ {
new ControllerDefinition.FloatRange(0, 64, 127), new ControllerDefinition.AxisRange(0, 64, 127),
new ControllerDefinition.FloatRange(0, 500, 1000) new ControllerDefinition.AxisRange(0, 500, 1000)
} }
}; };
/// <remarks>TODO verify direction against hardware</remarks>
private static readonly List<ControllerDefinition.AxisRange> SportsPadTrackballRanges = ControllerDefinition.CreateAxisRangePair(-64, 0, 63, ControllerDefinition.AxisPairOrientation.RightAndUp);
public static readonly ControllerDefinition SMSSportsPadController = new ControllerDefinition public static readonly ControllerDefinition SMSSportsPadController = new ControllerDefinition
{ {
Name = "SMS Sports Pad Controller", Name = "SMS Sports Pad Controller",
@ -79,13 +85,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
"P1 X", "P1 Y", "P1 X", "P1 Y",
"P2 X", "P2 Y" "P2 X", "P2 Y"
}, },
FloatRanges = FloatRanges = SportsPadTrackballRanges.Concat(SportsPadTrackballRanges).ToList()
{
new ControllerDefinition.FloatRange(-64, 0, 63),
new ControllerDefinition.FloatRange(-64, 0, 63),
new ControllerDefinition.FloatRange(-64, 0, 63),
new ControllerDefinition.FloatRange(-64, 0, 63)
}
}; };
public static readonly ControllerDefinition SMSKeyboardController = new ControllerDefinition public static readonly ControllerDefinition SMSKeyboardController = new ControllerDefinition

View File

@ -61,6 +61,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
return _data; return _data;
} }
/// <remarks>TODO verify direction against hardware</remarks>
private static readonly List<AxisRange> AnalogStickRanges = CreateAxisRangePair(0, 128, 255, AxisPairOrientation.RightAndDown);
private static readonly AxisRange MiscAxisRange = new AxisRange(0, 128, 255);
public static readonly List<AxisRange> MissionAxisRanges = AnalogStickRanges.Concat(new List<AxisRange> { MiscAxisRange }).ToList();
public static readonly List<AxisRange> DualMissionAxisRanges = MissionAxisRanges.Concat(MissionAxisRanges).ToList();
public static readonly List<AxisRange> ThreeDeeAxisRanges = AnalogStickRanges.Concat(new List<AxisRange> { new AxisRange(0, 0, 255), new AxisRange(0, 0, 255) }).ToList();
public enum Device public enum Device
{ {
None, None,
@ -95,8 +106,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
private abstract class ButtonedDevice : IDevice private abstract class ButtonedDevice : IDevice
{ {
private static readonly FloatRange AnalogFloatRange = new FloatRange(0, 128, 255);
protected ButtonedDevice() protected ButtonedDevice()
{ {
_bakedButtonNames = ButtonNames.Select(s => s != null ? "0" + s : null).ToArray(); _bakedButtonNames = ButtonNames.Select(s => s != null ? "0" + s : null).ToArray();
@ -115,7 +124,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
.Select((s, i) => new { s, i }) .Select((s, i) => new { s, i })
.OrderBy(a => AnalogOrdinal(AnalogNames[a.i])) .OrderBy(a => AnalogOrdinal(AnalogNames[a.i]))
.Select(a => a.s)); .Select(a => a.s));
Definition.FloatRanges.AddRange(_bakedAnalogNames.Select(s => AnalogFloatRange)); Definition.FloatRanges.AddRange(_bakedAnalogNames.Select(s => MiscAxisRange));
} }
private readonly string[] _bakedButtonNames; private readonly string[] _bakedButtonNames;
@ -233,8 +242,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
public ThreeDeeGamepad() public ThreeDeeGamepad()
{ {
Definition.FloatRanges[2] = new FloatRange(0, 0, 255); Definition.FloatRanges = ThreeDeeAxisRanges;
Definition.FloatRanges[3] = new FloatRange(0, 0, 255);
} }
public override void Update(IController controller, byte[] dest, int offset) public override void Update(IController controller, byte[] dest, int offset)
@ -358,6 +366,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
protected override string[] AnalogNames => _analogNames; protected override string[] AnalogNames => _analogNames;
protected override int AnalogByteOffset => 4; protected override int AnalogByteOffset => 4;
public Mission()
{
Definition.FloatRanges = MissionAxisRanges;
}
protected override int ButtonOrdinal(string name) protected override int ButtonOrdinal(string name)
{ {
switch (name) switch (name)
@ -397,6 +410,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
}; };
protected override string[] AnalogNames => _analogNames; protected override string[] AnalogNames => _analogNames;
public DualMission()
{
Definition.FloatRanges = DualMissionAxisRanges;
}
} }
private class Keyboard : ButtonedDevice private class Keyboard : ButtonedDevice

View File

@ -93,12 +93,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
new CName("XE E2", LibGPGX.INPUT_KEYS.INPUT_XE_E2), new CName("XE E2", LibGPGX.INPUT_KEYS.INPUT_XE_E2),
}; };
private static readonly ControllerDefinition.FloatRange MouseRange = new ControllerDefinition.FloatRange(-256, 0, 255); private static readonly ControllerDefinition.AxisRange MouseRange = new ControllerDefinition.AxisRange(-256, 0, 255);
// lightgun needs to be transformed to match the current screen resolution // lightgun needs to be transformed to match the current screen resolution
private static readonly ControllerDefinition.FloatRange LightgunRange = new ControllerDefinition.FloatRange(0, 5000, 10000); private static readonly ControllerDefinition.AxisRange LightgunRange = new ControllerDefinition.AxisRange(0, 5000, 10000);
private static readonly ControllerDefinition.FloatRange Xea1PRange = new ControllerDefinition.FloatRange(-128, 0, 127); private static readonly ControllerDefinition.AxisRange Xea1PRange = new ControllerDefinition.AxisRange(-128, 0, 127);
private LibGPGX.InputData _target; private LibGPGX.InputData _target;
private IController _source; private IController _source;

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -40,6 +41,12 @@ namespace BizHawk.Emulation.Cores.Sony.PSP
attachedcore = this; attachedcore = this;
} }
/// <remarks>TODO</remarks>
private static readonly List<ControllerDefinition.AxisRange> AnalogStickRanges = ControllerDefinition.CreateAxisRangePair(-1, 0, 1, ControllerDefinition.AxisPairOrientation.RightAndUp);
/// <remarks>TODO</remarks>
private static readonly ControllerDefinition.AxisRange TriggerRange = new ControllerDefinition.AxisRange(-1, 0, 1);
public static readonly ControllerDefinition PSPController = new ControllerDefinition public static readonly ControllerDefinition PSPController = new ControllerDefinition
{ {
Name = "PSP Controller", Name = "PSP Controller",
@ -51,17 +58,12 @@ namespace BizHawk.Emulation.Cores.Sony.PSP
}, },
FloatControls = FloatControls =
{ {
"Left Stick X", "Left Stick Y", "Right Stick X", "Right Stick Y", "Left Trigger", "Right Trigger" "Left Stick X", "Left Stick Y",
"Right Stick X", "Right Stick Y",
"Left Trigger",
"Right Trigger"
}, },
FloatRanges = // TODO FloatRanges = AnalogStickRanges.Concat(AnalogStickRanges).Concat(new List<ControllerDefinition.AxisRange> { TriggerRange, TriggerRange }).ToList()
{
new[] {-1.0f, 0.0f, 1.0f},
new[] {-1.0f, 0.0f, 1.0f},
new[] {-1.0f, 0.0f, 1.0f},
new[] {-1.0f, 0.0f, 1.0f},
new[] {-1.0f, 0.0f, 1.0f},
new[] {-1.0f, 0.0f, 1.0f},
}
}; };
public ControllerDefinition ControllerDefinition => PSPController; public ControllerDefinition ControllerDefinition => PSPController;

View File

@ -15,6 +15,7 @@ using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -216,6 +217,8 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public string SystemId => "PSX"; public string SystemId => "PSX";
public static readonly IReadOnlyList<ControllerDefinition.AxisRange> DualShockStickRanges = ControllerDefinition.CreateAxisRangePair(0, 128, 255, ControllerDefinition.AxisPairOrientation.RightAndDown);
public static ControllerDefinition CreateControllerDefinition(SyncSettings syncSettings) public static ControllerDefinition CreateControllerDefinition(SyncSettings syncSettings)
{ {
var definition = new ControllerDefinition { Name = "PSX Front Panel" }; var definition = new ControllerDefinition { Name = "PSX Front Panel" };
@ -249,10 +252,11 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
"P" + pnum + " L" "P" + pnum + " L"
}); });
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f }); var axisRange = new ControllerDefinition.AxisRange(0, 128, 255);
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f }); definition.FloatRanges.Add(axisRange);
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f }); definition.FloatRanges.Add(axisRange);
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f }); definition.FloatRanges.Add(axisRange);
definition.FloatRanges.Add(axisRange);
} }
else else
{ {
@ -289,10 +293,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
"P" + pnum + " RStick Y" "P" + pnum + " RStick Y"
}); });
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f }); definition.FloatRanges.AddRange(DualShockStickRanges.Concat(DualShockStickRanges).ToList());
definition.FloatRanges.Add(new[] { 255.0f, 128.0f, 0.0f });
definition.FloatRanges.Add(new[] { 0.0f, 128.0f, 255.0f });
definition.FloatRanges.Add(new[] { 255.0f, 128.0f, 0.0f });
} }
} }
} }
@ -307,9 +308,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
definition.FloatControls.Add("Disc Select"); definition.FloatControls.Add("Disc Select");
definition.FloatRanges.Add( definition.FloatRanges.Add(
//new[] {-1f,-1f,-1f} //this is carefully chosen so that we end up with a -1 disc by default (indicating that it's never been set) //new ControllerDefinition.AxisRange(-1, -1, -1) //this is carefully chosen so that we end up with a -1 disc by default (indicating that it's never been set)
//hmm.. I don't see why this wouldn't work //hmm.. I don't see why this wouldn't work
new[] { 0f, 1f, 1f } new ControllerDefinition.AxisRange(0, 1, 1)
); );
return definition; return definition;

View File

@ -260,8 +260,7 @@ namespace BizHawk.Emulation.Cores.Libretro
definition.BoolButtons.Add("Pointer Pressed"); //TODO: this isnt showing up in the binding panel. I don't want to find out why. definition.BoolButtons.Add("Pointer Pressed"); //TODO: this isnt showing up in the binding panel. I don't want to find out why.
definition.FloatControls.Add("Pointer X"); definition.FloatControls.Add("Pointer X");
definition.FloatControls.Add("Pointer Y"); definition.FloatControls.Add("Pointer Y");
definition.FloatRanges.Add(new ControllerDefinition.FloatRange(-32767, 0, 32767)); definition.FloatRanges.AddRange(ControllerDefinition.CreateAxisRangePair(-32767, 0, 32767, ControllerDefinition.AxisPairOrientation.RightAndUp));
definition.FloatRanges.Add(new ControllerDefinition.FloatRange(-32767, 0, 32767));
foreach (var key in new[]{ foreach (var key in new[]{
"Key Backspace", "Key Tab", "Key Clear", "Key Return", "Key Pause", "Key Escape", "Key Backspace", "Key Tab", "Key Clear", "Key Return", "Key Pause", "Key Escape",