diff --git a/FNA.csproj b/FNA.csproj index 6e2ec69..1da48ae 100644 --- a/FNA.csproj +++ b/FNA.csproj @@ -296,6 +296,7 @@ + @@ -334,10 +335,9 @@ - - + diff --git a/Makefile b/Makefile index 9e1583e..f8ac10d 100644 --- a/Makefile +++ b/Makefile @@ -262,6 +262,7 @@ SRC = \ src/IGraphicsDeviceManager.cs \ src/Input/Buttons.cs \ src/Input/ButtonState.cs \ + src/Input/GamePad.cs \ src/Input/GamePadButtons.cs \ src/Input/GamePadCapabilities.cs \ src/Input/GamePadDeadZone.cs \ @@ -300,10 +301,9 @@ SRC = \ src/Quaternion.cs \ src/Ray.cs \ src/Rectangle.cs \ - src/SDL2/Input/SDL2_GamePad.cs \ - src/SDL2/Input/SDL2_KeyboardUtil.cs \ src/SDL2/SDL2_FNAPlatform.cs \ src/SDL2/SDL2_GameWindow.cs \ + src/SDL2/SDL2_KeyboardUtil.cs \ src/Storage/StorageContainer.cs \ src/Storage/StorageDevice.cs \ src/Storage/StorageDeviceNotConnectedException.cs \ diff --git a/src/FNAPlatform.cs b/src/FNAPlatform.cs index c83fed1..9e2dbe7 100644 --- a/src/FNAPlatform.cs +++ b/src/FNAPlatform.cs @@ -48,6 +48,11 @@ namespace Microsoft.Xna.Framework GetMouseState = SDL2_FNAPlatform.GetMouseState; SetMousePosition = SDL2_FNAPlatform.SetMousePosition; OnIsMouseVisibleChanged = SDL2_FNAPlatform.OnIsMouseVisibleChanged; + GetGamePadCapabilities = SDL2_FNAPlatform.GetGamePadCapabilities; + GetGamePadState = SDL2_FNAPlatform.GetGamePadState; + SetGamePadVibration = SDL2_FNAPlatform.SetGamePadVibration; + GetGamePadGUID = SDL2_FNAPlatform.GetGamePadGUID; + SetGamePadLightBar = SDL2_FNAPlatform.SetGamePadLightBar; GetStorageRoot = SDL2_FNAPlatform.GetStorageRoot; IsStoragePathConnected = SDL2_FNAPlatform.IsStoragePathConnected; Log = SDL2_FNAPlatform.Log; @@ -110,6 +115,28 @@ namespace Microsoft.Xna.Framework public delegate void OnIsMouseVisibleChangedFunc(bool visible); public static OnIsMouseVisibleChangedFunc OnIsMouseVisibleChanged; + public delegate GamePadCapabilities GetGamePadCapabilitiesFunc(int index); + public static GetGamePadCapabilitiesFunc GetGamePadCapabilities; + + public delegate GamePadState GetGamePadStateFunc( + int index, + GamePadDeadZone deadZoneMode + ); + public static GetGamePadStateFunc GetGamePadState; + + public delegate bool SetGamePadVibrationFunc( + int index, + float leftMotor, + float rightMotor + ); + public static SetGamePadVibrationFunc SetGamePadVibration; + + public delegate string GetGamePadGUIDFunc(int index); + public static GetGamePadGUIDFunc GetGamePadGUID; + + public delegate void SetGamePadLightBarFunc(int index, Color color); + public static SetGamePadLightBarFunc SetGamePadLightBar; + public delegate string GetStorageRootFunc(); public static GetStorageRootFunc GetStorageRoot; diff --git a/src/Input/GamePad.cs b/src/Input/GamePad.cs new file mode 100644 index 0000000..46dba49 --- /dev/null +++ b/src/Input/GamePad.cs @@ -0,0 +1,96 @@ +#region License +/* FNA - XNA4 Reimplementation for Desktop Platforms + * Copyright 2009-2016 Ethan Lee and the MonoGame Team + * + * Released under the Microsoft Public License. + * See LICENSE for details. + */ +#endregion + +#region Using Statements +using System; +#endregion + +namespace Microsoft.Xna.Framework.Input +{ + public static class GamePad + { + #region Internal Static Variables + + /* Determines how many controllers we should be tracking. + * Per XNA4 we track 4 by default, but if you want to track more you can + * do this by changing PlayerIndex.cs to include more index names. + * -flibit + */ + internal static readonly int GAMEPAD_COUNT = DetermineNumGamepads(); + + private static int DetermineNumGamepads() + { + string numGamepadString = Environment.GetEnvironmentVariable( + "FNA_GAMEPAD_NUM_GAMEPADS" + ); + if (!String.IsNullOrEmpty(numGamepadString)) + { + int numGamepads; + if (int.TryParse(numGamepadString, out numGamepads)) + { + if (numGamepads >= 0) + { + return numGamepads; + } + } + } + return Enum.GetNames(typeof(PlayerIndex)).Length; + } + + #endregion + + #region Public GamePad API + + public static GamePadCapabilities GetCapabilities(PlayerIndex playerIndex) + { + return FNAPlatform.GetGamePadCapabilities((int) playerIndex); + } + + public static GamePadState GetState(PlayerIndex playerIndex) + { + return FNAPlatform.GetGamePadState( + (int) playerIndex, + GamePadDeadZone.IndependentAxes + ); + } + + public static GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode) + { + return FNAPlatform.GetGamePadState( + (int) playerIndex, + deadZoneMode + ); + } + + public static bool SetVibration(PlayerIndex playerIndex, float leftMotor, float rightMotor) + { + return FNAPlatform.SetGamePadVibration( + (int) playerIndex, + leftMotor, + rightMotor + ); + } + + #endregion + + #region Public GamePad API, FNA Extensions + + public static string GetGUIDEXT(PlayerIndex playerIndex) + { + return FNAPlatform.GetGamePadGUID((int) playerIndex); + } + + public static void SetLightBarEXT(PlayerIndex playerIndex, Color color) + { + FNAPlatform.SetGamePadLightBar((int) playerIndex, color); + } + + #endregion + } +} diff --git a/src/SDL2/Input/SDL2_GamePad.cs b/src/SDL2/Input/SDL2_GamePad.cs deleted file mode 100644 index 32e5ffb..0000000 --- a/src/SDL2/Input/SDL2_GamePad.cs +++ /dev/null @@ -1,677 +0,0 @@ -#region License -/* FNA - XNA4 Reimplementation for Desktop Platforms - * Copyright 2009-2016 Ethan Lee and the MonoGame Team - * - * Released under the Microsoft Public License. - * See LICENSE for details. - */ -#endregion - -#region Using Statements -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; - -using SDL2; -#endregion - -namespace Microsoft.Xna.Framework.Input -{ - public static class GamePad - { - #region Internal Haptic Type Enum - - private enum HapticType - { - Simple = 0, - LeftRight = 1, - LeftRightMacHack = 2 - } - - #endregion - - #region Internal SDL2_GamePad Variables - - /* Determines how many controllers we should be tracking. - * Per XNA4 we track 4 by default, but if you want to track more you can - * do this by changing PlayerIndex.cs to include more index names. - * -flibit - */ - private static readonly int GAMEPAD_COUNT = DetermineNumGamepads(); - - // Controller device information - private static IntPtr[] INTERNAL_devices = new IntPtr[GAMEPAD_COUNT]; - private static Dictionary INTERNAL_instanceList = new Dictionary(); - private static string[] INTERNAL_guids = GenStringArray(); - - // Haptic device information - private static IntPtr[] INTERNAL_haptics = new IntPtr[GAMEPAD_COUNT]; - private static HapticType[] INTERNAL_hapticTypes = new HapticType[GAMEPAD_COUNT]; - - // Light bar information - private static string[] INTERNAL_lightBars = GenStringArray(); - - // Cached GamePadStates - private static GamePadState[] INTERNAL_states = new GamePadState[GAMEPAD_COUNT]; - - // We use this to apply XInput-like rumble effects. - private static SDL.SDL_HapticEffect INTERNAL_leftRightEffect = new SDL.SDL_HapticEffect - { - type = SDL.SDL_HAPTIC_LEFTRIGHT, - leftright = new SDL.SDL_HapticLeftRight - { - type = SDL.SDL_HAPTIC_LEFTRIGHT, - length = SDL.SDL_HAPTIC_INFINITY, - large_magnitude = ushort.MaxValue, - small_magnitude = ushort.MaxValue - } - }; - - // We use this to get left/right support on OSX via a nice driver workaround! - private static ushort[] leftRightMacHackData = {0, 0}; - private static GCHandle leftRightMacHackPArry = GCHandle.Alloc(leftRightMacHackData, GCHandleType.Pinned); - private static IntPtr leftRightMacHackPtr = leftRightMacHackPArry.AddrOfPinnedObject(); - private static SDL.SDL_HapticEffect INTERNAL_leftRightMacHackEffect = new SDL.SDL_HapticEffect - { - type = SDL.SDL_HAPTIC_CUSTOM, - custom = new SDL.SDL_HapticCustom - { - type = SDL.SDL_HAPTIC_CUSTOM, - length = SDL.SDL_HAPTIC_INFINITY, - channels = 2, - period = 1, - samples = 2, - data = leftRightMacHackPtr - } - }; - - // Used as a "blank" state - private static GamePadState InitializedState = new GamePadState(); - - // FIXME: SDL_GameController config input inversion! - private static float invertAxis = Environment.GetEnvironmentVariable( - "FNA_WORKAROUND_INVERT_YAXIS" - ) == "1" ? -1.0f : 1.0f; - - #endregion - - #region String Array Init Method - - private static int DetermineNumGamepads() - { - string numGamepadString = Environment.GetEnvironmentVariable( - "FNA_GAMEPAD_NUM_GAMEPADS" - ); - if (!String.IsNullOrEmpty(numGamepadString)) - { - int numGamepads; - if (int.TryParse(numGamepadString, out numGamepads)) - { - if (numGamepads >= 0) - { - return numGamepads; - } - } - } - return Enum.GetNames(typeof(PlayerIndex)).Length; - } - - private static string[] GenStringArray() - { - string[] result = new string[GAMEPAD_COUNT]; - for (int i = 0; i < result.Length; i += 1) - { - result[i] = String.Empty; - } - return result; - } - - #endregion - - #region Device List, Open/Close Devices - - internal static void INTERNAL_AddInstance(int dev) - { - int which = -1; - for (int i = 0; i < INTERNAL_devices.Length; i += 1) - { - if (INTERNAL_devices[i] == IntPtr.Zero) - { - which = i; - break; - } - } - if (which == -1) - { - return; // Ignoring more than 4 controllers. - } - - // Clear the error buffer. We're about to do a LOT of dangerous stuff. - SDL.SDL_ClearError(); - - // Open the device! - INTERNAL_devices[which] = SDL.SDL_GameControllerOpen(dev); - - // We use this when dealing with Haptic/GUID initialization. - IntPtr thisJoystick = SDL.SDL_GameControllerGetJoystick(INTERNAL_devices[which]); - - // Pair up the instance ID to the player index. - // FIXME: Remove check after 2.0.4? -flibit - int thisInstance = SDL.SDL_JoystickInstanceID(thisJoystick); - if (INTERNAL_instanceList.ContainsKey(thisInstance)) - { - // Duplicate? Usually this is OSX being dumb, but...? - INTERNAL_devices[which] = IntPtr.Zero; - return; - } - INTERNAL_instanceList.Add(thisInstance, which); - - // Start with a fresh state. - INTERNAL_states[which] = InitializedState; - INTERNAL_states[which].IsConnected = true; - - // Initialize the haptics for the joystick, if applicable. - if (SDL.SDL_JoystickIsHaptic(thisJoystick) == 1) - { - INTERNAL_haptics[which] = SDL.SDL_HapticOpenFromJoystick(thisJoystick); - if (INTERNAL_haptics[which] == IntPtr.Zero) - { - System.Console.WriteLine("HAPTIC OPEN ERROR: " + SDL.SDL_GetError()); - } - } - if (INTERNAL_haptics[which] != IntPtr.Zero) - { - if ( SDL2_FNAPlatform.OSVersion.Equals("Mac OS X") && - SDL.SDL_HapticEffectSupported(INTERNAL_haptics[which], ref INTERNAL_leftRightMacHackEffect) == 1 ) - { - INTERNAL_hapticTypes[which] = HapticType.LeftRightMacHack; - SDL.SDL_HapticNewEffect(INTERNAL_haptics[which], ref INTERNAL_leftRightMacHackEffect); - } - else if ( !SDL2_FNAPlatform.OSVersion.Equals("Mac OS X") && - SDL.SDL_HapticEffectSupported(INTERNAL_haptics[which], ref INTERNAL_leftRightEffect) == 1 ) - { - INTERNAL_hapticTypes[which] = HapticType.LeftRight; - SDL.SDL_HapticNewEffect(INTERNAL_haptics[which], ref INTERNAL_leftRightEffect); - } - else if (SDL.SDL_HapticRumbleSupported(INTERNAL_haptics[which]) == 1) - { - INTERNAL_hapticTypes[which] = HapticType.Simple; - SDL.SDL_HapticRumbleInit(INTERNAL_haptics[which]); - } - else - { - // We can't even play simple rumble, this haptic device is useless to us. - SDL.SDL_HapticClose(INTERNAL_haptics[which]); - INTERNAL_haptics[which] = IntPtr.Zero; - } - } - - // Store the GUID string for this device - StringBuilder result = new StringBuilder(); - byte[] resChar = new byte[33]; // FIXME: Sort of arbitrary. - SDL.SDL_JoystickGetGUIDString( - SDL.SDL_JoystickGetGUID(thisJoystick), - resChar, - resChar.Length - ); - if (SDL2_FNAPlatform.OSVersion.Equals("Linux")) - { - result.Append((char) resChar[8]); - result.Append((char) resChar[9]); - result.Append((char) resChar[10]); - result.Append((char) resChar[11]); - result.Append((char) resChar[16]); - result.Append((char) resChar[17]); - result.Append((char) resChar[18]); - result.Append((char) resChar[19]); - } - else if (SDL2_FNAPlatform.OSVersion.Equals("Mac OS X")) - { - result.Append((char) resChar[0]); - result.Append((char) resChar[1]); - result.Append((char) resChar[2]); - result.Append((char) resChar[3]); - result.Append((char) resChar[16]); - result.Append((char) resChar[17]); - result.Append((char) resChar[18]); - result.Append((char) resChar[19]); - } - else if (SDL2_FNAPlatform.OSVersion.Equals("Windows")) - { - bool isXInput = true; - foreach (byte b in resChar) - { - if (((char) b) != '0' && b != 0) - { - isXInput = false; - break; - } - } - if (isXInput) - { - result.Append("xinput"); - } - else - { - result.Append((char) resChar[0]); - result.Append((char) resChar[1]); - result.Append((char) resChar[2]); - result.Append((char) resChar[3]); - result.Append((char) resChar[4]); - result.Append((char) resChar[5]); - result.Append((char) resChar[6]); - result.Append((char) resChar[7]); - } - } - else - { - throw new Exception("SDL2_GamePad: Platform.OSVersion not handled!"); - } - INTERNAL_guids[which] = result.ToString(); - - // Initialize light bar - if ( SDL2_FNAPlatform.OSVersion.Equals("Linux") && - INTERNAL_guids[which].Equals("4c05c405") ) - { - // Get all of the individual PS4 LED instances - List ledList = new List(); - string[] dirs = Directory.GetDirectories("/sys/class/leds/"); - foreach (string dir in dirs) - { - if ( dir.Contains("054C:05C4") && - dir.EndsWith("blue") ) - { - ledList.Add(dir.Substring(0, dir.LastIndexOf(':') + 1)); - } - } - // Find how many of these are already in use - int numLights = 0; - for (int i = 0; i < INTERNAL_lightBars.Length; i += 1) - { - if (!String.IsNullOrEmpty(INTERNAL_lightBars[i])) - { - numLights += 1; - } - } - // If all are not already in use, use the first unused light - if (numLights < ledList.Count) - { - INTERNAL_lightBars[which] = ledList[numLights]; - } - } - - // Print controller information to stdout. - System.Console.WriteLine( - "Controller " + which.ToString() + ": " + - SDL.SDL_GameControllerName(INTERNAL_devices[which]) - ); - } - - internal static void INTERNAL_RemoveInstance(int dev) - { - int output; - if (!INTERNAL_instanceList.TryGetValue(dev, out output)) - { - // Odds are, this is controller 5+ getting removed. - return; - } - INTERNAL_instanceList.Remove(dev); - if (INTERNAL_haptics[output] != IntPtr.Zero) - { - SDL.SDL_HapticClose(INTERNAL_haptics[output]); - INTERNAL_haptics[output] = IntPtr.Zero; - } - SDL.SDL_GameControllerClose(INTERNAL_devices[output]); - INTERNAL_devices[output] = IntPtr.Zero; - INTERNAL_states[output] = InitializedState; - INTERNAL_guids[output] = String.Empty; - - // A lot of errors can happen here, but honestly, they can be ignored... - SDL.SDL_ClearError(); - - System.Console.WriteLine("Removed device, player: " + output.ToString()); - } - - #endregion - - #region Value-To-Input Helper Methods - - // GetState can convert stick values to button values - private static Buttons READ_StickToButtons(Vector2 stick, Buttons left, Buttons right, Buttons up , Buttons down, float DeadZoneSize) - { - Buttons b = (Buttons) 0; - - if (stick.X > DeadZoneSize) - { - b |= right; - } - if (stick.X < -DeadZoneSize) - { - b |= left; - } - if (stick.Y > DeadZoneSize) - { - b |= up; - } - if (stick.Y < -DeadZoneSize) - { - b |= down; - } - - return b; - } - - // GetState can convert trigger values to button values - private static Buttons READ_TriggerToButton(float trigger, Buttons button, float DeadZoneSize) - { - Buttons b = (Buttons) 0; - - if (trigger > DeadZoneSize) - { - b |= button; - } - - return b; - } - - #endregion - - #region Public GamePad API - - public static GamePadCapabilities GetCapabilities(PlayerIndex playerIndex) - { - if (INTERNAL_devices[(int) playerIndex] == IntPtr.Zero) - { - return new GamePadCapabilities(); - } - - // An SDL_GameController will _always_ be feature-complete. - return new GamePadCapabilities() - { - IsConnected = INTERNAL_devices[(int) playerIndex] != IntPtr.Zero, - HasAButton = true, - HasBButton = true, - HasXButton = true, - HasYButton = true, - HasBackButton = true, - HasStartButton = true, - HasDPadDownButton = true, - HasDPadLeftButton = true, - HasDPadRightButton = true, - HasDPadUpButton = true, - HasLeftShoulderButton = true, - HasRightShoulderButton = true, - HasLeftStickButton = true, - HasRightStickButton = true, - HasLeftTrigger = true, - HasRightTrigger = true, - HasLeftXThumbStick = true, - HasLeftYThumbStick = true, - HasRightXThumbStick = true, - HasRightYThumbStick = true, - HasBigButton = true, - HasLeftVibrationMotor = INTERNAL_haptics[(int) playerIndex] != IntPtr.Zero, - HasRightVibrationMotor = INTERNAL_haptics[(int) playerIndex] != IntPtr.Zero, - HasVoiceSupport = false - }; - } - - public static GamePadState GetState(PlayerIndex playerIndex) - { - return GetState(playerIndex, GamePadDeadZone.IndependentAxes); - } - - public static GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode) - { - IntPtr device = INTERNAL_devices[(int) playerIndex]; - if (device == IntPtr.Zero) - { - return InitializedState; - } - - // Do not attempt to understand this number at all costs! - const float DeadZoneSize = 0.27f; - - // The "master" button state is built from this. - Buttons gc_buttonState = (Buttons) 0; - - // Sticks - GamePadThumbSticks gc_sticks = new GamePadThumbSticks( - new Vector2( - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX - ) / 32768.0f, - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY - ) / -32768.0f * invertAxis - ), - new Vector2( - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX - ) / 32768.0f, - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY - ) / -32768.0f * invertAxis - ), - deadZoneMode - ); - gc_buttonState |= READ_StickToButtons( - gc_sticks.Left, - Buttons.LeftThumbstickLeft, - Buttons.LeftThumbstickRight, - Buttons.LeftThumbstickUp, - Buttons.LeftThumbstickDown, - DeadZoneSize - ); - gc_buttonState |= READ_StickToButtons( - gc_sticks.Right, - Buttons.RightThumbstickLeft, - Buttons.RightThumbstickRight, - Buttons.RightThumbstickUp, - Buttons.RightThumbstickDown, - DeadZoneSize - ); - - // Triggers - GamePadTriggers gc_triggers = new GamePadTriggers( - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT - ) / 32768.0f, - (float) SDL.SDL_GameControllerGetAxis( - device, - SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT - ) / 32768.0f - ); - gc_buttonState |= READ_TriggerToButton( - gc_triggers.Left, - Buttons.LeftTrigger, - DeadZoneSize - ); - gc_buttonState |= READ_TriggerToButton( - gc_triggers.Right, - Buttons.RightTrigger, - DeadZoneSize - ); - - // Buttons - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A) != 0) - { - gc_buttonState |= Buttons.A; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B) != 0) - { - gc_buttonState |= Buttons.B; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X) != 0) - { - gc_buttonState |= Buttons.X; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y) != 0) - { - gc_buttonState |= Buttons.Y; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK) != 0) - { - gc_buttonState |= Buttons.Back; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE) != 0) - { - gc_buttonState |= Buttons.BigButton; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START) != 0) - { - gc_buttonState |= Buttons.Start; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK) != 0) - { - gc_buttonState |= Buttons.LeftStick; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK) != 0) - { - gc_buttonState |= Buttons.RightStick; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER) != 0) - { - gc_buttonState |= Buttons.LeftShoulder; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) != 0) - { - gc_buttonState |= Buttons.RightShoulder; - } - - // DPad - GamePadDPad gc_dpad; - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP) != 0) - { - gc_buttonState |= Buttons.DPadUp; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN) != 0) - { - gc_buttonState |= Buttons.DPadDown; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT) != 0) - { - gc_buttonState |= Buttons.DPadLeft; - } - if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT) != 0) - { - gc_buttonState |= Buttons.DPadRight; - } - gc_dpad = new GamePadDPad(gc_buttonState); - - // Compile the master buttonstate - GamePadButtons gc_buttons = new GamePadButtons(gc_buttonState); - - // Build the GamePadState, increment PacketNumber if state changed. - GamePadState gc_builtState = new GamePadState( - gc_sticks, - gc_triggers, - gc_buttons, - gc_dpad - ); - gc_builtState.IsConnected = true; - gc_builtState.PacketNumber = INTERNAL_states[(int) playerIndex].PacketNumber; - if (gc_builtState != INTERNAL_states[(int) playerIndex]) - { - gc_builtState.PacketNumber += 1; - INTERNAL_states[(int) playerIndex] = gc_builtState; - } - - return gc_builtState; - } - - public static bool SetVibration(PlayerIndex playerIndex, float leftMotor, float rightMotor) - { - IntPtr haptic = INTERNAL_haptics[(int) playerIndex]; - HapticType type = INTERNAL_hapticTypes[(int) playerIndex]; - - if (haptic == IntPtr.Zero) - { - return false; - } - - if (leftMotor <= 0.0f && rightMotor <= 0.0f) - { - SDL.SDL_HapticStopAll(haptic); - } - else if (type == HapticType.LeftRight) - { - INTERNAL_leftRightEffect.leftright.large_magnitude = (ushort) (65535.0f * leftMotor); - INTERNAL_leftRightEffect.leftright.small_magnitude = (ushort) (65535.0f * rightMotor); - SDL.SDL_HapticUpdateEffect( - haptic, - 0, - ref INTERNAL_leftRightEffect - ); - SDL.SDL_HapticRunEffect( - haptic, - 0, - 1 - ); - } - else if (type == HapticType.LeftRightMacHack) - { - leftRightMacHackData[0] = (ushort) (65535.0f * leftMotor); - leftRightMacHackData[1] = (ushort) (65535.0f * rightMotor); - SDL.SDL_HapticUpdateEffect( - haptic, - 0, - ref INTERNAL_leftRightMacHackEffect - ); - SDL.SDL_HapticRunEffect( - haptic, - 0, - 1 - ); - } - else - { - SDL.SDL_HapticRumblePlay( - haptic, - Math.Max(leftMotor, rightMotor), - SDL.SDL_HAPTIC_INFINITY // Oh dear... - ); - } - return true; - } - - #endregion - - #region Public GamePad API, FNA Extensions - - public static string GetGUIDEXT(PlayerIndex playerIndex) - { - return INTERNAL_guids[(int) playerIndex]; - } - - public static void SetLightBarEXT(PlayerIndex playerIndex, Color color) - { - if (String.IsNullOrEmpty(INTERNAL_lightBars[(int) playerIndex])) - { - return; - } - - string baseDir = INTERNAL_lightBars[(int) playerIndex]; - try - { - File.WriteAllText(baseDir + "red/brightness", color.R.ToString()); - File.WriteAllText(baseDir + "green/brightness", color.G.ToString()); - File.WriteAllText(baseDir + "blue/brightness", color.B.ToString()); - } - catch - { - // If something went wrong, assume the worst and just remove it. - INTERNAL_lightBars[(int) playerIndex] = String.Empty; - } - } - - #endregion - } -} diff --git a/src/SDL2/Input/SDL2_KeyboardUtil.cs b/src/SDL2/Input/SDL2_KeyboardUtil.cs deleted file mode 100644 index 0d18b8d..0000000 --- a/src/SDL2/Input/SDL2_KeyboardUtil.cs +++ /dev/null @@ -1,457 +0,0 @@ -#region License -/* FNA - XNA4 Reimplementation for Desktop Platforms - * Copyright 2009-2016 Ethan Lee and the MonoGame Team - * - * Released under the Microsoft Public License. - * See LICENSE for details. - */ -#endregion - -#region Using Statements -using System.Collections.Generic; - -using SDL2; -#endregion - -namespace Microsoft.Xna.Framework.Input -{ - internal static class SDL2_KeyboardUtil - { - #region Private SDL2->XNA Key Hashmaps - - /* From: http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage-collector-nirvana.aspx - * "If you use an enum type as a dictionary key, internal dictionary operations will cause boxing. - * You can avoid this by using integer keys, and casting your enum values to ints before adding - * them to the dictionary." - */ - private static Dictionary INTERNAL_keyMap; - private static Dictionary INTERNAL_scanMap; - private static Dictionary INTERNAL_xnaMap; - - #endregion - - #region Hashmap Initializer Constructor - - static SDL2_KeyboardUtil() - { - // Create the dictionaries... - INTERNAL_keyMap = new Dictionary(); - INTERNAL_scanMap = new Dictionary(); - INTERNAL_xnaMap = new Dictionary(); - - // Then fill them with known keys that match up to XNA Keys. - - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_a, Keys.A); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_b, Keys.B); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_c, Keys.C); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_d, Keys.D); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_e, Keys.E); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_f, Keys.F); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_g, Keys.G); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_h, Keys.H); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_i, Keys.I); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_j, Keys.J); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_k, Keys.K); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_l, Keys.L); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_m, Keys.M); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_n, Keys.N); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_o, Keys.O); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_p, Keys.P); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_q, Keys.Q); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_r, Keys.R); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_s, Keys.S); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_t, Keys.T); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_u, Keys.U); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_v, Keys.V); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_w, Keys.W); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_x, Keys.X); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_y, Keys.Y); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_z, Keys.Z); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_0, Keys.D0); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_1, Keys.D1); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_2, Keys.D2); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_3, Keys.D3); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_4, Keys.D4); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_5, Keys.D5); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_6, Keys.D6); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_7, Keys.D7); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_8, Keys.D8); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_9, Keys.D9); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_0, Keys.NumPad0); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_1, Keys.NumPad1); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_2, Keys.NumPad2); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_3, Keys.NumPad3); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_4, Keys.NumPad4); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_5, Keys.NumPad5); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_6, Keys.NumPad6); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_7, Keys.NumPad7); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_8, Keys.NumPad8); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_9, Keys.NumPad9); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_CLEAR, Keys.OemClear); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_DECIMAL, Keys.Decimal); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_DIVIDE, Keys.Divide); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_ENTER, Keys.Enter); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_MINUS, Keys.Subtract); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_MULTIPLY, Keys.Multiply); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_PERIOD, Keys.OemPeriod); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_PLUS, Keys.Add); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F1, Keys.F1); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F2, Keys.F2); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F3, Keys.F3); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F4, Keys.F4); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F5, Keys.F5); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F6, Keys.F6); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F7, Keys.F7); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F8, Keys.F8); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F9, Keys.F9); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F10, Keys.F10); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F11, Keys.F11); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F12, Keys.F12); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F13, Keys.F13); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F14, Keys.F14); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F15, Keys.F15); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F16, Keys.F16); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F17, Keys.F17); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F18, Keys.F18); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F19, Keys.F19); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F20, Keys.F20); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F21, Keys.F21); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F22, Keys.F22); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F23, Keys.F23); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F24, Keys.F24); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SPACE, Keys.Space); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_UP, Keys.Up); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_DOWN, Keys.Down); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LEFT, Keys.Left); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RIGHT, Keys.Right); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LALT, Keys.LeftAlt); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RALT, Keys.RightAlt); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LCTRL, Keys.LeftControl); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RCTRL, Keys.RightControl); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LGUI, Keys.LeftWindows); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RGUI, Keys.RightWindows); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LSHIFT, Keys.LeftShift); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RSHIFT, Keys.RightShift); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_APPLICATION, Keys.Apps); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SLASH, Keys.OemQuestion); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKSLASH, Keys.OemBackslash); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LEFTBRACKET, Keys.OemOpenBrackets); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RIGHTBRACKET, Keys.OemCloseBrackets); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_CAPSLOCK, Keys.CapsLock); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_COMMA, Keys.OemComma); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_DELETE, Keys.Delete); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_END, Keys.End); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKSPACE, Keys.Back); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RETURN, Keys.Enter); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_ESCAPE, Keys.Escape); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_HOME, Keys.Home); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_INSERT, Keys.Insert); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_MINUS, Keys.OemMinus); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_NUMLOCKCLEAR, Keys.NumLock); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAGEUP, Keys.PageUp); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAGEDOWN, Keys.PageDown); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAUSE, Keys.Pause); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PERIOD, Keys.OemPeriod); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_EQUALS, Keys.OemPlus); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PRINTSCREEN, Keys.PrintScreen); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_QUOTE, Keys.OemQuotes); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SCROLLLOCK, Keys.Scroll); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SEMICOLON, Keys.OemSemicolon); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SLEEP, Keys.Sleep); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_TAB, Keys.Tab); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKQUOTE, Keys.OemTilde); - INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_UNKNOWN, Keys.None); - - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_A, Keys.A); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_B, Keys.B); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_C, Keys.C); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_D, Keys.D); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_E, Keys.E); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F, Keys.F); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_G, Keys.G); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_H, Keys.H); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_I, Keys.I); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_J, Keys.J); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_K, Keys.K); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_L, Keys.L); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_M, Keys.M); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_N, Keys.N); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_O, Keys.O); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_P, Keys.P); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Q, Keys.Q); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_R, Keys.R); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_S, Keys.S); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_T, Keys.T); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_U, Keys.U); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_V, Keys.V); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_W, Keys.W); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_X, Keys.X); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Y, Keys.Y); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Z, Keys.Z); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_0, Keys.D0); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_1, Keys.D1); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_2, Keys.D2); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_3, Keys.D3); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_4, Keys.D4); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_5, Keys.D5); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_6, Keys.D6); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_7, Keys.D7); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_8, Keys.D8); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_9, Keys.D9); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_0, Keys.NumPad0); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_1, Keys.NumPad1); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_2, Keys.NumPad2); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_3, Keys.NumPad3); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_4, Keys.NumPad4); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_5, Keys.NumPad5); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_6, Keys.NumPad6); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_7, Keys.NumPad7); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_8, Keys.NumPad8); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_9, Keys.NumPad9); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_CLEAR, Keys.OemClear); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_DECIMAL, Keys.Decimal); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_DIVIDE, Keys.Divide); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_ENTER, Keys.Enter); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_MINUS, Keys.Subtract); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY, Keys.Multiply); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_PERIOD, Keys.OemPeriod); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_PLUS, Keys.Add); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F1, Keys.F1); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F2, Keys.F2); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F3, Keys.F3); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F4, Keys.F4); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F5, Keys.F5); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F6, Keys.F6); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F7, Keys.F7); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F8, Keys.F8); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F9, Keys.F9); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F10, Keys.F10); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F11, Keys.F11); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F12, Keys.F12); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F13, Keys.F13); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F14, Keys.F14); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F15, Keys.F15); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F16, Keys.F16); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F17, Keys.F17); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F18, Keys.F18); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F19, Keys.F19); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F20, Keys.F20); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F21, Keys.F21); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F22, Keys.F22); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F23, Keys.F23); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F24, Keys.F24); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SPACE, Keys.Space); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_UP, Keys.Up); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_DOWN, Keys.Down); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LEFT, Keys.Left); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RIGHT, Keys.Right); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LALT, Keys.LeftAlt); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RALT, Keys.RightAlt); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LCTRL, Keys.LeftControl); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RCTRL, Keys.RightControl); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LGUI, Keys.LeftWindows); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RGUI, Keys.RightWindows); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LSHIFT, Keys.LeftShift); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RSHIFT, Keys.RightShift); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_APPLICATION, Keys.Apps); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SLASH, Keys.OemQuestion); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_BACKSLASH, Keys.OemBackslash); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LEFTBRACKET, Keys.OemOpenBrackets); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RIGHTBRACKET, Keys.OemCloseBrackets); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_CAPSLOCK, Keys.CapsLock); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_COMMA, Keys.OemComma); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_DELETE, Keys.Delete); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_END, Keys.End); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_BACKSPACE, Keys.Back); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RETURN, Keys.Enter); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_ESCAPE, Keys.Escape); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_HOME, Keys.Home); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_INSERT, Keys.Insert); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_MINUS, Keys.OemMinus); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR, Keys.NumLock); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAGEUP, Keys.PageUp); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAGEDOWN, Keys.PageDown); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAUSE, Keys.Pause); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PERIOD, Keys.OemPeriod); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_EQUALS, Keys.OemPlus); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PRINTSCREEN, Keys.PrintScreen); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_APOSTROPHE, Keys.OemQuotes); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SCROLLLOCK, Keys.Scroll); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SEMICOLON, Keys.OemSemicolon); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SLEEP, Keys.Sleep); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_TAB, Keys.Tab); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_GRAVE, Keys.OemTilde); - INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_UNKNOWN, Keys.None); - - // Also, fill up another with the reverse, for scancode->keycode lookups - - INTERNAL_xnaMap.Add((int) Keys.A, SDL.SDL_Scancode.SDL_SCANCODE_A); - INTERNAL_xnaMap.Add((int) Keys.B, SDL.SDL_Scancode.SDL_SCANCODE_B); - INTERNAL_xnaMap.Add((int) Keys.C, SDL.SDL_Scancode.SDL_SCANCODE_C); - INTERNAL_xnaMap.Add((int) Keys.D, SDL.SDL_Scancode.SDL_SCANCODE_D); - INTERNAL_xnaMap.Add((int) Keys.E, SDL.SDL_Scancode.SDL_SCANCODE_E); - INTERNAL_xnaMap.Add((int) Keys.F, SDL.SDL_Scancode.SDL_SCANCODE_F); - INTERNAL_xnaMap.Add((int) Keys.G, SDL.SDL_Scancode.SDL_SCANCODE_G); - INTERNAL_xnaMap.Add((int) Keys.H, SDL.SDL_Scancode.SDL_SCANCODE_H); - INTERNAL_xnaMap.Add((int) Keys.I, SDL.SDL_Scancode.SDL_SCANCODE_I); - INTERNAL_xnaMap.Add((int) Keys.J, SDL.SDL_Scancode.SDL_SCANCODE_J); - INTERNAL_xnaMap.Add((int) Keys.K, SDL.SDL_Scancode.SDL_SCANCODE_K); - INTERNAL_xnaMap.Add((int) Keys.L, SDL.SDL_Scancode.SDL_SCANCODE_L); - INTERNAL_xnaMap.Add((int) Keys.M, SDL.SDL_Scancode.SDL_SCANCODE_M); - INTERNAL_xnaMap.Add((int) Keys.N, SDL.SDL_Scancode.SDL_SCANCODE_N); - INTERNAL_xnaMap.Add((int) Keys.O, SDL.SDL_Scancode.SDL_SCANCODE_O); - INTERNAL_xnaMap.Add((int) Keys.P, SDL.SDL_Scancode.SDL_SCANCODE_P); - INTERNAL_xnaMap.Add((int) Keys.Q, SDL.SDL_Scancode.SDL_SCANCODE_Q); - INTERNAL_xnaMap.Add((int) Keys.R, SDL.SDL_Scancode.SDL_SCANCODE_R); - INTERNAL_xnaMap.Add((int) Keys.S, SDL.SDL_Scancode.SDL_SCANCODE_S); - INTERNAL_xnaMap.Add((int) Keys.T, SDL.SDL_Scancode.SDL_SCANCODE_T); - INTERNAL_xnaMap.Add((int) Keys.U, SDL.SDL_Scancode.SDL_SCANCODE_U); - INTERNAL_xnaMap.Add((int) Keys.V, SDL.SDL_Scancode.SDL_SCANCODE_V); - INTERNAL_xnaMap.Add((int) Keys.W, SDL.SDL_Scancode.SDL_SCANCODE_W); - INTERNAL_xnaMap.Add((int) Keys.X, SDL.SDL_Scancode.SDL_SCANCODE_X); - INTERNAL_xnaMap.Add((int) Keys.Y, SDL.SDL_Scancode.SDL_SCANCODE_Y); - INTERNAL_xnaMap.Add((int) Keys.Z, SDL.SDL_Scancode.SDL_SCANCODE_Z); - INTERNAL_xnaMap.Add((int) Keys.D0, SDL.SDL_Scancode.SDL_SCANCODE_0); - INTERNAL_xnaMap.Add((int) Keys.D1, SDL.SDL_Scancode.SDL_SCANCODE_1); - INTERNAL_xnaMap.Add((int) Keys.D2, SDL.SDL_Scancode.SDL_SCANCODE_2); - INTERNAL_xnaMap.Add((int) Keys.D3, SDL.SDL_Scancode.SDL_SCANCODE_3); - INTERNAL_xnaMap.Add((int) Keys.D4, SDL.SDL_Scancode.SDL_SCANCODE_4); - INTERNAL_xnaMap.Add((int) Keys.D5, SDL.SDL_Scancode.SDL_SCANCODE_5); - INTERNAL_xnaMap.Add((int) Keys.D6, SDL.SDL_Scancode.SDL_SCANCODE_6); - INTERNAL_xnaMap.Add((int) Keys.D7, SDL.SDL_Scancode.SDL_SCANCODE_7); - INTERNAL_xnaMap.Add((int) Keys.D8, SDL.SDL_Scancode.SDL_SCANCODE_8); - INTERNAL_xnaMap.Add((int) Keys.D9, SDL.SDL_Scancode.SDL_SCANCODE_9); - INTERNAL_xnaMap.Add((int) Keys.NumPad0, SDL.SDL_Scancode.SDL_SCANCODE_KP_0); - INTERNAL_xnaMap.Add((int) Keys.NumPad1, SDL.SDL_Scancode.SDL_SCANCODE_KP_1); - INTERNAL_xnaMap.Add((int) Keys.NumPad2, SDL.SDL_Scancode.SDL_SCANCODE_KP_2); - INTERNAL_xnaMap.Add((int) Keys.NumPad3, SDL.SDL_Scancode.SDL_SCANCODE_KP_3); - INTERNAL_xnaMap.Add((int) Keys.NumPad4, SDL.SDL_Scancode.SDL_SCANCODE_KP_4); - INTERNAL_xnaMap.Add((int) Keys.NumPad5, SDL.SDL_Scancode.SDL_SCANCODE_KP_5); - INTERNAL_xnaMap.Add((int) Keys.NumPad6, SDL.SDL_Scancode.SDL_SCANCODE_KP_6); - INTERNAL_xnaMap.Add((int) Keys.NumPad7, SDL.SDL_Scancode.SDL_SCANCODE_KP_7); - INTERNAL_xnaMap.Add((int) Keys.NumPad8, SDL.SDL_Scancode.SDL_SCANCODE_KP_8); - INTERNAL_xnaMap.Add((int) Keys.NumPad9, SDL.SDL_Scancode.SDL_SCANCODE_KP_9); - INTERNAL_xnaMap.Add((int) Keys.OemClear, SDL.SDL_Scancode.SDL_SCANCODE_KP_CLEAR); - INTERNAL_xnaMap.Add((int) Keys.Decimal, SDL.SDL_Scancode.SDL_SCANCODE_KP_DECIMAL); - INTERNAL_xnaMap.Add((int) Keys.Divide, SDL.SDL_Scancode.SDL_SCANCODE_KP_DIVIDE); - INTERNAL_xnaMap.Add((int) Keys.Multiply, SDL.SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY); - INTERNAL_xnaMap.Add((int) Keys.Subtract, SDL.SDL_Scancode.SDL_SCANCODE_KP_MINUS); - INTERNAL_xnaMap.Add((int) Keys.Add, SDL.SDL_Scancode.SDL_SCANCODE_KP_PLUS); - INTERNAL_xnaMap.Add((int) Keys.F1, SDL.SDL_Scancode.SDL_SCANCODE_F1); - INTERNAL_xnaMap.Add((int) Keys.F2, SDL.SDL_Scancode.SDL_SCANCODE_F2); - INTERNAL_xnaMap.Add((int) Keys.F3, SDL.SDL_Scancode.SDL_SCANCODE_F3); - INTERNAL_xnaMap.Add((int) Keys.F4, SDL.SDL_Scancode.SDL_SCANCODE_F4); - INTERNAL_xnaMap.Add((int) Keys.F5, SDL.SDL_Scancode.SDL_SCANCODE_F5); - INTERNAL_xnaMap.Add((int) Keys.F6, SDL.SDL_Scancode.SDL_SCANCODE_F6); - INTERNAL_xnaMap.Add((int) Keys.F7, SDL.SDL_Scancode.SDL_SCANCODE_F7); - INTERNAL_xnaMap.Add((int) Keys.F8, SDL.SDL_Scancode.SDL_SCANCODE_F8); - INTERNAL_xnaMap.Add((int) Keys.F9, SDL.SDL_Scancode.SDL_SCANCODE_F9); - INTERNAL_xnaMap.Add((int) Keys.F10, SDL.SDL_Scancode.SDL_SCANCODE_F10); - INTERNAL_xnaMap.Add((int) Keys.F11, SDL.SDL_Scancode.SDL_SCANCODE_F11); - INTERNAL_xnaMap.Add((int) Keys.F12, SDL.SDL_Scancode.SDL_SCANCODE_F12); - INTERNAL_xnaMap.Add((int) Keys.F13, SDL.SDL_Scancode.SDL_SCANCODE_F13); - INTERNAL_xnaMap.Add((int) Keys.F14, SDL.SDL_Scancode.SDL_SCANCODE_F14); - INTERNAL_xnaMap.Add((int) Keys.F15, SDL.SDL_Scancode.SDL_SCANCODE_F15); - INTERNAL_xnaMap.Add((int) Keys.F16, SDL.SDL_Scancode.SDL_SCANCODE_F16); - INTERNAL_xnaMap.Add((int) Keys.F17, SDL.SDL_Scancode.SDL_SCANCODE_F17); - INTERNAL_xnaMap.Add((int) Keys.F18, SDL.SDL_Scancode.SDL_SCANCODE_F18); - INTERNAL_xnaMap.Add((int) Keys.F19, SDL.SDL_Scancode.SDL_SCANCODE_F19); - INTERNAL_xnaMap.Add((int) Keys.F20, SDL.SDL_Scancode.SDL_SCANCODE_F20); - INTERNAL_xnaMap.Add((int) Keys.F21, SDL.SDL_Scancode.SDL_SCANCODE_F21); - INTERNAL_xnaMap.Add((int) Keys.F22, SDL.SDL_Scancode.SDL_SCANCODE_F22); - INTERNAL_xnaMap.Add((int) Keys.F23, SDL.SDL_Scancode.SDL_SCANCODE_F23); - INTERNAL_xnaMap.Add((int) Keys.F24, SDL.SDL_Scancode.SDL_SCANCODE_F24); - INTERNAL_xnaMap.Add((int) Keys.Space, SDL.SDL_Scancode.SDL_SCANCODE_SPACE); - INTERNAL_xnaMap.Add((int) Keys.Up, SDL.SDL_Scancode.SDL_SCANCODE_UP); - INTERNAL_xnaMap.Add((int) Keys.Down, SDL.SDL_Scancode.SDL_SCANCODE_DOWN); - INTERNAL_xnaMap.Add((int) Keys.Left, SDL.SDL_Scancode.SDL_SCANCODE_LEFT); - INTERNAL_xnaMap.Add((int) Keys.Right, SDL.SDL_Scancode.SDL_SCANCODE_RIGHT); - INTERNAL_xnaMap.Add((int) Keys.LeftAlt, SDL.SDL_Scancode.SDL_SCANCODE_LALT); - INTERNAL_xnaMap.Add((int) Keys.RightAlt, SDL.SDL_Scancode.SDL_SCANCODE_RALT); - INTERNAL_xnaMap.Add((int) Keys.LeftControl, SDL.SDL_Scancode.SDL_SCANCODE_LCTRL); - INTERNAL_xnaMap.Add((int) Keys.RightControl, SDL.SDL_Scancode.SDL_SCANCODE_RCTRL); - INTERNAL_xnaMap.Add((int) Keys.LeftWindows, SDL.SDL_Scancode.SDL_SCANCODE_LGUI); - INTERNAL_xnaMap.Add((int) Keys.RightWindows, SDL.SDL_Scancode.SDL_SCANCODE_RGUI); - INTERNAL_xnaMap.Add((int) Keys.LeftShift, SDL.SDL_Scancode.SDL_SCANCODE_LSHIFT); - INTERNAL_xnaMap.Add((int) Keys.RightShift, SDL.SDL_Scancode.SDL_SCANCODE_RSHIFT); - INTERNAL_xnaMap.Add((int) Keys.Apps, SDL.SDL_Scancode.SDL_SCANCODE_APPLICATION); - INTERNAL_xnaMap.Add((int) Keys.OemQuestion, SDL.SDL_Scancode.SDL_SCANCODE_SLASH); - INTERNAL_xnaMap.Add((int) Keys.OemBackslash, SDL.SDL_Scancode.SDL_SCANCODE_BACKSLASH); - INTERNAL_xnaMap.Add((int) Keys.OemOpenBrackets, SDL.SDL_Scancode.SDL_SCANCODE_LEFTBRACKET); - INTERNAL_xnaMap.Add((int) Keys.OemCloseBrackets, SDL.SDL_Scancode.SDL_SCANCODE_RIGHTBRACKET); - INTERNAL_xnaMap.Add((int) Keys.CapsLock, SDL.SDL_Scancode.SDL_SCANCODE_CAPSLOCK); - INTERNAL_xnaMap.Add((int) Keys.OemComma, SDL.SDL_Scancode.SDL_SCANCODE_COMMA); - INTERNAL_xnaMap.Add((int) Keys.Delete, SDL.SDL_Scancode.SDL_SCANCODE_DELETE); - INTERNAL_xnaMap.Add((int) Keys.End, SDL.SDL_Scancode.SDL_SCANCODE_END); - INTERNAL_xnaMap.Add((int) Keys.Back, SDL.SDL_Scancode.SDL_SCANCODE_BACKSPACE); - INTERNAL_xnaMap.Add((int) Keys.Enter, SDL.SDL_Scancode.SDL_SCANCODE_RETURN); - INTERNAL_xnaMap.Add((int) Keys.Escape, SDL.SDL_Scancode.SDL_SCANCODE_ESCAPE); - INTERNAL_xnaMap.Add((int) Keys.Home, SDL.SDL_Scancode.SDL_SCANCODE_HOME); - INTERNAL_xnaMap.Add((int) Keys.Insert, SDL.SDL_Scancode.SDL_SCANCODE_INSERT); - INTERNAL_xnaMap.Add((int) Keys.OemMinus, SDL.SDL_Scancode.SDL_SCANCODE_MINUS); - INTERNAL_xnaMap.Add((int) Keys.NumLock, SDL.SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR); - INTERNAL_xnaMap.Add((int) Keys.PageUp, SDL.SDL_Scancode.SDL_SCANCODE_PAGEUP); - INTERNAL_xnaMap.Add((int) Keys.PageDown, SDL.SDL_Scancode.SDL_SCANCODE_PAGEDOWN); - INTERNAL_xnaMap.Add((int) Keys.Pause, SDL.SDL_Scancode.SDL_SCANCODE_PAUSE); - INTERNAL_xnaMap.Add((int) Keys.OemPeriod, SDL.SDL_Scancode.SDL_SCANCODE_PERIOD); - INTERNAL_xnaMap.Add((int) Keys.OemPlus, SDL.SDL_Scancode.SDL_SCANCODE_EQUALS); - INTERNAL_xnaMap.Add((int) Keys.PrintScreen, SDL.SDL_Scancode.SDL_SCANCODE_PRINTSCREEN); - INTERNAL_xnaMap.Add((int) Keys.OemQuotes, SDL.SDL_Scancode.SDL_SCANCODE_APOSTROPHE); - INTERNAL_xnaMap.Add((int) Keys.Scroll, SDL.SDL_Scancode.SDL_SCANCODE_SCROLLLOCK); - INTERNAL_xnaMap.Add((int) Keys.OemSemicolon, SDL.SDL_Scancode.SDL_SCANCODE_SEMICOLON); - INTERNAL_xnaMap.Add((int) Keys.Sleep, SDL.SDL_Scancode.SDL_SCANCODE_SLEEP); - INTERNAL_xnaMap.Add((int) Keys.Tab, SDL.SDL_Scancode.SDL_SCANCODE_TAB); - INTERNAL_xnaMap.Add((int) Keys.OemTilde, SDL.SDL_Scancode.SDL_SCANCODE_GRAVE); - INTERNAL_xnaMap.Add((int) Keys.None, SDL.SDL_Scancode.SDL_SCANCODE_UNKNOWN); - } - - #endregion - - #region Public SDL2<->XNA Key Conversion Methods - - public static Keys ToXNA(SDL.SDL_Keycode key) - { - Keys retVal; - if (INTERNAL_keyMap.TryGetValue((int) key, out retVal)) - { - return retVal; - } - else - { - System.Console.WriteLine("KEY MISSING FROM SDL2->XNA DICTIONARY: " + key.ToString()); - return Keys.None; - } - } - - public static Keys ToXNA(SDL.SDL_Scancode key) - { - Keys retVal; - if (INTERNAL_scanMap.TryGetValue((int) key, out retVal)) - { - return retVal; - } - else - { - System.Console.WriteLine("SCANCODE MISSING FROM SDL2->XNA DICTIONARY: " + key.ToString()); - return Keys.None; - } - } - - public static Keys KeyFromScancode(Keys scancode) - { - SDL.SDL_Scancode retVal; - if (INTERNAL_xnaMap.TryGetValue((int) scancode, out retVal)) - { - return INTERNAL_keyMap[(int) SDL.SDL_GetKeyFromScancode(retVal)]; - } - else - { - System.Console.WriteLine("SCANCODE MISSING FROM XNA->SDL2 DICTIONARY: " + scancode.ToString()); - return Keys.None; - } - } - - #endregion - } -} - diff --git a/src/SDL2/SDL2_FNAPlatform.cs b/src/SDL2/SDL2_FNAPlatform.cs index b2f194d..7c079f7 100644 --- a/src/SDL2/SDL2_FNAPlatform.cs +++ b/src/SDL2/SDL2_FNAPlatform.cs @@ -27,6 +27,7 @@ #region Using Statements using System; using System.IO; +using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -355,11 +356,11 @@ namespace Microsoft.Xna.Framework // Controller device management else if (evt.type == SDL.SDL_EventType.SDL_CONTROLLERDEVICEADDED) { - GamePad.INTERNAL_AddInstance(evt.cdevice.which); + INTERNAL_AddInstance(evt.cdevice.which); } else if (evt.type == SDL.SDL_EventType.SDL_CONTROLLERDEVICEREMOVED) { - GamePad.INTERNAL_RemoveInstance(evt.cdevice.which); + INTERNAL_RemoveInstance(evt.cdevice.which); } // Text Input @@ -431,7 +432,7 @@ namespace Microsoft.Xna.Framework SDL.SDL_EventType.SDL_CONTROLLERDEVICEADDED, SDL.SDL_EventType.SDL_CONTROLLERDEVICEADDED ) == 1) { - GamePad.INTERNAL_AddInstance(evt[0].cdevice.which); + INTERNAL_AddInstance(evt[0].cdevice.which); } } @@ -611,7 +612,7 @@ namespace Microsoft.Xna.Framework } return osConfigDir; } - throw new Exception("StorageDevice: Platform.OSVersion not handled!"); + throw new NotSupportedException("Unhandled SDL2 platform!"); } public static bool IsStoragePathConnected(string path) @@ -636,7 +637,7 @@ namespace Microsoft.Xna.Framework return false; } } - throw new Exception("StorageDevice: Platform.OSVersion not handled!"); + throw new NotSupportedException("Unhandled SDL2 platform"); } public static void Log(string Message) @@ -889,6 +890,603 @@ namespace Microsoft.Xna.Framework #endregion + #region GamePad Backend + + private enum HapticType + { + Simple = 0, + LeftRight = 1, + LeftRightMacHack = 2 + } + + // Controller device information + private static IntPtr[] INTERNAL_devices = new IntPtr[GamePad.GAMEPAD_COUNT]; + private static Dictionary INTERNAL_instanceList = new Dictionary(); + private static string[] INTERNAL_guids = GenStringArray(); + + // Haptic device information + private static IntPtr[] INTERNAL_haptics = new IntPtr[GamePad.GAMEPAD_COUNT]; + private static HapticType[] INTERNAL_hapticTypes = new HapticType[GamePad.GAMEPAD_COUNT]; + + // Light bar information + private static string[] INTERNAL_lightBars = GenStringArray(); + + // Cached GamePadStates/Capabilities + private static GamePadState[] INTERNAL_states = new GamePadState[GamePad.GAMEPAD_COUNT]; + private static GamePadCapabilities[] INTERNAL_capabilities = new GamePadCapabilities[GamePad.GAMEPAD_COUNT]; + + // We use this to apply XInput-like rumble effects. + private static SDL.SDL_HapticEffect INTERNAL_leftRightEffect = new SDL.SDL_HapticEffect + { + type = SDL.SDL_HAPTIC_LEFTRIGHT, + leftright = new SDL.SDL_HapticLeftRight + { + type = SDL.SDL_HAPTIC_LEFTRIGHT, + length = SDL.SDL_HAPTIC_INFINITY, + large_magnitude = ushort.MaxValue, + small_magnitude = ushort.MaxValue + } + }; + + // We use this to get left/right support on OSX via a nice driver workaround! + private static ushort[] leftRightMacHackData = {0, 0}; + private static GCHandle leftRightMacHackPArry = GCHandle.Alloc(leftRightMacHackData, GCHandleType.Pinned); + private static IntPtr leftRightMacHackPtr = leftRightMacHackPArry.AddrOfPinnedObject(); + private static SDL.SDL_HapticEffect INTERNAL_leftRightMacHackEffect = new SDL.SDL_HapticEffect + { + type = SDL.SDL_HAPTIC_CUSTOM, + custom = new SDL.SDL_HapticCustom + { + type = SDL.SDL_HAPTIC_CUSTOM, + length = SDL.SDL_HAPTIC_INFINITY, + channels = 2, + period = 1, + samples = 2, + data = leftRightMacHackPtr + } + }; + + // FIXME: SDL_GameController config input inversion! + private static float invertAxis = Environment.GetEnvironmentVariable( + "FNA_WORKAROUND_INVERT_YAXIS" + ) == "1" ? -1.0f : 1.0f; + + public static GamePadCapabilities GetGamePadCapabilities(int index) + { + if (INTERNAL_devices[index] == IntPtr.Zero) + { + return new GamePadCapabilities(); + } + return INTERNAL_capabilities[index]; + } + + public static GamePadState GetGamePadState(int index, GamePadDeadZone deadZoneMode) + { + IntPtr device = INTERNAL_devices[index]; + if (device == IntPtr.Zero) + { + return new GamePadState(); + } + + // Do not attempt to understand this number at all costs! + const float DeadZoneSize = 0.27f; + + // The "master" button state is built from this. + Buttons gc_buttonState = (Buttons) 0; + + // Sticks + GamePadThumbSticks gc_sticks = new GamePadThumbSticks( + new Vector2( + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX + ) / 32768.0f, + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY + ) / -32768.0f * invertAxis + ), + new Vector2( + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX + ) / 32768.0f, + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY + ) / -32768.0f * invertAxis + ), + deadZoneMode + ); + gc_buttonState |= READ_StickToButtons( + gc_sticks.Left, + Buttons.LeftThumbstickLeft, + Buttons.LeftThumbstickRight, + Buttons.LeftThumbstickUp, + Buttons.LeftThumbstickDown, + DeadZoneSize + ); + gc_buttonState |= READ_StickToButtons( + gc_sticks.Right, + Buttons.RightThumbstickLeft, + Buttons.RightThumbstickRight, + Buttons.RightThumbstickUp, + Buttons.RightThumbstickDown, + DeadZoneSize + ); + + // Triggers + GamePadTriggers gc_triggers = new GamePadTriggers( + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT + ) / 32768.0f, + (float) SDL.SDL_GameControllerGetAxis( + device, + SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT + ) / 32768.0f + ); + gc_buttonState |= READ_TriggerToButton( + gc_triggers.Left, + Buttons.LeftTrigger, + DeadZoneSize + ); + gc_buttonState |= READ_TriggerToButton( + gc_triggers.Right, + Buttons.RightTrigger, + DeadZoneSize + ); + + // Buttons + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A) != 0) + { + gc_buttonState |= Buttons.A; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B) != 0) + { + gc_buttonState |= Buttons.B; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X) != 0) + { + gc_buttonState |= Buttons.X; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y) != 0) + { + gc_buttonState |= Buttons.Y; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK) != 0) + { + gc_buttonState |= Buttons.Back; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE) != 0) + { + gc_buttonState |= Buttons.BigButton; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START) != 0) + { + gc_buttonState |= Buttons.Start; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK) != 0) + { + gc_buttonState |= Buttons.LeftStick; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK) != 0) + { + gc_buttonState |= Buttons.RightStick; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER) != 0) + { + gc_buttonState |= Buttons.LeftShoulder; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) != 0) + { + gc_buttonState |= Buttons.RightShoulder; + } + + // DPad + GamePadDPad gc_dpad; + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP) != 0) + { + gc_buttonState |= Buttons.DPadUp; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN) != 0) + { + gc_buttonState |= Buttons.DPadDown; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT) != 0) + { + gc_buttonState |= Buttons.DPadLeft; + } + if (SDL.SDL_GameControllerGetButton(device, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT) != 0) + { + gc_buttonState |= Buttons.DPadRight; + } + gc_dpad = new GamePadDPad(gc_buttonState); + + // Compile the master buttonstate + GamePadButtons gc_buttons = new GamePadButtons(gc_buttonState); + + // Build the GamePadState, increment PacketNumber if state changed. + GamePadState gc_builtState = new GamePadState( + gc_sticks, + gc_triggers, + gc_buttons, + gc_dpad + ); + gc_builtState.IsConnected = true; + gc_builtState.PacketNumber = INTERNAL_states[index].PacketNumber; + if (gc_builtState != INTERNAL_states[index]) + { + gc_builtState.PacketNumber += 1; + INTERNAL_states[index] = gc_builtState; + } + + return gc_builtState; + } + + public static bool SetGamePadVibration(int index, float leftMotor, float rightMotor) + { + IntPtr haptic = INTERNAL_haptics[index]; + HapticType type = INTERNAL_hapticTypes[index]; + + if (haptic == IntPtr.Zero) + { + return false; + } + + if (leftMotor <= 0.0f && rightMotor <= 0.0f) + { + SDL.SDL_HapticStopAll(haptic); + } + else if (type == HapticType.LeftRight) + { + INTERNAL_leftRightEffect.leftright.large_magnitude = (ushort) (65535.0f * leftMotor); + INTERNAL_leftRightEffect.leftright.small_magnitude = (ushort) (65535.0f * rightMotor); + SDL.SDL_HapticUpdateEffect( + haptic, + 0, + ref INTERNAL_leftRightEffect + ); + SDL.SDL_HapticRunEffect( + haptic, + 0, + 1 + ); + } + else if (type == HapticType.LeftRightMacHack) + { + leftRightMacHackData[0] = (ushort) (65535.0f * leftMotor); + leftRightMacHackData[1] = (ushort) (65535.0f * rightMotor); + SDL.SDL_HapticUpdateEffect( + haptic, + 0, + ref INTERNAL_leftRightMacHackEffect + ); + SDL.SDL_HapticRunEffect( + haptic, + 0, + 1 + ); + } + else + { + SDL.SDL_HapticRumblePlay( + haptic, + Math.Max(leftMotor, rightMotor), + SDL.SDL_HAPTIC_INFINITY // Oh dear... + ); + } + return true; + } + + public static string GetGamePadGUID(int index) + { + return INTERNAL_guids[index]; + } + + public static void SetGamePadLightBar(int index, Color color) + { + if (String.IsNullOrEmpty(INTERNAL_lightBars[index])) + { + return; + } + + string baseDir = INTERNAL_lightBars[index]; + try + { + File.WriteAllText(baseDir + "red/brightness", color.R.ToString()); + File.WriteAllText(baseDir + "green/brightness", color.G.ToString()); + File.WriteAllText(baseDir + "blue/brightness", color.B.ToString()); + } + catch + { + // If something went wrong, assume the worst and just remove it. + INTERNAL_lightBars[index] = String.Empty; + } + } + + private static void INTERNAL_AddInstance(int dev) + { + int which = -1; + for (int i = 0; i < INTERNAL_devices.Length; i += 1) + { + if (INTERNAL_devices[i] == IntPtr.Zero) + { + which = i; + break; + } + } + if (which == -1) + { + return; // Ignoring more than 4 controllers. + } + + // Clear the error buffer. We're about to do a LOT of dangerous stuff. + SDL.SDL_ClearError(); + + // Open the device! + INTERNAL_devices[which] = SDL.SDL_GameControllerOpen(dev); + + // We use this when dealing with Haptic/GUID initialization. + IntPtr thisJoystick = SDL.SDL_GameControllerGetJoystick(INTERNAL_devices[which]); + + // Pair up the instance ID to the player index. + // FIXME: Remove check after 2.0.4? -flibit + int thisInstance = SDL.SDL_JoystickInstanceID(thisJoystick); + if (INTERNAL_instanceList.ContainsKey(thisInstance)) + { + // Duplicate? Usually this is OSX being dumb, but...? + INTERNAL_devices[which] = IntPtr.Zero; + return; + } + INTERNAL_instanceList.Add(thisInstance, which); + + // Start with a fresh state. + INTERNAL_states[which] = new GamePadState(); + INTERNAL_states[which].IsConnected = true; + + // Initialize the haptics for the joystick, if applicable. + if (SDL.SDL_JoystickIsHaptic(thisJoystick) == 1) + { + INTERNAL_haptics[which] = SDL.SDL_HapticOpenFromJoystick(thisJoystick); + if (INTERNAL_haptics[which] == IntPtr.Zero) + { + System.Console.WriteLine("HAPTIC OPEN ERROR: " + SDL.SDL_GetError()); + } + } + if (INTERNAL_haptics[which] != IntPtr.Zero) + { + if ( OSVersion.Equals("Mac OS X") && + SDL.SDL_HapticEffectSupported(INTERNAL_haptics[which], ref INTERNAL_leftRightMacHackEffect) == 1 ) + { + INTERNAL_hapticTypes[which] = HapticType.LeftRightMacHack; + SDL.SDL_HapticNewEffect(INTERNAL_haptics[which], ref INTERNAL_leftRightMacHackEffect); + } + else if ( !OSVersion.Equals("Mac OS X") && + SDL.SDL_HapticEffectSupported(INTERNAL_haptics[which], ref INTERNAL_leftRightEffect) == 1 ) + { + INTERNAL_hapticTypes[which] = HapticType.LeftRight; + SDL.SDL_HapticNewEffect(INTERNAL_haptics[which], ref INTERNAL_leftRightEffect); + } + else if (SDL.SDL_HapticRumbleSupported(INTERNAL_haptics[which]) == 1) + { + INTERNAL_hapticTypes[which] = HapticType.Simple; + SDL.SDL_HapticRumbleInit(INTERNAL_haptics[which]); + } + else + { + // We can't even play simple rumble, this haptic device is useless to us. + SDL.SDL_HapticClose(INTERNAL_haptics[which]); + INTERNAL_haptics[which] = IntPtr.Zero; + } + } + + // An SDL_GameController _should_ always be complete... + INTERNAL_capabilities[which] = new GamePadCapabilities() + { + IsConnected = true, + HasAButton = true, + HasBButton = true, + HasXButton = true, + HasYButton = true, + HasBackButton = true, + HasStartButton = true, + HasDPadDownButton = true, + HasDPadLeftButton = true, + HasDPadRightButton = true, + HasDPadUpButton = true, + HasLeftShoulderButton = true, + HasRightShoulderButton = true, + HasLeftStickButton = true, + HasRightStickButton = true, + HasLeftTrigger = true, + HasRightTrigger = true, + HasLeftXThumbStick = true, + HasLeftYThumbStick = true, + HasRightXThumbStick = true, + HasRightYThumbStick = true, + HasBigButton = true, + HasLeftVibrationMotor = INTERNAL_haptics[which] != IntPtr.Zero, + HasRightVibrationMotor = INTERNAL_haptics[which] != IntPtr.Zero, + HasVoiceSupport = false + }; + + // Store the GUID string for this device + StringBuilder result = new StringBuilder(); + byte[] resChar = new byte[33]; // FIXME: Sort of arbitrary. + SDL.SDL_JoystickGetGUIDString( + SDL.SDL_JoystickGetGUID(thisJoystick), + resChar, + resChar.Length + ); + if (OSVersion.Equals("Linux")) + { + result.Append((char) resChar[8]); + result.Append((char) resChar[9]); + result.Append((char) resChar[10]); + result.Append((char) resChar[11]); + result.Append((char) resChar[16]); + result.Append((char) resChar[17]); + result.Append((char) resChar[18]); + result.Append((char) resChar[19]); + } + else if (OSVersion.Equals("Mac OS X")) + { + result.Append((char) resChar[0]); + result.Append((char) resChar[1]); + result.Append((char) resChar[2]); + result.Append((char) resChar[3]); + result.Append((char) resChar[16]); + result.Append((char) resChar[17]); + result.Append((char) resChar[18]); + result.Append((char) resChar[19]); + } + else if (OSVersion.Equals("Windows")) + { + bool isXInput = true; + foreach (byte b in resChar) + { + if (((char) b) != '0' && b != 0) + { + isXInput = false; + break; + } + } + if (isXInput) + { + result.Append("xinput"); + } + else + { + result.Append((char) resChar[0]); + result.Append((char) resChar[1]); + result.Append((char) resChar[2]); + result.Append((char) resChar[3]); + result.Append((char) resChar[4]); + result.Append((char) resChar[5]); + result.Append((char) resChar[6]); + result.Append((char) resChar[7]); + } + } + else + { + throw new NotSupportedException("Unhandled SDL2 platform!"); + } + INTERNAL_guids[which] = result.ToString(); + + // Initialize light bar + if ( OSVersion.Equals("Linux") && + INTERNAL_guids[which].Equals("4c05c405") ) + { + // Get all of the individual PS4 LED instances + List ledList = new List(); + string[] dirs = Directory.GetDirectories("/sys/class/leds/"); + foreach (string dir in dirs) + { + if ( dir.Contains("054C:05C4") && + dir.EndsWith("blue") ) + { + ledList.Add(dir.Substring(0, dir.LastIndexOf(':') + 1)); + } + } + // Find how many of these are already in use + int numLights = 0; + for (int i = 0; i < INTERNAL_lightBars.Length; i += 1) + { + if (!String.IsNullOrEmpty(INTERNAL_lightBars[i])) + { + numLights += 1; + } + } + // If all are not already in use, use the first unused light + if (numLights < ledList.Count) + { + INTERNAL_lightBars[which] = ledList[numLights]; + } + } + + // Print controller information to stdout. + System.Console.WriteLine( + "Controller " + which.ToString() + ": " + + SDL.SDL_GameControllerName(INTERNAL_devices[which]) + ); + } + + private static void INTERNAL_RemoveInstance(int dev) + { + int output; + if (!INTERNAL_instanceList.TryGetValue(dev, out output)) + { + // Odds are, this is controller 5+ getting removed. + return; + } + INTERNAL_instanceList.Remove(dev); + if (INTERNAL_haptics[output] != IntPtr.Zero) + { + SDL.SDL_HapticClose(INTERNAL_haptics[output]); + INTERNAL_haptics[output] = IntPtr.Zero; + } + SDL.SDL_GameControllerClose(INTERNAL_devices[output]); + INTERNAL_devices[output] = IntPtr.Zero; + INTERNAL_states[output] = new GamePadState(); + INTERNAL_guids[output] = String.Empty; + + // A lot of errors can happen here, but honestly, they can be ignored... + SDL.SDL_ClearError(); + + System.Console.WriteLine("Removed device, player: " + output.ToString()); + } + + // GetState can convert stick values to button values + private static Buttons READ_StickToButtons(Vector2 stick, Buttons left, Buttons right, Buttons up , Buttons down, float DeadZoneSize) + { + Buttons b = (Buttons) 0; + + if (stick.X > DeadZoneSize) + { + b |= right; + } + if (stick.X < -DeadZoneSize) + { + b |= left; + } + if (stick.Y > DeadZoneSize) + { + b |= up; + } + if (stick.Y < -DeadZoneSize) + { + b |= down; + } + + return b; + } + + // GetState can convert trigger values to button values + private static Buttons READ_TriggerToButton(float trigger, Buttons button, float DeadZoneSize) + { + Buttons b = (Buttons) 0; + + if (trigger > DeadZoneSize) + { + b |= button; + } + + return b; + } + + private static string[] GenStringArray() + { + string[] result = new string[GamePad.GAMEPAD_COUNT]; + for (int i = 0; i < result.Length; i += 1) + { + result[i] = String.Empty; + } + return result; + } + + #endregion + #region Private Static SDL_Surface Interop private static unsafe IntPtr INTERNAL_convertSurfaceFormat(IntPtr surface) diff --git a/src/SDL2/SDL2_KeyboardUtil.cs b/src/SDL2/SDL2_KeyboardUtil.cs new file mode 100644 index 0000000..0d18b8d --- /dev/null +++ b/src/SDL2/SDL2_KeyboardUtil.cs @@ -0,0 +1,457 @@ +#region License +/* FNA - XNA4 Reimplementation for Desktop Platforms + * Copyright 2009-2016 Ethan Lee and the MonoGame Team + * + * Released under the Microsoft Public License. + * See LICENSE for details. + */ +#endregion + +#region Using Statements +using System.Collections.Generic; + +using SDL2; +#endregion + +namespace Microsoft.Xna.Framework.Input +{ + internal static class SDL2_KeyboardUtil + { + #region Private SDL2->XNA Key Hashmaps + + /* From: http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage-collector-nirvana.aspx + * "If you use an enum type as a dictionary key, internal dictionary operations will cause boxing. + * You can avoid this by using integer keys, and casting your enum values to ints before adding + * them to the dictionary." + */ + private static Dictionary INTERNAL_keyMap; + private static Dictionary INTERNAL_scanMap; + private static Dictionary INTERNAL_xnaMap; + + #endregion + + #region Hashmap Initializer Constructor + + static SDL2_KeyboardUtil() + { + // Create the dictionaries... + INTERNAL_keyMap = new Dictionary(); + INTERNAL_scanMap = new Dictionary(); + INTERNAL_xnaMap = new Dictionary(); + + // Then fill them with known keys that match up to XNA Keys. + + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_a, Keys.A); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_b, Keys.B); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_c, Keys.C); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_d, Keys.D); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_e, Keys.E); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_f, Keys.F); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_g, Keys.G); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_h, Keys.H); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_i, Keys.I); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_j, Keys.J); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_k, Keys.K); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_l, Keys.L); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_m, Keys.M); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_n, Keys.N); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_o, Keys.O); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_p, Keys.P); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_q, Keys.Q); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_r, Keys.R); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_s, Keys.S); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_t, Keys.T); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_u, Keys.U); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_v, Keys.V); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_w, Keys.W); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_x, Keys.X); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_y, Keys.Y); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_z, Keys.Z); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_0, Keys.D0); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_1, Keys.D1); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_2, Keys.D2); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_3, Keys.D3); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_4, Keys.D4); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_5, Keys.D5); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_6, Keys.D6); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_7, Keys.D7); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_8, Keys.D8); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_9, Keys.D9); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_0, Keys.NumPad0); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_1, Keys.NumPad1); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_2, Keys.NumPad2); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_3, Keys.NumPad3); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_4, Keys.NumPad4); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_5, Keys.NumPad5); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_6, Keys.NumPad6); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_7, Keys.NumPad7); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_8, Keys.NumPad8); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_9, Keys.NumPad9); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_CLEAR, Keys.OemClear); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_DECIMAL, Keys.Decimal); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_DIVIDE, Keys.Divide); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_ENTER, Keys.Enter); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_MINUS, Keys.Subtract); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_MULTIPLY, Keys.Multiply); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_PERIOD, Keys.OemPeriod); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_KP_PLUS, Keys.Add); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F1, Keys.F1); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F2, Keys.F2); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F3, Keys.F3); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F4, Keys.F4); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F5, Keys.F5); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F6, Keys.F6); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F7, Keys.F7); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F8, Keys.F8); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F9, Keys.F9); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F10, Keys.F10); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F11, Keys.F11); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F12, Keys.F12); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F13, Keys.F13); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F14, Keys.F14); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F15, Keys.F15); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F16, Keys.F16); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F17, Keys.F17); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F18, Keys.F18); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F19, Keys.F19); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F20, Keys.F20); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F21, Keys.F21); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F22, Keys.F22); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F23, Keys.F23); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_F24, Keys.F24); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SPACE, Keys.Space); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_UP, Keys.Up); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_DOWN, Keys.Down); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LEFT, Keys.Left); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RIGHT, Keys.Right); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LALT, Keys.LeftAlt); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RALT, Keys.RightAlt); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LCTRL, Keys.LeftControl); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RCTRL, Keys.RightControl); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LGUI, Keys.LeftWindows); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RGUI, Keys.RightWindows); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LSHIFT, Keys.LeftShift); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RSHIFT, Keys.RightShift); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_APPLICATION, Keys.Apps); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SLASH, Keys.OemQuestion); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKSLASH, Keys.OemBackslash); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_LEFTBRACKET, Keys.OemOpenBrackets); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RIGHTBRACKET, Keys.OemCloseBrackets); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_CAPSLOCK, Keys.CapsLock); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_COMMA, Keys.OemComma); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_DELETE, Keys.Delete); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_END, Keys.End); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKSPACE, Keys.Back); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_RETURN, Keys.Enter); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_ESCAPE, Keys.Escape); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_HOME, Keys.Home); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_INSERT, Keys.Insert); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_MINUS, Keys.OemMinus); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_NUMLOCKCLEAR, Keys.NumLock); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAGEUP, Keys.PageUp); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAGEDOWN, Keys.PageDown); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PAUSE, Keys.Pause); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PERIOD, Keys.OemPeriod); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_EQUALS, Keys.OemPlus); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_PRINTSCREEN, Keys.PrintScreen); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_QUOTE, Keys.OemQuotes); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SCROLLLOCK, Keys.Scroll); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SEMICOLON, Keys.OemSemicolon); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_SLEEP, Keys.Sleep); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_TAB, Keys.Tab); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_BACKQUOTE, Keys.OemTilde); + INTERNAL_keyMap.Add((int) SDL.SDL_Keycode.SDLK_UNKNOWN, Keys.None); + + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_A, Keys.A); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_B, Keys.B); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_C, Keys.C); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_D, Keys.D); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_E, Keys.E); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F, Keys.F); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_G, Keys.G); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_H, Keys.H); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_I, Keys.I); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_J, Keys.J); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_K, Keys.K); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_L, Keys.L); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_M, Keys.M); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_N, Keys.N); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_O, Keys.O); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_P, Keys.P); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Q, Keys.Q); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_R, Keys.R); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_S, Keys.S); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_T, Keys.T); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_U, Keys.U); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_V, Keys.V); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_W, Keys.W); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_X, Keys.X); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Y, Keys.Y); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_Z, Keys.Z); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_0, Keys.D0); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_1, Keys.D1); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_2, Keys.D2); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_3, Keys.D3); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_4, Keys.D4); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_5, Keys.D5); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_6, Keys.D6); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_7, Keys.D7); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_8, Keys.D8); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_9, Keys.D9); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_0, Keys.NumPad0); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_1, Keys.NumPad1); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_2, Keys.NumPad2); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_3, Keys.NumPad3); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_4, Keys.NumPad4); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_5, Keys.NumPad5); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_6, Keys.NumPad6); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_7, Keys.NumPad7); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_8, Keys.NumPad8); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_9, Keys.NumPad9); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_CLEAR, Keys.OemClear); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_DECIMAL, Keys.Decimal); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_DIVIDE, Keys.Divide); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_ENTER, Keys.Enter); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_MINUS, Keys.Subtract); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY, Keys.Multiply); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_PERIOD, Keys.OemPeriod); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_KP_PLUS, Keys.Add); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F1, Keys.F1); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F2, Keys.F2); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F3, Keys.F3); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F4, Keys.F4); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F5, Keys.F5); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F6, Keys.F6); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F7, Keys.F7); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F8, Keys.F8); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F9, Keys.F9); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F10, Keys.F10); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F11, Keys.F11); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F12, Keys.F12); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F13, Keys.F13); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F14, Keys.F14); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F15, Keys.F15); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F16, Keys.F16); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F17, Keys.F17); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F18, Keys.F18); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F19, Keys.F19); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F20, Keys.F20); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F21, Keys.F21); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F22, Keys.F22); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F23, Keys.F23); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_F24, Keys.F24); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SPACE, Keys.Space); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_UP, Keys.Up); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_DOWN, Keys.Down); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LEFT, Keys.Left); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RIGHT, Keys.Right); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LALT, Keys.LeftAlt); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RALT, Keys.RightAlt); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LCTRL, Keys.LeftControl); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RCTRL, Keys.RightControl); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LGUI, Keys.LeftWindows); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RGUI, Keys.RightWindows); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LSHIFT, Keys.LeftShift); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RSHIFT, Keys.RightShift); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_APPLICATION, Keys.Apps); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SLASH, Keys.OemQuestion); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_BACKSLASH, Keys.OemBackslash); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_LEFTBRACKET, Keys.OemOpenBrackets); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RIGHTBRACKET, Keys.OemCloseBrackets); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_CAPSLOCK, Keys.CapsLock); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_COMMA, Keys.OemComma); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_DELETE, Keys.Delete); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_END, Keys.End); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_BACKSPACE, Keys.Back); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_RETURN, Keys.Enter); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_ESCAPE, Keys.Escape); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_HOME, Keys.Home); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_INSERT, Keys.Insert); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_MINUS, Keys.OemMinus); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR, Keys.NumLock); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAGEUP, Keys.PageUp); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAGEDOWN, Keys.PageDown); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PAUSE, Keys.Pause); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PERIOD, Keys.OemPeriod); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_EQUALS, Keys.OemPlus); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_PRINTSCREEN, Keys.PrintScreen); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_APOSTROPHE, Keys.OemQuotes); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SCROLLLOCK, Keys.Scroll); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SEMICOLON, Keys.OemSemicolon); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_SLEEP, Keys.Sleep); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_TAB, Keys.Tab); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_GRAVE, Keys.OemTilde); + INTERNAL_scanMap.Add((int) SDL.SDL_Scancode.SDL_SCANCODE_UNKNOWN, Keys.None); + + // Also, fill up another with the reverse, for scancode->keycode lookups + + INTERNAL_xnaMap.Add((int) Keys.A, SDL.SDL_Scancode.SDL_SCANCODE_A); + INTERNAL_xnaMap.Add((int) Keys.B, SDL.SDL_Scancode.SDL_SCANCODE_B); + INTERNAL_xnaMap.Add((int) Keys.C, SDL.SDL_Scancode.SDL_SCANCODE_C); + INTERNAL_xnaMap.Add((int) Keys.D, SDL.SDL_Scancode.SDL_SCANCODE_D); + INTERNAL_xnaMap.Add((int) Keys.E, SDL.SDL_Scancode.SDL_SCANCODE_E); + INTERNAL_xnaMap.Add((int) Keys.F, SDL.SDL_Scancode.SDL_SCANCODE_F); + INTERNAL_xnaMap.Add((int) Keys.G, SDL.SDL_Scancode.SDL_SCANCODE_G); + INTERNAL_xnaMap.Add((int) Keys.H, SDL.SDL_Scancode.SDL_SCANCODE_H); + INTERNAL_xnaMap.Add((int) Keys.I, SDL.SDL_Scancode.SDL_SCANCODE_I); + INTERNAL_xnaMap.Add((int) Keys.J, SDL.SDL_Scancode.SDL_SCANCODE_J); + INTERNAL_xnaMap.Add((int) Keys.K, SDL.SDL_Scancode.SDL_SCANCODE_K); + INTERNAL_xnaMap.Add((int) Keys.L, SDL.SDL_Scancode.SDL_SCANCODE_L); + INTERNAL_xnaMap.Add((int) Keys.M, SDL.SDL_Scancode.SDL_SCANCODE_M); + INTERNAL_xnaMap.Add((int) Keys.N, SDL.SDL_Scancode.SDL_SCANCODE_N); + INTERNAL_xnaMap.Add((int) Keys.O, SDL.SDL_Scancode.SDL_SCANCODE_O); + INTERNAL_xnaMap.Add((int) Keys.P, SDL.SDL_Scancode.SDL_SCANCODE_P); + INTERNAL_xnaMap.Add((int) Keys.Q, SDL.SDL_Scancode.SDL_SCANCODE_Q); + INTERNAL_xnaMap.Add((int) Keys.R, SDL.SDL_Scancode.SDL_SCANCODE_R); + INTERNAL_xnaMap.Add((int) Keys.S, SDL.SDL_Scancode.SDL_SCANCODE_S); + INTERNAL_xnaMap.Add((int) Keys.T, SDL.SDL_Scancode.SDL_SCANCODE_T); + INTERNAL_xnaMap.Add((int) Keys.U, SDL.SDL_Scancode.SDL_SCANCODE_U); + INTERNAL_xnaMap.Add((int) Keys.V, SDL.SDL_Scancode.SDL_SCANCODE_V); + INTERNAL_xnaMap.Add((int) Keys.W, SDL.SDL_Scancode.SDL_SCANCODE_W); + INTERNAL_xnaMap.Add((int) Keys.X, SDL.SDL_Scancode.SDL_SCANCODE_X); + INTERNAL_xnaMap.Add((int) Keys.Y, SDL.SDL_Scancode.SDL_SCANCODE_Y); + INTERNAL_xnaMap.Add((int) Keys.Z, SDL.SDL_Scancode.SDL_SCANCODE_Z); + INTERNAL_xnaMap.Add((int) Keys.D0, SDL.SDL_Scancode.SDL_SCANCODE_0); + INTERNAL_xnaMap.Add((int) Keys.D1, SDL.SDL_Scancode.SDL_SCANCODE_1); + INTERNAL_xnaMap.Add((int) Keys.D2, SDL.SDL_Scancode.SDL_SCANCODE_2); + INTERNAL_xnaMap.Add((int) Keys.D3, SDL.SDL_Scancode.SDL_SCANCODE_3); + INTERNAL_xnaMap.Add((int) Keys.D4, SDL.SDL_Scancode.SDL_SCANCODE_4); + INTERNAL_xnaMap.Add((int) Keys.D5, SDL.SDL_Scancode.SDL_SCANCODE_5); + INTERNAL_xnaMap.Add((int) Keys.D6, SDL.SDL_Scancode.SDL_SCANCODE_6); + INTERNAL_xnaMap.Add((int) Keys.D7, SDL.SDL_Scancode.SDL_SCANCODE_7); + INTERNAL_xnaMap.Add((int) Keys.D8, SDL.SDL_Scancode.SDL_SCANCODE_8); + INTERNAL_xnaMap.Add((int) Keys.D9, SDL.SDL_Scancode.SDL_SCANCODE_9); + INTERNAL_xnaMap.Add((int) Keys.NumPad0, SDL.SDL_Scancode.SDL_SCANCODE_KP_0); + INTERNAL_xnaMap.Add((int) Keys.NumPad1, SDL.SDL_Scancode.SDL_SCANCODE_KP_1); + INTERNAL_xnaMap.Add((int) Keys.NumPad2, SDL.SDL_Scancode.SDL_SCANCODE_KP_2); + INTERNAL_xnaMap.Add((int) Keys.NumPad3, SDL.SDL_Scancode.SDL_SCANCODE_KP_3); + INTERNAL_xnaMap.Add((int) Keys.NumPad4, SDL.SDL_Scancode.SDL_SCANCODE_KP_4); + INTERNAL_xnaMap.Add((int) Keys.NumPad5, SDL.SDL_Scancode.SDL_SCANCODE_KP_5); + INTERNAL_xnaMap.Add((int) Keys.NumPad6, SDL.SDL_Scancode.SDL_SCANCODE_KP_6); + INTERNAL_xnaMap.Add((int) Keys.NumPad7, SDL.SDL_Scancode.SDL_SCANCODE_KP_7); + INTERNAL_xnaMap.Add((int) Keys.NumPad8, SDL.SDL_Scancode.SDL_SCANCODE_KP_8); + INTERNAL_xnaMap.Add((int) Keys.NumPad9, SDL.SDL_Scancode.SDL_SCANCODE_KP_9); + INTERNAL_xnaMap.Add((int) Keys.OemClear, SDL.SDL_Scancode.SDL_SCANCODE_KP_CLEAR); + INTERNAL_xnaMap.Add((int) Keys.Decimal, SDL.SDL_Scancode.SDL_SCANCODE_KP_DECIMAL); + INTERNAL_xnaMap.Add((int) Keys.Divide, SDL.SDL_Scancode.SDL_SCANCODE_KP_DIVIDE); + INTERNAL_xnaMap.Add((int) Keys.Multiply, SDL.SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY); + INTERNAL_xnaMap.Add((int) Keys.Subtract, SDL.SDL_Scancode.SDL_SCANCODE_KP_MINUS); + INTERNAL_xnaMap.Add((int) Keys.Add, SDL.SDL_Scancode.SDL_SCANCODE_KP_PLUS); + INTERNAL_xnaMap.Add((int) Keys.F1, SDL.SDL_Scancode.SDL_SCANCODE_F1); + INTERNAL_xnaMap.Add((int) Keys.F2, SDL.SDL_Scancode.SDL_SCANCODE_F2); + INTERNAL_xnaMap.Add((int) Keys.F3, SDL.SDL_Scancode.SDL_SCANCODE_F3); + INTERNAL_xnaMap.Add((int) Keys.F4, SDL.SDL_Scancode.SDL_SCANCODE_F4); + INTERNAL_xnaMap.Add((int) Keys.F5, SDL.SDL_Scancode.SDL_SCANCODE_F5); + INTERNAL_xnaMap.Add((int) Keys.F6, SDL.SDL_Scancode.SDL_SCANCODE_F6); + INTERNAL_xnaMap.Add((int) Keys.F7, SDL.SDL_Scancode.SDL_SCANCODE_F7); + INTERNAL_xnaMap.Add((int) Keys.F8, SDL.SDL_Scancode.SDL_SCANCODE_F8); + INTERNAL_xnaMap.Add((int) Keys.F9, SDL.SDL_Scancode.SDL_SCANCODE_F9); + INTERNAL_xnaMap.Add((int) Keys.F10, SDL.SDL_Scancode.SDL_SCANCODE_F10); + INTERNAL_xnaMap.Add((int) Keys.F11, SDL.SDL_Scancode.SDL_SCANCODE_F11); + INTERNAL_xnaMap.Add((int) Keys.F12, SDL.SDL_Scancode.SDL_SCANCODE_F12); + INTERNAL_xnaMap.Add((int) Keys.F13, SDL.SDL_Scancode.SDL_SCANCODE_F13); + INTERNAL_xnaMap.Add((int) Keys.F14, SDL.SDL_Scancode.SDL_SCANCODE_F14); + INTERNAL_xnaMap.Add((int) Keys.F15, SDL.SDL_Scancode.SDL_SCANCODE_F15); + INTERNAL_xnaMap.Add((int) Keys.F16, SDL.SDL_Scancode.SDL_SCANCODE_F16); + INTERNAL_xnaMap.Add((int) Keys.F17, SDL.SDL_Scancode.SDL_SCANCODE_F17); + INTERNAL_xnaMap.Add((int) Keys.F18, SDL.SDL_Scancode.SDL_SCANCODE_F18); + INTERNAL_xnaMap.Add((int) Keys.F19, SDL.SDL_Scancode.SDL_SCANCODE_F19); + INTERNAL_xnaMap.Add((int) Keys.F20, SDL.SDL_Scancode.SDL_SCANCODE_F20); + INTERNAL_xnaMap.Add((int) Keys.F21, SDL.SDL_Scancode.SDL_SCANCODE_F21); + INTERNAL_xnaMap.Add((int) Keys.F22, SDL.SDL_Scancode.SDL_SCANCODE_F22); + INTERNAL_xnaMap.Add((int) Keys.F23, SDL.SDL_Scancode.SDL_SCANCODE_F23); + INTERNAL_xnaMap.Add((int) Keys.F24, SDL.SDL_Scancode.SDL_SCANCODE_F24); + INTERNAL_xnaMap.Add((int) Keys.Space, SDL.SDL_Scancode.SDL_SCANCODE_SPACE); + INTERNAL_xnaMap.Add((int) Keys.Up, SDL.SDL_Scancode.SDL_SCANCODE_UP); + INTERNAL_xnaMap.Add((int) Keys.Down, SDL.SDL_Scancode.SDL_SCANCODE_DOWN); + INTERNAL_xnaMap.Add((int) Keys.Left, SDL.SDL_Scancode.SDL_SCANCODE_LEFT); + INTERNAL_xnaMap.Add((int) Keys.Right, SDL.SDL_Scancode.SDL_SCANCODE_RIGHT); + INTERNAL_xnaMap.Add((int) Keys.LeftAlt, SDL.SDL_Scancode.SDL_SCANCODE_LALT); + INTERNAL_xnaMap.Add((int) Keys.RightAlt, SDL.SDL_Scancode.SDL_SCANCODE_RALT); + INTERNAL_xnaMap.Add((int) Keys.LeftControl, SDL.SDL_Scancode.SDL_SCANCODE_LCTRL); + INTERNAL_xnaMap.Add((int) Keys.RightControl, SDL.SDL_Scancode.SDL_SCANCODE_RCTRL); + INTERNAL_xnaMap.Add((int) Keys.LeftWindows, SDL.SDL_Scancode.SDL_SCANCODE_LGUI); + INTERNAL_xnaMap.Add((int) Keys.RightWindows, SDL.SDL_Scancode.SDL_SCANCODE_RGUI); + INTERNAL_xnaMap.Add((int) Keys.LeftShift, SDL.SDL_Scancode.SDL_SCANCODE_LSHIFT); + INTERNAL_xnaMap.Add((int) Keys.RightShift, SDL.SDL_Scancode.SDL_SCANCODE_RSHIFT); + INTERNAL_xnaMap.Add((int) Keys.Apps, SDL.SDL_Scancode.SDL_SCANCODE_APPLICATION); + INTERNAL_xnaMap.Add((int) Keys.OemQuestion, SDL.SDL_Scancode.SDL_SCANCODE_SLASH); + INTERNAL_xnaMap.Add((int) Keys.OemBackslash, SDL.SDL_Scancode.SDL_SCANCODE_BACKSLASH); + INTERNAL_xnaMap.Add((int) Keys.OemOpenBrackets, SDL.SDL_Scancode.SDL_SCANCODE_LEFTBRACKET); + INTERNAL_xnaMap.Add((int) Keys.OemCloseBrackets, SDL.SDL_Scancode.SDL_SCANCODE_RIGHTBRACKET); + INTERNAL_xnaMap.Add((int) Keys.CapsLock, SDL.SDL_Scancode.SDL_SCANCODE_CAPSLOCK); + INTERNAL_xnaMap.Add((int) Keys.OemComma, SDL.SDL_Scancode.SDL_SCANCODE_COMMA); + INTERNAL_xnaMap.Add((int) Keys.Delete, SDL.SDL_Scancode.SDL_SCANCODE_DELETE); + INTERNAL_xnaMap.Add((int) Keys.End, SDL.SDL_Scancode.SDL_SCANCODE_END); + INTERNAL_xnaMap.Add((int) Keys.Back, SDL.SDL_Scancode.SDL_SCANCODE_BACKSPACE); + INTERNAL_xnaMap.Add((int) Keys.Enter, SDL.SDL_Scancode.SDL_SCANCODE_RETURN); + INTERNAL_xnaMap.Add((int) Keys.Escape, SDL.SDL_Scancode.SDL_SCANCODE_ESCAPE); + INTERNAL_xnaMap.Add((int) Keys.Home, SDL.SDL_Scancode.SDL_SCANCODE_HOME); + INTERNAL_xnaMap.Add((int) Keys.Insert, SDL.SDL_Scancode.SDL_SCANCODE_INSERT); + INTERNAL_xnaMap.Add((int) Keys.OemMinus, SDL.SDL_Scancode.SDL_SCANCODE_MINUS); + INTERNAL_xnaMap.Add((int) Keys.NumLock, SDL.SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR); + INTERNAL_xnaMap.Add((int) Keys.PageUp, SDL.SDL_Scancode.SDL_SCANCODE_PAGEUP); + INTERNAL_xnaMap.Add((int) Keys.PageDown, SDL.SDL_Scancode.SDL_SCANCODE_PAGEDOWN); + INTERNAL_xnaMap.Add((int) Keys.Pause, SDL.SDL_Scancode.SDL_SCANCODE_PAUSE); + INTERNAL_xnaMap.Add((int) Keys.OemPeriod, SDL.SDL_Scancode.SDL_SCANCODE_PERIOD); + INTERNAL_xnaMap.Add((int) Keys.OemPlus, SDL.SDL_Scancode.SDL_SCANCODE_EQUALS); + INTERNAL_xnaMap.Add((int) Keys.PrintScreen, SDL.SDL_Scancode.SDL_SCANCODE_PRINTSCREEN); + INTERNAL_xnaMap.Add((int) Keys.OemQuotes, SDL.SDL_Scancode.SDL_SCANCODE_APOSTROPHE); + INTERNAL_xnaMap.Add((int) Keys.Scroll, SDL.SDL_Scancode.SDL_SCANCODE_SCROLLLOCK); + INTERNAL_xnaMap.Add((int) Keys.OemSemicolon, SDL.SDL_Scancode.SDL_SCANCODE_SEMICOLON); + INTERNAL_xnaMap.Add((int) Keys.Sleep, SDL.SDL_Scancode.SDL_SCANCODE_SLEEP); + INTERNAL_xnaMap.Add((int) Keys.Tab, SDL.SDL_Scancode.SDL_SCANCODE_TAB); + INTERNAL_xnaMap.Add((int) Keys.OemTilde, SDL.SDL_Scancode.SDL_SCANCODE_GRAVE); + INTERNAL_xnaMap.Add((int) Keys.None, SDL.SDL_Scancode.SDL_SCANCODE_UNKNOWN); + } + + #endregion + + #region Public SDL2<->XNA Key Conversion Methods + + public static Keys ToXNA(SDL.SDL_Keycode key) + { + Keys retVal; + if (INTERNAL_keyMap.TryGetValue((int) key, out retVal)) + { + return retVal; + } + else + { + System.Console.WriteLine("KEY MISSING FROM SDL2->XNA DICTIONARY: " + key.ToString()); + return Keys.None; + } + } + + public static Keys ToXNA(SDL.SDL_Scancode key) + { + Keys retVal; + if (INTERNAL_scanMap.TryGetValue((int) key, out retVal)) + { + return retVal; + } + else + { + System.Console.WriteLine("SCANCODE MISSING FROM SDL2->XNA DICTIONARY: " + key.ToString()); + return Keys.None; + } + } + + public static Keys KeyFromScancode(Keys scancode) + { + SDL.SDL_Scancode retVal; + if (INTERNAL_xnaMap.TryGetValue((int) scancode, out retVal)) + { + return INTERNAL_keyMap[(int) SDL.SDL_GetKeyFromScancode(retVal)]; + } + else + { + System.Console.WriteLine("SCANCODE MISSING FROM XNA->SDL2 DICTIONARY: " + scancode.ToString()); + return Keys.None; + } + } + + #endregion + } +} +