diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj index 81fec8c7..c7de48e4 100644 --- a/Source/OpenTK/OpenTK.csproj +++ b/Source/OpenTK/OpenTK.csproj @@ -158,6 +158,7 @@ + Code diff --git a/Source/OpenTK/Platform/Windows/XInputJoystick.cs b/Source/OpenTK/Platform/Windows/XInputJoystick.cs new file mode 100644 index 00000000..f3e0c04e --- /dev/null +++ b/Source/OpenTK/Platform/Windows/XInputJoystick.cs @@ -0,0 +1,299 @@ +// #region License +// +// XInputJoystick.cs +// +// Author: +// Stefanos A. +// +// Copyright (c) 2006-2013 Stefanos Apostolopoulos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// #endregion + +using System; +using System.Collections.Generic; +using System.Text; +using OpenTK.Input; +using System.Runtime.InteropServices; +using System.Security; + +namespace OpenTK.Platform.Windows +{ + class XInputJoystick : IGamePadDriver + { + #region IGamePadDriver Members + + public GamePadState GetState(int index) + { + XInputState xstate; + XInput910.GetState((XInputUserIndex)index, out xstate); + + GamePadState state = new GamePadState(); + state.SetButton(Buttons.A, (xstate.GamePad.Buttons & XInputButtons.A) != 0); + state.SetButton(Buttons.B, (xstate.GamePad.Buttons & XInputButtons.B) != 0); + state.SetButton(Buttons.X, (xstate.GamePad.Buttons & XInputButtons.X) != 0); + state.SetButton(Buttons.Y, (xstate.GamePad.Buttons & XInputButtons.Y) != 0); + state.SetButton(Buttons.Start, (xstate.GamePad.Buttons & XInputButtons.Start) != 0); + state.SetButton(Buttons.Back, (xstate.GamePad.Buttons & XInputButtons.Back) != 0); + //state.SetButton(Buttons.BigButton, (xstate.GamePad.Buttons & XInputButtons.???) != 0); + state.SetButton(Buttons.LeftShoulder, (xstate.GamePad.Buttons & XInputButtons.LeftShoulder) != 0); + state.SetButton(Buttons.RightShoulder, (xstate.GamePad.Buttons & XInputButtons.RightShoulder) != 0); + state.SetButton(Buttons.LeftStick, (xstate.GamePad.Buttons & XInputButtons.LeftThumb) != 0); + state.SetButton(Buttons.RightStick, (xstate.GamePad.Buttons & XInputButtons.RightThumb) != 0); + state.SetButton(Buttons.DPadDown, (xstate.GamePad.Buttons & XInputButtons.DPadDown) != 0); + state.SetButton(Buttons.DPadUp, (xstate.GamePad.Buttons & XInputButtons.DPadUp) != 0); + state.SetButton(Buttons.DPadLeft, (xstate.GamePad.Buttons & XInputButtons.DPadLeft) != 0); + state.SetButton(Buttons.DPadRight, (xstate.GamePad.Buttons & XInputButtons.DPadRight) != 0); + + return state; + } + + public GamePadCapabilities GetCapabilities(int index) + { + throw new NotImplementedException(); + } + + public string GetName(int index) + { + throw new NotImplementedException(); + } + + #endregion + + #region Private Members + + enum XInputErrorCode + { + Success = 0, + DeviceNotConnected + } + + enum XInputType + { + GamePad + } + + enum XInputSubType + { + Unknown = 0, + GamePad = 1, + Wheel = 2, + ArcadeStick = 3, + FlightStick = 4, + DancePad = 5, + Guitar = 6, + GuitarAlternate = 7, + DrumKit = 8, + GuitarBass = 0xb, + ArcadePad = 0x13 + } + + enum XInputCapabilities + { + Ffb = 0x0001, + Wireless = 0x0002, + Voice = 0x0004, + Pmd = 0x0008, + NoNavigation = 0x0010, + } + + enum XInputButtons : ushort + { + 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 + } + + [Flags] + enum XInputCapabilitiesFlags + { + Default = 0, + GamePadOnly = 1 + } + + enum XInputBatteryType : byte + { + Disconnected = 0x00, + Wired = 0x01, + Alkaline = 0x02, + NiMH = 0x03, + Unknown = 0xff + } + + enum XInputBatteryLevel : byte + { + Empty = 0x00, + Low = 0x01, + Medium = 0x02, + Full = 0x03 + } + + enum XInputUserIndex + { + First = 0, + Second, + Third, + Fourth, + Any = 0xff + } + + struct XInputThresholds + { + public const int LeftThumbDeadzone = 7849; + public const int RightThumbDeadzone = 8689; + public const int TriggerThreshold = 30; + } + + struct XInputGamePad + { + public XInputButtons Buttons; + public byte LeftTrigger; + public byte RightTrigger; + public short ThumbLX; + public short ThumbLY; + public short ThumbRX; + public short ThumbRY; + } + + struct XInputState + { + public int PacketNumber; + public XInputGamePad GamePad; + } + + struct XInputVibration + { + public short LeftMotorSpeed; + public short RightMotorSpeed; + } + + struct XInputDeviceCapabilities + { + public byte Type; + public byte SubType; + public short Flags; + public XInputGamePad GamePad; + public XInputVibration Vibration; + } + + struct XInputBatteryInformation + { + public XInputBatteryType Type; + public XInputBatteryLevel Level; + } + + static class XInput910 + { + const string dll = "XINPUT9_1_0"; + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetCapabilities", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetCapabilities( + XInputUserIndex dwUserIndex, + XInputCapabilitiesFlags dwFlags, + ref XInputDeviceCapabilities pCapabilities); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetState + ( + XInputUserIndex dwUserIndex, + out XInputState pState + ); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputSetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode SetState + ( + XInputUserIndex dwUserIndex, + ref XInputVibration pVibration + ); + } + + static class XInput13 + { + const string dll = "XINPUT1_3"; + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetCapabilities", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetCapabilities( + XInputUserIndex dwUserIndex, + XInputCapabilitiesFlags dwFlags, + ref XInputDeviceCapabilities pCapabilities); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetState + ( + XInputUserIndex dwUserIndex, + out XInputState pState + ); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputSetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode SetState + ( + XInputUserIndex dwUserIndex, + ref XInputVibration pVibration + ); + } + + static class XInput14 + { + const string dll = "XINPUT1_4"; + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetCapabilities", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetCapabilities( + XInputUserIndex dwUserIndex, + XInputCapabilitiesFlags dwFlags, + ref XInputDeviceCapabilities pCapabilities); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputGetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode GetState + ( + XInputUserIndex dwUserIndex, + out XInputState pState + ); + + [SuppressUnmanagedCodeSecurity] + [DllImport(dll, EntryPoint = "XInputSetState", ExactSpelling = true, SetLastError = false)] + public static extern XInputErrorCode SetState + ( + XInputUserIndex dwUserIndex, + ref XInputVibration pVibration + ); + } + + #endregion + } +}