ScpControl.Shared/Core/DualShockButtons.cs (579 lines of code) (raw):

using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.Serialization; namespace ScpControl.Shared.Core { #region Interfaces /// <summary> /// Describes the possible states for a DualShock button. /// </summary> public interface IDsButtonState { bool IsPressed { get; set; } float Pressure { get; } byte Value { get; } X360Button Xbox360Button { get; set; } } /// <summary> /// Describes a DualShock button. /// </summary> public interface IDsButton { uint Offset { get; } string Name { get; } string DisplayName { get; } int MaskOffset { get; } int ArrayIndex { get; } void ToggleBit(ref byte source, bool value); X360Button Xbox360Button { get; } } #endregion /// <summary> /// Implements the possible states for a DualShock button. /// </summary> public class DsButtonState : IDsButtonState { #region Properties /// <summary> /// True if the button in question is currently pressed, false if it's released. /// </summary> public bool IsPressed { get; set; } /// <summary> /// Gets the pressure value of the current button compatible with PCSX2s XInput/LilyPad mod. /// </summary> /// <remarks>This is just a boolean to float conversion.</remarks> public float Pressure { get { return IsPressed ? 1.0f : 0.0f; } } /// <summary> /// Gets the button press state as byte value. /// </summary> /// <remarks>255 equals pressed, 0 equals released.</remarks> public byte Value { get { return (byte) (IsPressed ? 0xFF : 0x00); } } public X360Button Xbox360Button { get; set; } #endregion } /// <summary> /// Implements a DualShock button. /// </summary> [DataContract] public class DsButton : IDsButton { #region Ctors public DsButton() { } public DsButton(string name) : this() { Name = name; } #endregion #region Properties [DataMember] public uint Offset { get; protected set; } /// <summary> /// The short name identifying the button. /// </summary> [DataMember] public string Name { get; private set; } /// <summary> /// A short descriptive name of the button. /// </summary> [DataMember] public string DisplayName { get; protected set; } /// <summary> /// The bit offset within the <see cref="ArrayIndex" /> /// </summary> [DataMember] public int MaskOffset { get; protected set; } /// <summary> /// The corresponding byte in the <see cref="ScpHidReport.RawBytes" /> holding the value of the button. /// </summary> [DataMember] public int ArrayIndex { get; protected set; } /// <summary> /// The equivalent button on an Xbox 360 controller. /// </summary> [DataMember] public X360Button Xbox360Button { get; protected set; } #endregion #region Methods /// <summary> /// Sets or unsets a given bit in a specified byte. /// </summary> /// <param name="source">The byte to manipulate.</param> /// <param name="value">True if the bit should be set high, false otherwise.</param> /// <remarks>If the bit is already high it will be overwritten and vice versa.</remarks> public void ToggleBit(ref byte source, bool value) { if (value) { source |= (byte) (1 << MaskOffset); } else { source &= (byte) ~(1 << MaskOffset); } } public override bool Equals(object obj) { var button = obj as DsButton; return button != null && button.Name.Equals(Name); } public override int GetHashCode() { return Name.GetHashCode(); } public override string ToString() { return DisplayName; } #endregion } /// <summary> /// Definition of a DualShock 3 button. /// </summary> public class Ds3Button : DsButton { #region Properties private static readonly Lazy<IEnumerable<Ds3Button>> Ds3Buttons = new Lazy<IEnumerable<Ds3Button>>(() => typeof (Ds3Button).GetProperties( BindingFlags.Public | BindingFlags.Static) .Select(b => b.GetValue(null, null)) .Where(o => o.GetType() == typeof (Ds3Button)).Cast<Ds3Button>()); public static IEnumerable<Ds3Button> Buttons { get { return Ds3Buttons.Value; } } #endregion #region Ctors public Ds3Button() { } public Ds3Button(string name) : base(name) { } #endregion #region Buttons private static readonly Lazy<IDsButton> DsBtnNone = new Lazy<IDsButton>(() => new Ds3Button("None") { Offset = 0, DisplayName = "None" }); public static IDsButton None { get { return DsBtnNone.Value; } } private static readonly Lazy<IDsButton> DsBtnSelect = new Lazy<IDsButton>(() => new Ds3Button("Select") { Offset = 1 << 0, DisplayName = "Select", ArrayIndex = 10, MaskOffset = 0, Xbox360Button = X360Button.Back }); public static IDsButton Select { get { return DsBtnSelect.Value; } } private static readonly Lazy<IDsButton> DsBtnL3 = new Lazy<IDsButton>(() => new Ds3Button("L3") { Offset = 1 << 1, DisplayName = "Left thumb", ArrayIndex = 10, MaskOffset = 1, Xbox360Button = X360Button.LS }); public static IDsButton L3 { get { return DsBtnL3.Value; } } private static readonly Lazy<IDsButton> DsBtnR3 = new Lazy<IDsButton>(() => new Ds3Button("R3") { Offset = 1 << 2, DisplayName = "Right thumb", ArrayIndex = 10, MaskOffset = 2, Xbox360Button = X360Button.RS }); public static IDsButton R3 { get { return DsBtnR3.Value; } } private static readonly Lazy<IDsButton> DsBtnStart = new Lazy<IDsButton>(() => new Ds3Button("Start") { Offset = 1 << 3, DisplayName = "Start", ArrayIndex = 10, MaskOffset = 3, Xbox360Button = X360Button.Start }); public static IDsButton Start { get { return DsBtnStart.Value; } } private static readonly Lazy<IDsButton> DsBtnUp = new Lazy<IDsButton>(() => new Ds3Button("Up") { Offset = 1 << 4, DisplayName = "D-Pad up", ArrayIndex = 10, MaskOffset = 4, Xbox360Button = X360Button.Up }); public static IDsButton Up { get { return DsBtnUp.Value; } } private static readonly Lazy<IDsButton> DsBtnRight = new Lazy<IDsButton>(() => new Ds3Button("Right") { Offset = 1 << 5, DisplayName = "D-Pad right", ArrayIndex = 10, MaskOffset = 5, Xbox360Button = X360Button.Right }); public static IDsButton Right { get { return DsBtnRight.Value; } } private static readonly Lazy<IDsButton> DsBtnDown = new Lazy<IDsButton>(() => new Ds3Button("Down") { Offset = 1 << 6, DisplayName = "D-Pad down", ArrayIndex = 10, MaskOffset = 6, Xbox360Button = X360Button.Down }); public static IDsButton Down { get { return DsBtnDown.Value; } } private static readonly Lazy<IDsButton> DsBtnLeft = new Lazy<IDsButton>(() => new Ds3Button("Left") { Offset = 1 << 7, DisplayName = "D-Pad left", ArrayIndex = 10, MaskOffset = 7, Xbox360Button = X360Button.Left }); public static IDsButton Left { get { return DsBtnLeft.Value; } } private static readonly Lazy<IDsButton> DsBtnL2 = new Lazy<IDsButton>(() => new Ds3Button("L2") { Offset = 1 << 8, DisplayName = "Left trigger", ArrayIndex = 11, MaskOffset = 0 }); public static IDsButton L2 { get { return DsBtnL2.Value; } } private static readonly Lazy<IDsButton> DsBtnR2 = new Lazy<IDsButton>(() => new Ds3Button("R2") { Offset = 1 << 9, DisplayName = "Right trigger", ArrayIndex = 11, MaskOffset = 1 }); public static IDsButton R2 { get { return DsBtnR2.Value; } } private static readonly Lazy<IDsButton> DsBtnL1 = new Lazy<IDsButton>(() => new Ds3Button("L1") { Offset = 1 << 10, DisplayName = "Left shoulder", ArrayIndex = 11, MaskOffset = 2, Xbox360Button = X360Button.LB }); public static IDsButton L1 { get { return DsBtnL1.Value; } } private static readonly Lazy<IDsButton> DsBtnR1 = new Lazy<IDsButton>(() => new Ds3Button("R1") { Offset = 1 << 11, DisplayName = "Right shoulder", ArrayIndex = 11, MaskOffset = 3, Xbox360Button = X360Button.RB }); public static IDsButton R1 { get { return DsBtnR1.Value; } } private static readonly Lazy<IDsButton> DsBtnTriangle = new Lazy<IDsButton>(() => new Ds3Button("Triangle") { Offset = 1 << 12, DisplayName = "Triangle", ArrayIndex = 11, MaskOffset = 4, Xbox360Button = X360Button.Y }); public static IDsButton Triangle { get { return DsBtnTriangle.Value; } } private static readonly Lazy<IDsButton> DsBtnCircle = new Lazy<IDsButton>(() => new Ds3Button("Circle") { Offset = 1 << 13, DisplayName = "Circle", ArrayIndex = 11, MaskOffset = 5, Xbox360Button = X360Button.B }); public static IDsButton Circle { get { return DsBtnCircle.Value; } } private static readonly Lazy<IDsButton> DsBtnCross = new Lazy<IDsButton>(() => new Ds3Button("Cross") { Offset = 1 << 14, DisplayName = "Cross", ArrayIndex = 11, MaskOffset = 6, Xbox360Button = X360Button.A }); public static IDsButton Cross { get { return DsBtnCross.Value; } } private static readonly Lazy<IDsButton> DsBtnSquare = new Lazy<IDsButton>(() => new Ds3Button("Square") { Offset = 1 << 15, DisplayName = "Square", ArrayIndex = 11, MaskOffset = 7, Xbox360Button = X360Button.X }); public static IDsButton Square { get { return DsBtnSquare.Value; } } private static readonly Lazy<IDsButton> DsBtnPs = new Lazy<IDsButton>(() => new Ds3Button("PS") { Offset = 1 << 16, DisplayName = "PS", ArrayIndex = 12, MaskOffset = 0, Xbox360Button = X360Button.Guide }); public static IDsButton Ps { get { return DsBtnPs.Value; } } #endregion } /// <summary> /// Definition of a DualShock 4 button. /// </summary> public class Ds4Button : DsButton { #region Properties private static readonly Lazy<IEnumerable<Ds4Button>> Ds4Buttons = new Lazy<IEnumerable<Ds4Button>>(() => typeof (Ds4Button).GetProperties( BindingFlags.Public | BindingFlags.Static) .Select(b => b.GetValue(null, null)) .Where(o => o.GetType() == typeof (Ds4Button)).Cast<Ds4Button>()); public static IEnumerable<Ds4Button> Buttons { get { return Ds4Buttons.Value; } } #endregion #region Ctors public Ds4Button() { } public Ds4Button(string name) : base(name) { } #endregion #region Buttons private static readonly Lazy<IDsButton> DsBtnNone = new Lazy<IDsButton>(() => new Ds4Button("None") { Offset = 0, DisplayName = "None" }); public static IDsButton None { get { return DsBtnNone.Value; } } private static readonly Lazy<IDsButton> DsBtnUp = new Lazy<IDsButton>(() => new Ds4Button("Up") { Offset = 1 << 0, DisplayName = "D-Pad up", ArrayIndex = 13, MaskOffset = 0, Xbox360Button = X360Button.Up }); public static IDsButton Up { get { return DsBtnUp.Value; } } private static readonly Lazy<IDsButton> DsBtnRight = new Lazy<IDsButton>(() => new Ds4Button("Right") { Offset = 1 << 1, DisplayName = "D-Pad right", ArrayIndex = 13, MaskOffset = 1, Xbox360Button = X360Button.Right }); public static IDsButton Right { get { return DsBtnRight.Value; } } private static readonly Lazy<IDsButton> DsBtnDown = new Lazy<IDsButton>(() => new Ds4Button("Down") { Offset = 1 << 2, DisplayName = "D-Pad down", ArrayIndex = 13, MaskOffset = 2, Xbox360Button = X360Button.Down }); public static IDsButton Down { get { return DsBtnDown.Value; } } private static readonly Lazy<IDsButton> DsBtnLeft = new Lazy<IDsButton>(() => new Ds4Button("Left") { Offset = 1 << 3, DisplayName = "D-Pad left", ArrayIndex = 13, MaskOffset = 3, Xbox360Button = X360Button.Left }); public static IDsButton Left { get { return DsBtnLeft.Value; } } private static readonly Lazy<IDsButton> DsBtnSquare = new Lazy<IDsButton>(() => new Ds4Button("Square") { Offset = 1 << 4, DisplayName = "Square", ArrayIndex = 13, MaskOffset = 4, Xbox360Button = X360Button.X }); public static IDsButton Square { get { return DsBtnSquare.Value; } } private static readonly Lazy<IDsButton> DsBtnCross = new Lazy<IDsButton>(() => new Ds4Button("Cross") { Offset = 1 << 5, DisplayName = "Cross", ArrayIndex = 13, MaskOffset = 5, Xbox360Button = X360Button.A }); public static IDsButton Cross { get { return DsBtnCross.Value; } } private static readonly Lazy<IDsButton> DsBtnCircle = new Lazy<IDsButton>(() => new Ds4Button("Circle") { Offset = 1 << 6, DisplayName = "Circle", ArrayIndex = 13, MaskOffset = 6, Xbox360Button = X360Button.B }); public static IDsButton Circle { get { return DsBtnCircle.Value; } } private static readonly Lazy<IDsButton> DsBtnTriangle = new Lazy<IDsButton>(() => new Ds4Button("Triangle") { Offset = 1 << 7, DisplayName = "Triangle", ArrayIndex = 13, MaskOffset = 7, Xbox360Button = X360Button.Y }); public static IDsButton Triangle { get { return DsBtnTriangle.Value; } } private static readonly Lazy<IDsButton> DsBtnL1 = new Lazy<IDsButton>(() => new Ds4Button("L1") { Offset = 1 << 8, DisplayName = "Left shoulder", ArrayIndex = 14, MaskOffset = 0, Xbox360Button = X360Button.LB }); public static IDsButton L1 { get { return DsBtnL1.Value; } } private static readonly Lazy<IDsButton> DsBtnR1 = new Lazy<IDsButton>(() => new Ds4Button("R1") { Offset = 1 << 9, DisplayName = "Right shoulder", ArrayIndex = 14, MaskOffset = 1, Xbox360Button = X360Button.RB }); public static IDsButton R1 { get { return DsBtnR1.Value; } } private static readonly Lazy<IDsButton> DsBtnL2 = new Lazy<IDsButton>(() => new Ds4Button("L2") { Offset = 1 << 10, DisplayName = "Left trigger", ArrayIndex = 14, MaskOffset = 2 }); public static IDsButton L2 { get { return DsBtnL2.Value; } } private static readonly Lazy<IDsButton> DsBtnR2 = new Lazy<IDsButton>(() => new Ds4Button("R2") { Offset = 1 << 11, DisplayName = "Right trigger", ArrayIndex = 14, MaskOffset = 3 }); public static IDsButton R2 { get { return DsBtnR2.Value; } } private static readonly Lazy<IDsButton> DsBtnShare = new Lazy<IDsButton>(() => new Ds4Button("Select") { Offset = 1 << 12, DisplayName = "Share", ArrayIndex = 14, MaskOffset = 4, Xbox360Button = X360Button.Back }); public static IDsButton Share { get { return DsBtnShare.Value; } } private static readonly Lazy<IDsButton> DsBtnOptions = new Lazy<IDsButton>(() => new Ds4Button("Start") { Offset = 1 << 13, DisplayName = "Options", ArrayIndex = 14, MaskOffset = 5, Xbox360Button = X360Button.Start }); public static IDsButton Options { get { return DsBtnOptions.Value; } } private static readonly Lazy<IDsButton> DsBtnL3 = new Lazy<IDsButton>(() => new Ds4Button("L3") { Offset = 1 << 14, DisplayName = "Left thumb", ArrayIndex = 14, MaskOffset = 6, Xbox360Button = X360Button.LS }); public static IDsButton L3 { get { return DsBtnL3.Value; } } private static readonly Lazy<IDsButton> DsBtnR3 = new Lazy<IDsButton>(() => new Ds4Button("R3") { Offset = 1 << 15, DisplayName = "Right thumb", ArrayIndex = 14, MaskOffset = 7, Xbox360Button = X360Button.RS }); public static IDsButton R3 { get { return DsBtnR3.Value; } } private static readonly Lazy<IDsButton> DsBtnPs = new Lazy<IDsButton>(() => new Ds4Button("PS") { Offset = 1 << 16, DisplayName = "PS", ArrayIndex = 15, MaskOffset = 0, Xbox360Button = X360Button.Guide }); public static IDsButton Ps { get { return DsBtnPs.Value; } } private static readonly Lazy<IDsButton> DsBtnTouchPad = new Lazy<IDsButton>(() => new Ds4Button("TouchPad") { Offset = 1 << 17, DisplayName = "Touchpad", ArrayIndex = 15, MaskOffset = 1 }); public static IDsButton TouchPad { get { return DsBtnTouchPad.Value; } } #endregion } }