Last active
April 4, 2016 10:07
-
-
Save mfakane/c06ac68b31fa80f2df4f9aa92c0994b7 to your computer and use it in GitHub Desktop.
C# で XInput おためし、おきらく (取得はともかく振動はテストしてないです)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.ComponentModel; | |
| using System.Runtime.InteropServices; | |
| using System.Security; | |
| namespace Linearstar.Lavis.Interop | |
| { | |
| public class XInput | |
| { | |
| const string XInputLibrary = "XINPUT9_1_0"; | |
| #region P/Invoke | |
| [SuppressUnmanagedCodeSecurity, DllImport(XInputLibrary)] | |
| static extern int XInputGetCapabilities(int dwUserIndex, int dwFlags, out XInputCapabilities pCapabilities); | |
| [SuppressUnmanagedCodeSecurity, DllImport(XInputLibrary)] | |
| static extern int XInputGetState(int dwUserIndex, out XInputState pState); | |
| [SuppressUnmanagedCodeSecurity, DllImport(XInputLibrary)] | |
| static extern int XInputSetState(int dwUserIndex, ref XInputVibration pVibration); | |
| const int ERROR_SUCCESS = 0; | |
| const int ERROR_DEVICE_NOT_CONNECTED = 1167; | |
| struct XInputCapabilities | |
| { | |
| public byte Type; | |
| public XInputDeviceSubType SubType; | |
| public XInputDeviceCapabilityFlags Flags; | |
| public XInputGamepad Gamepad; | |
| public XInputVibration Vibration; | |
| } | |
| struct XInputGamepad | |
| { | |
| public XInputButtons Buttons; | |
| public byte LeftTrigger; | |
| public byte RightTrigger; | |
| public short ThumbLX; | |
| public short ThumbLY; | |
| public short ThumbRX; | |
| public short ThumbRY; | |
| } | |
| struct XInputVibration | |
| { | |
| public ushort LeftMotorSpeed; | |
| public ushort RightMotorSpeed; | |
| } | |
| struct XInputState | |
| { | |
| public int dwPacketNumber; | |
| public XInputGamepad Gamepad; | |
| } | |
| #endregion | |
| static void EnsureErrorState(int errorState) | |
| { | |
| if (errorState == ERROR_SUCCESS) | |
| return; | |
| else if (errorState == ERROR_DEVICE_NOT_CONNECTED) | |
| throw new InvalidOperationException(); | |
| else | |
| throw new Win32Exception(errorState); | |
| } | |
| readonly XInputCapabilities capabilities; | |
| XInputState state; | |
| XInputState previousState; | |
| public int PlayerIndex | |
| { | |
| get; | |
| } | |
| public XInputDeviceSubType Kind => capabilities.SubType; | |
| public XInputDeviceCapabilityFlags Capabilities => capabilities.Flags; | |
| public XInputButtons Buttons => state.Gamepad.Buttons; | |
| public double LeftStickX => | |
| state.Gamepad.ThumbLX > 0 ? state.Gamepad.ThumbLX / (double)short.MaxValue : -state.Gamepad.ThumbLX / (double)short.MinValue; | |
| public double LeftStickY => | |
| state.Gamepad.ThumbLY > 0 ? -state.Gamepad.ThumbLY / (double)short.MaxValue : state.Gamepad.ThumbLY / (double)short.MinValue; | |
| public double RightStickX => | |
| state.Gamepad.ThumbRX > 0 ? state.Gamepad.ThumbRX / (double)short.MaxValue : -state.Gamepad.ThumbRX / (double)short.MinValue; | |
| public double RightStickY => | |
| state.Gamepad.ThumbRY > 0 ? -state.Gamepad.ThumbRY / (double)short.MaxValue : state.Gamepad.ThumbRY / (double)short.MinValue; | |
| public double LeftTrigger => state.Gamepad.LeftTrigger / 255.0; | |
| public double RightTrigger => state.Gamepad.RightTrigger / 255.0; | |
| public XInput(int playerIndex) | |
| { | |
| if (playerIndex < 0 || playerIndex >= 4) | |
| throw new ArgumentException($"{nameof(playerIndex)} must be 0, 1, 2, or 3.", nameof(playerIndex)); | |
| this.PlayerIndex = playerIndex; | |
| EnsureErrorState(XInputGetCapabilities(this.PlayerIndex, 0, out capabilities)); | |
| } | |
| public void Update() | |
| { | |
| previousState = state; | |
| EnsureErrorState(XInputGetState(this.PlayerIndex, out state)); | |
| } | |
| public bool IsDown(XInputButtons button) => (state.Gamepad.Buttons & button) != 0; | |
| public bool IsPress(XInputButtons button) => (state.Gamepad.Buttons & button) != 0 && (previousState.Gamepad.Buttons & button) == 0; | |
| public bool IsRelease(XInputButtons button) => (state.Gamepad.Buttons & button) == 0 && (previousState.Gamepad.Buttons & button) != 0; | |
| public void SetVibration(double leftMotorSpeed, double rightMotorSpeed) | |
| { | |
| var vib = new XInputVibration | |
| { | |
| LeftMotorSpeed = (ushort)(ushort.MaxValue * leftMotorSpeed), | |
| RightMotorSpeed = (ushort)(ushort.MaxValue * rightMotorSpeed), | |
| }; | |
| XInputSetState(this.PlayerIndex, ref vib); | |
| } | |
| } | |
| public enum XInputDeviceSubType : byte | |
| { | |
| Unknown, | |
| Gamepad, | |
| Wheel, | |
| ArcadeStick, | |
| FlightStick, | |
| DancePad, | |
| Guitar, | |
| GuitarAlternate, | |
| DrumKit, | |
| GuitarBass = 11, | |
| ArcadePad = 19, | |
| } | |
| public enum XInputDeviceCapabilityFlags : ushort | |
| { | |
| None, | |
| ForceFeedbackSupported = 1, | |
| Wireless = 1 << 1, | |
| VoiceSupported = 1 << 2, | |
| PluginModulesSupported = 1 << 3, | |
| NoNavigation = 1 << 4, | |
| } | |
| public enum XInputButtons : ushort | |
| { | |
| None, | |
| DPadUp = 0x0001, | |
| DPadDown = 0x0002, | |
| DPadLeft = 0x0004, | |
| DPadRight = 0x0008, | |
| Start = 0x0010, | |
| Back = 0x0020, | |
| LeftThumb = 0x0040, | |
| RightThumb = 0x0080, | |
| LeftShoulder = 0x0100, | |
| RightShoulder = 0x0200, | |
| A = 0x1000, | |
| B = 0x2000, | |
| X = 0x4000, | |
| Y = 0x8000, | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment