Use inheritance for AxisConstraints
This commit is contained in:
parent
15906af6e4
commit
1e67fc1d4b
|
@ -97,7 +97,7 @@ namespace BizHawk.Emulation.Common
|
|||
/// For instance, a N64 controller's analog range is actually larger than the amount allowed by the plastic that artificially constrains it to lower values
|
||||
/// Axis constraints provide a way to technically allow the full range but have a user option to constrain down to typical values that a real control would have
|
||||
/// </summary>
|
||||
public readonly AxisConstraint? Constraint;
|
||||
public readonly AxisConstraint Constraint;
|
||||
|
||||
public Range<float> FloatRange => ((float) Min).RangeTo(Max);
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public readonly Range<int> Range;
|
||||
|
||||
public AxisSpec(Range<int> range, int mid, bool isReversed = false, AxisConstraint? constraint = null)
|
||||
public AxisSpec(Range<int> range, int mid, bool isReversed = false, AxisConstraint constraint = null)
|
||||
{
|
||||
Constraint = constraint;
|
||||
IsReversed = isReversed;
|
||||
|
@ -132,37 +132,17 @@ namespace BizHawk.Emulation.Common
|
|||
public void ApplyAxisConstraints(string constraintClass, IDictionary<string, int> axes)
|
||||
{
|
||||
if (!Axes.HasContraints) return;
|
||||
|
||||
foreach (var kvp in Axes)
|
||||
{
|
||||
if (kvp.Value.Constraint == null) continue;
|
||||
var constraint = kvp.Value.Constraint.Value;
|
||||
|
||||
if (constraint.Class != constraintClass) continue;
|
||||
|
||||
switch (constraint.Type)
|
||||
var constraint = kvp.Value.Constraint;
|
||||
if (constraint == null || constraint.Class != constraintClass) continue;
|
||||
switch (constraint)
|
||||
{
|
||||
case AxisConstraintType.Circular:
|
||||
{
|
||||
string xAxis = constraint.Params[0] as string ?? "";
|
||||
string yAxis = constraint.Params[1] as string ?? "";
|
||||
float range = (float)constraint.Params[2];
|
||||
if (!axes.ContainsKey(xAxis)) break;
|
||||
if (!axes.ContainsKey(yAxis)) break;
|
||||
double xVal = axes[xAxis];
|
||||
double yVal = axes[yAxis];
|
||||
double length = Math.Sqrt((xVal * xVal) + (yVal * yVal));
|
||||
if (length > range)
|
||||
{
|
||||
double ratio = range / length;
|
||||
xVal *= ratio;
|
||||
yVal *= ratio;
|
||||
}
|
||||
|
||||
axes[xAxis] = (int) xVal;
|
||||
axes[yAxis] = (int) yVal;
|
||||
break;
|
||||
}
|
||||
case CircularAxisConstraint circular:
|
||||
var xAxis = kvp.Key;
|
||||
var yAxis = circular.PairedAxis;
|
||||
(axes[xAxis], axes[yAxis]) = circular.ApplyTo(axes[xAxis], axes[yAxis]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,16 +157,38 @@ namespace BizHawk.Emulation.Common
|
|||
LeftAndDown = 3
|
||||
}
|
||||
|
||||
public enum AxisConstraintType
|
||||
public interface AxisConstraint
|
||||
{
|
||||
Circular
|
||||
public string Class { get; }
|
||||
|
||||
public string PairedAxis { get; }
|
||||
}
|
||||
|
||||
public struct AxisConstraint
|
||||
public sealed class CircularAxisConstraint : AxisConstraint
|
||||
{
|
||||
public string Class;
|
||||
public AxisConstraintType Type;
|
||||
public object[] Params;
|
||||
public string Class { get; }
|
||||
|
||||
private readonly float Magnitude;
|
||||
|
||||
public string PairedAxis { get; }
|
||||
|
||||
public CircularAxisConstraint(string @class, string pairedAxis, float magnitude)
|
||||
{
|
||||
Class = @class;
|
||||
Magnitude = magnitude;
|
||||
PairedAxis = pairedAxis;
|
||||
}
|
||||
|
||||
public (int X, int Y) ApplyTo(int rawX, int rawY)
|
||||
{
|
||||
var xVal = (double) rawX;
|
||||
var yVal = (double) rawY;
|
||||
var length = Math.Sqrt(xVal * xVal + yVal * yVal);
|
||||
var ratio = Magnitude / length;
|
||||
return ratio < 1.0
|
||||
? ((int) (xVal * ratio), (int) (yVal * ratio))
|
||||
: ((int) xVal, (int) yVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -407,7 +407,7 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
/// <param name="constraint">pass only for one axis in a pair, by convention the X axis</param>
|
||||
/// <returns>identical reference to <paramref name="def"/>; the object is mutated</returns>
|
||||
public static ControllerDefinition AddAxis(this ControllerDefinition def, string name, Range<int> range, int mid, bool isReversed = false, AxisConstraint? constraint = null)
|
||||
public static ControllerDefinition AddAxis(this ControllerDefinition def, string name, Range<int> range, int mid, bool isReversed = false, AxisConstraint constraint = null)
|
||||
{
|
||||
def.Axes.Add(name, new AxisSpec(range, mid, isReversed, constraint));
|
||||
return def;
|
||||
|
@ -419,7 +419,7 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
/// <param name="nameFormat">format string e.g. <c>"P1 Left {0}"</c> (will be used to interpolate <c>"X"</c> and <c>"Y"</c>)</param>
|
||||
/// <returns>identical reference to <paramref name="def"/>; the object is mutated</returns>
|
||||
public static ControllerDefinition AddXYPair(this ControllerDefinition def, string nameFormat, AxisPairOrientation pDir, Range<int> rangeX, int midX, Range<int> rangeY, int midY, AxisConstraint? constraint = null)
|
||||
public static ControllerDefinition AddXYPair(this ControllerDefinition def, string nameFormat, AxisPairOrientation pDir, Range<int> rangeX, int midX, Range<int> rangeY, int midY, AxisConstraint constraint = null)
|
||||
=> def.AddAxis(string.Format(nameFormat, "X"), rangeX, midX, ((byte) pDir & 2) != 0, constraint)
|
||||
.AddAxis(string.Format(nameFormat, "Y"), rangeY, midY, ((byte) pDir & 1) != 0);
|
||||
|
||||
|
@ -429,7 +429,7 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
/// <param name="nameFormat">format string e.g. <c>"P1 Left {0}"</c> (will be used to interpolate <c>"X"</c> and <c>"Y"</c>)</param>
|
||||
/// <returns>identical reference to <paramref name="def"/>; the object is mutated</returns>
|
||||
public static ControllerDefinition AddXYPair(this ControllerDefinition def, string nameFormat, AxisPairOrientation pDir, Range<int> rangeBoth, int midBoth, AxisConstraint? constraint = null)
|
||||
public static ControllerDefinition AddXYPair(this ControllerDefinition def, string nameFormat, AxisPairOrientation pDir, Range<int> rangeBoth, int midBoth, AxisConstraint constraint = null)
|
||||
=> def.AddXYPair(nameFormat, pDir, rangeBoth, midBoth, rangeBoth, midBoth, constraint);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -40,12 +40,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
|
|||
AxisPairOrientation.RightAndUp,
|
||||
(-128).RangeTo(127),
|
||||
0,
|
||||
new AxisConstraint
|
||||
{
|
||||
Class = "Natural Circle",
|
||||
Type = AxisConstraintType.Circular,
|
||||
Params = new object[] { $"P{player} X Axis", $"P{player} Y Axis", 127.0f }
|
||||
}
|
||||
new CircularAxisConstraint("Natural Circle", $"P{player} Y Axis", 127.0f)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue