Further refactoring of the XInput InputDevices, fixed some stuff and working on implementing it 100%

This commit is contained in:
SND\AstrorEnales_cp 2012-08-31 21:45:50 +00:00
parent 2745521141
commit c9aa5eb707
8 changed files with 290 additions and 223 deletions

View File

@ -44,6 +44,7 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("ANX.Framework.Windows.XAudio")]
[assembly: InternalsVisibleTo("ANX.InputSystem.Recording")]
[assembly: InternalsVisibleTo("ANX.InputDevices.PsVita")]
[assembly: InternalsVisibleTo("ANX.InputDevices.Windows.XInput")]
[assembly: InternalsVisibleTo("ANX.PlatformSystem.Windows")]
[assembly: InternalsVisibleTo("ANX.PlatformSystem.Linux")]
[assembly: InternalsVisibleTo("ANX.PlatformSystem.Metro")]

View File

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ANX.Framework.Input;
using ANX.Framework.NonXNA.Development;
using SharpDX.XInput;
using Key = SharpDX.DirectInput.Key;
@ -10,6 +10,9 @@ using Key = SharpDX.DirectInput.Key;
namespace ANX.InputDevices.Windows.XInput
{
[PercentageComplete(80)]
[TestState(TestStateAttribute.TestState.InProgress)]
[Developer("AstrorEnales")]
internal static class FormatConverter
{
private static Dictionary<GamepadButtonFlags, Buttons> gamePadButtonsMap;
@ -243,19 +246,6 @@ namespace ANX.InputDevices.Windows.XInput
}
#endregion
#region Translate (KeyboardState)
public static KeyboardState Translate(SharpDX.DirectInput.KeyboardState keyboardState)
{
int keyCount = keyboardState.PressedKeys.Count;
Keys[] keys = new Keys[keyCount];
for (int i = 0; i < keyCount; i++)
keys[i] = Translate(keyboardState.PressedKeys[i]);
return new KeyboardState(keys);
}
#endregion
#region Translate (GamepadButtonFlags)
public static Buttons Translate(SharpDX.XInput.GamepadButtonFlags buttons)
{
@ -266,5 +256,30 @@ namespace ANX.InputDevices.Windows.XInput
return tb;
}
#endregion
#region Translate (DeviceSubType)
public static GamePadType Translate(SharpDX.XInput.DeviceSubType type)
{
switch (type)
{
case DeviceSubType.ArcadeStick:
return GamePadType.ArcadeStick;
case DeviceSubType.DancePad:
return GamePadType.DancePad;
case DeviceSubType.DrumKit:
return GamePadType.DrumKit;
case DeviceSubType.FlightSick:
return GamePadType.FlightStick;
case DeviceSubType.Gamepad:
return GamePadType.GamePad;
case DeviceSubType.Guitar:
return GamePadType.Guitar;
case DeviceSubType.Wheel:
return GamePadType.Wheel;
}
return GamePadType.Unknown;
}
#endregion
}
}

View File

