Skip to content

Instantly share code, notes, and snippets.

@mfakane
Last active April 4, 2016 10:07
Show Gist options
  • Select an option

  • Save mfakane/c06ac68b31fa80f2df4f9aa92c0994b7 to your computer and use it in GitHub Desktop.

Select an option

Save mfakane/c06ac68b31fa80f2df4f9aa92c0994b7 to your computer and use it in GitHub Desktop.
C# で XInput おためし、おきらく (取得はともかく振動はテストしてないです)
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