@ -1,11 +1,9 @@
#region Using Statements
using System;
using ANX.Framework;
using ANX.Framework.Input;
using ANX.Framework.NonXNA;
using SharpDX.XInput;
#endregion // Using Statements
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
@ -13,99 +11,148 @@ using SharpDX.XInput;
namespace ANX.InputDevices.Windows.XInput
{
public class GamePad : IGamePad
{
#region Private Members
private Controller[] controller;
private const float thumbstickRangeFactor = 1.0f / short.MaxValue;
[PercentageComplete(90)]
[TestState(TestStateAttribute.TestState.InProgress)]
[Developer("AstrorEnales")]
public class GamePad : IGamePad
{
#region Private
private Controller[] controller;
private const float thumbstickRangeFactor = 1f / short.MaxValue;
private const float triggerRangeFactor = 1f / byte.MaxValue;
private GamePadCapabilities emptyCaps;
private GamePadState emptyState;
#endregion
#endregion // Private Members
public GamePad()
{
controller = new Controller[4];
for (int index = 0; index < controller.Length; index++)
controller[index] = new Controller((UserIndex)index);
}
public GamePad()
{
controller = new Controller[4];
controller[0] = new Controller(UserIndex.One);
controller[1] = new Controller(UserIndex.Two);
controller[2] = new Controller(UserIndex.Three);
controller[3] = new Controller(UserIndex.Four);
}
public GamePadCapabilities GetCapabilities(PlayerIndex playerIndex)
{
Capabilities result;
GamePadCapabilities returnres;
//SharpDX.XInput.Capabilities = new SharpDX.XInput.Capabilities();
try
{
result = controller[(int)playerIndex].GetCapabilities(DeviceQueryType.Gamepad);
returnres = new GamePadCapabilities();
public GamePadCapabilities GetCapabilities(PlayerIndex playerIndex)
{
try
{
Capabilities nativeCaps = controller[(int)playerIndex].GetCapabilities(DeviceQueryType.Gamepad);
return new GamePadCapabilities()
{
GamePadType = FormatConverter.Translate(nativeCaps.SubType),
IsConnected = controller[(int)playerIndex].IsConnected,
HasAButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.A) != 0,
HasBackButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.Back) != 0,
HasBButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.B) != 0,
HasBigButton = false, // TODO
HasDPadDownButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0,
HasDPadLeftButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0,
HasDPadRightButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0,
HasDPadUpButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0,
HasLeftShoulderButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.LeftShoulder) != 0,
HasRightShoulderButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.RightShoulder) != 0,
HasLeftStickButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.LeftThumb) != 0,
HasRightStickButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.RightThumb) != 0,
HasStartButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.Start) != 0,
HasXButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.X) != 0,
HasYButton = (nativeCaps.Gamepad.Buttons & GamepadButtonFlags.Y) != 0,
HasLeftVibrationMotor = false,
HasRightVibrationMotor = false, // TODO
HasVoiceSupport = false, // TODO
HasRightXThumbStick = false, // TODO
HasRightYThumbStick = false, // TODO
HasLeftXThumbStick = false, // TODO
HasLeftYThumbStick = false, // TODO
HasLeftTrigger = false, // TODO
HasRightTrigger = false, // TODO
};
}
catch
{
return emptyCaps;
}
}
}
catch (Exception)
{
public GamePadState GetState(PlayerIndex playerIndex, out bool isConnected, out int packetNumber)
{
isConnected = controller[(int)playerIndex].IsConnected;
if (isConnected == false)
{
packetNumber = 0;
return emptyState;
}
returnres = new GamePadCapabilities();
} return returnres;
}
State nativeState = controller[(int)playerIndex].GetState();
var result = new GamePadState(
new Vector2(nativeState.Gamepad.LeftThumbX, nativeState.Gamepad.LeftThumbY) * thumbstickRangeFactor,
new Vector2(nativeState.Gamepad.RightThumbX, nativeState.Gamepad.RightThumbY) * thumbstickRangeFactor,
nativeState.Gamepad.LeftTrigger * triggerRangeFactor, nativeState.Gamepad.RightTrigger * triggerRangeFactor,
FormatConverter.Translate(nativeState.Gamepad.Buttons));
public GamePadState GetState(PlayerIndex playerIndex, out bool isConnected, out int packetNumber)
{
State result;
GamePadState returnres;
if(controller[(int)playerIndex].IsConnected)
{
result = controller[(int)playerIndex].GetState();
//returnres = new GamePadCapabilities(result.Type,result.Gamepad.Buttons.)
returnres = new GamePadState(new Vector2(result.Gamepad.LeftThumbX * thumbstickRangeFactor, result.Gamepad.LeftThumbY * thumbstickRangeFactor), new Vector2(result.Gamepad.RightThumbX * thumbstickRangeFactor, result.Gamepad.RightThumbY * thumbstickRangeFactor), (float)result.Gamepad.LeftTrigger, (float)result.Gamepad.RightTrigger, FormatConverter.Translate(result.Gamepad.Buttons));
packetNumber = result.PacketNumber;
isConnected = true;
}
else
{
isConnected = false;
packetNumber = 0;
returnres = new GamePadState();
}
packetNumber = nativeState.PacketNumber;
return result;
}
public GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode, out bool isConnected,
out int packetNumber)
{
// TODO: deadZoneMode
return returnres;
}
isConnected = controller[(int)playerIndex].IsConnected;
if (isConnected == false)
{
packetNumber = 0;
return emptyState;
}
public GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode, out bool isConnected, out int packetNumber)
{
throw new NotImplementedException();
}
State nativeState = controller[(int)playerIndex].GetState();
Vector2 leftThumb = ConvertThumbStick(nativeState.Gamepad.LeftThumbX, nativeState.Gamepad.LeftThumbY,
SharpDX.XInput.Gamepad.LeftThumbDeadZone, deadZoneMode);
Vector2 rightThumb = ConvertThumbStick(nativeState.Gamepad.RightThumbX, nativeState.Gamepad.RightThumbY,
SharpDX.XInput.Gamepad.LeftThumbDeadZone, deadZoneMode);
public bool SetVibration(PlayerIndex playerIndex, float leftMotor, float rightMotor)
{
short left;
short right;
if (Math.Abs(leftMotor)>1)
{
left = 1;
}
else
{
left = Convert.ToInt16(Math.Abs(leftMotor) * short.MaxValue);
}
if (Math.Abs(rightMotor) > 1)
{
right = 1;
}
else
{
right = Convert.ToInt16(Math.Abs(rightMotor) * short.MaxValue);
}
var result = new GamePadState(leftThumb, rightThumb, nativeState.Gamepad.LeftTrigger * triggerRangeFactor,
nativeState.Gamepad.RightTrigger * triggerRangeFactor, FormatConverter.Translate(nativeState.Gamepad.Buttons));
if (controller[(int)playerIndex].IsConnected)
{
Vibration vib = new Vibration();
vib.LeftMotorSpeed = left;
vib.RightMotorSpeed = right;
controller[(int)playerIndex].SetVibration(vib);
return true;
}
return false;
packetNumber = nativeState.PacketNumber;
return result;
}
}
}
public bool SetVibration(PlayerIndex playerIndex, float leftMotor, float rightMotor)
{
if (controller[(int)playerIndex].IsConnected == false)
return false;
var vib = new Vibration()
{
LeftMotorSpeed = (short)((Math.Abs(leftMotor) > 1) ? 1 : Math.Abs(leftMotor) * short.MaxValue),
RightMotorSpeed = (short)((Math.Abs(rightMotor) > 1) ? 1 : Math.Abs(rightMotor) * short.MaxValue),
};
controller[(int)playerIndex].SetVibration(vib);
return true;
}
private Vector2 ConvertThumbStick(int x, int y, int deadZone, GamePadDeadZone deadZoneMode)
{
int deadZoneSquare = deadZone * deadZone;
if (deadZoneMode == GamePadDeadZone.IndependentAxes)
{
if (x * x < deadZoneSquare)
x = 0;
if (y * y < deadZoneSquare)
y = 0;
}
else if (deadZoneMode == GamePadDeadZone.Circular)
{
if ((x * x) + (y * y) < deadZoneSquare)
{
x = 0;
y = 0;
}
}
return new Vector2(x < 0 ? -((float)x / (float)short.MinValue) : (float)x / (float)short.MaxValue,
y < 0 ? -((float)y / (float)short.MinValue) : (float)y / (float)short.MaxValue);
}
}
}

View File

@ -1,5 +1,6 @@
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.InputSystem;
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
@ -7,6 +8,9 @@ using ANX.Framework.NonXNA.InputSystem;
namespace ANX.InputDevices.Windows.XInput
{
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.Tested)]
[Developer("AstrorEnales")]
public class GamePadCreator : IGamePadCreator
{
public string Name

View File

@ -1,9 +1,9 @@
#region Using Statements
using System;
using ANX.Framework;
using ANX.Framework.Input;
using ANX.Framework.NonXNA;
using SharpDX.DirectInput;
using DXKeyboard = SharpDX.DirectInput.Keyboard;
#endregion // Using Statements
using DInput = SharpDX.DirectInput;
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
@ -11,71 +11,82 @@ using DXKeyboard = SharpDX.DirectInput.Keyboard;
namespace ANX.InputDevices.Windows.XInput
{
public class Keyboard : IKeyboard
{
#region Private Members
private DirectInput directInput;
private DXKeyboard nativeKeyboard;
private KeyboardState nativeState;
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.InProgress)]
[Developer("AstrorEnales")]
public class Keyboard : IKeyboard
{
#region Private
private DInput.DirectInput directInput;
private DInput.Keyboard nativeKeyboard;
private DInput.KeyboardState nativeState;
private IntPtr windowHandle;
private KeyboardState emptyState;
#endregion
#endregion // Private Members
public IntPtr WindowHandle
{
get { return windowHandle; }
set
{
if (windowHandle != value)
{
windowHandle = value;
nativeKeyboard.Unacquire();
nativeKeyboard.SetCooperativeLevel(WindowHandle,
DInput.CooperativeLevel.NonExclusive | DInput.CooperativeLevel.Background);
nativeKeyboard.Acquire();
}
}
}
public IntPtr WindowHandle
{
get;
set;
}
public Keyboard()
{
emptyState = new KeyboardState(new Keys[0]);
public Keyboard()
{
this.nativeState = new KeyboardState();
}
nativeState = new DInput.KeyboardState();
directInput = new DInput.DirectInput();
nativeKeyboard = new DInput.Keyboard(directInput);
nativeKeyboard.Acquire();
}
public Framework.Input.KeyboardState GetState(Framework.PlayerIndex playerIndex)
{
//TODO: prevent new
/// <summary>
/// Only available on XBox, behaviour regarding MSDN: empty keystate
/// </summary>
public KeyboardState GetState(PlayerIndex playerIndex)
{
return emptyState;
}
// only available on XBox, behaviour regarding MSDN: empty keystate
public KeyboardState GetState()
{
if (WindowHandle == IntPtr.Zero)
return emptyState;
return new Framework.Input.KeyboardState(new Framework.Input.Keys[0]);
}
nativeKeyboard.GetCurrentState(ref nativeState);
public Framework.Input.KeyboardState GetState()
{
if (this.nativeKeyboard == null && this.WindowHandle != null && this.WindowHandle != IntPtr.Zero)
{
this.directInput = new DirectInput();
this.nativeKeyboard = new DXKeyboard(this.directInput);
this.nativeKeyboard.SetCooperativeLevel(this.WindowHandle, CooperativeLevel.NonExclusive | CooperativeLevel.Background);
this.nativeKeyboard.Acquire();
}
int keyCount = nativeState.PressedKeys.Count;
Keys[] keys = new Keys[keyCount];
for (int i = 0; i < keyCount; i++)
keys[i] = FormatConverter.Translate(nativeState.PressedKeys[i]);
if (this.nativeKeyboard != null)
{
nativeKeyboard.GetCurrentState(ref this.nativeState);
if (this.nativeState.PressedKeys.Count > 0)
{
return FormatConverter.Translate(this.nativeState);
}
}
return new KeyboardState(keys);
}
return new Framework.Input.KeyboardState(new Framework.Input.Keys[0]);
}
public void Dispose()
{
if (nativeKeyboard != null)
{
nativeKeyboard.Unacquire();
nativeKeyboard.Dispose();
nativeKeyboard = null;
}
public void Dispose()
{
if (this.nativeKeyboard != null)
{
this.nativeKeyboard.Unacquire();
this.nativeKeyboard.Dispose();
this.nativeKeyboard = null;
}
if (this.directInput != null)
{
this.directInput.Dispose();
this.directInput = null;
}
}
}
if (directInput != null)
{
directInput.Dispose();
directInput = null;
}
}
}
}

View File

@ -1,5 +1,6 @@
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.InputSystem;
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
@ -7,6 +8,9 @@ using ANX.Framework.NonXNA.InputSystem;
namespace ANX.InputDevices.Windows.XInput
{
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.Tested)]
[Developer("AstrorEnales")]
public class KeyboardCreator : IKeyboardCreator
{
public string Name

View File

@ -1,91 +1,72 @@
#region Using Statements
using System;
using ANX.Framework.NonXNA;
using ANX.Framework.Input;
using SharpDX.DirectInput;
using System.Runtime.InteropServices;
using ANX.Framework;
#endregion // Using Statements
using ANX.Framework.Input;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development;
using DInput = SharpDX.DirectInput;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license
using MouseX = SharpDX.DirectInput.Mouse;
namespace ANX.InputDevices.Windows.XInput
{
class Mouse : IMouse
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.InProgress)]
[Developer("AstrorEnales")]
public class Mouse : IMouse
{
#region Interop
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref Point lpPoint);
private DInput.DirectInput directInput;
private DInput.Mouse mouse;
[DllImport("user32.dll")]
static extern void SetCursorPos(int x, int y);
[DllImport("user32.dll")]
static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint);
#endregion // Interop
#region Private Members
private DirectInput directInput;
private MouseX mouse;
#endregion // Private Members
public IntPtr WindowHandle
{
get;
set;
}
public IntPtr WindowHandle { get; set; }
public Mouse()
{
this.directInput = new DirectInput();
this.mouse = new MouseX(this.directInput);
this.mouse.Properties.AxisMode = DeviceAxisMode.Absolute;
this.mouse.Acquire();
directInput = new DInput.DirectInput();
mouse = new DInput.Mouse(directInput);
mouse.Properties.AxisMode = DInput.DeviceAxisMode.Absolute;
mouse.Acquire();
}
public ANX.Framework.Input.MouseState GetState()
{
var state = this.mouse.GetCurrentState();
public MouseState GetState()
{
var state = this.mouse.GetCurrentState();
Point cursorPos = new Point();
GetCursorPos(ref cursorPos);
if (WindowHandle != IntPtr.Zero)
{
ScreenToClient(WindowHandle, ref cursorPos);
}
Point cursorPos = new Point();
GetCursorPos(ref cursorPos);
if (WindowHandle != IntPtr.Zero)
ScreenToClient(WindowHandle, ref cursorPos);
state.X = cursorPos.X;
state.Y = cursorPos.Y;
ButtonState left = state.Buttons[0] ? ButtonState.Pressed : ButtonState.Released;
ButtonState middle = state.Buttons[1] ? ButtonState.Pressed : ButtonState.Released;
ButtonState right = state.Buttons[2] ? ButtonState.Pressed : ButtonState.Released;
ButtonState x1 = state.Buttons[3] ? ButtonState.Pressed : ButtonState.Released;
ButtonState x2 = state.Buttons[4] ? ButtonState.Pressed : ButtonState.Released;
ButtonState left = new ButtonState();
ButtonState middle = new ButtonState();
ButtonState right = new ButtonState();
ButtonState x1 = new ButtonState();
ButtonState x2 = new ButtonState();
if(state.Buttons[0]){left=ButtonState.Pressed;}
if(state.Buttons[1]){middle=ButtonState.Pressed;}
if(state.Buttons[2]){right=ButtonState.Pressed;}
if(state.Buttons[3]){x1=ButtonState.Pressed;}
if(state.Buttons[4]){x2=ButtonState.Pressed;}
return new ANX.Framework.Input.MouseState(state.X,state.Y,state.Z,left,middle,right,x1,x2);
}
return new MouseState(cursorPos.X, cursorPos.Y, state.Z, left, middle, right, x1, x2);
}
public void SetPosition(int x, int y)
{
Point currentPosition = new Point(x, y);
GetCursorPos(ref currentPosition);
if (WindowHandle != IntPtr.Zero)
{
ScreenToClient(WindowHandle, ref currentPosition);
}
ClientToScreen(WindowHandle, ref currentPosition);
SetCursorPos(currentPosition.X, currentPosition.Y);
}
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref Point lpPoint);
[DllImport("user32.dll")]
static extern void SetCursorPos(int x, int y);
[DllImport("user32.dll")]
static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint);
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);
}
}

View File

@ -1,5 +1,6 @@
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.InputSystem;
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
@ -7,6 +8,9 @@ using ANX.Framework.NonXNA.InputSystem;
namespace ANX.InputDevices.Windows.XInput
{
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.Tested)]
[Developer("AstrorEnales")]
public class MouseCreator : IMouseCreator
{
public string Name