159 lines
5.9 KiB
C#
159 lines
5.9 KiB
C#
using System;
|
|
using ANX.Framework;
|
|
using ANX.Framework.Input;
|
|
using ANX.Framework.NonXNA;
|
|
using SharpDX.XInput;
|
|
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.
|
|
// For details see: http://anxframework.codeplex.com/license
|
|
|
|
namespace ANX.InputDevices.Windows.XInput
|
|
{
|
|
[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
|
|
|
|
public GamePad()
|
|
{
|
|
controller = new Controller[4];
|
|
for (int index = 0; index < controller.Length; index++)
|
|
controller[index] = new Controller((UserIndex)index);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
public GamePadState GetState(PlayerIndex playerIndex, out bool isConnected, out int packetNumber)
|
|
{
|
|
isConnected = controller[(int)playerIndex].IsConnected;
|
|
if (isConnected == false)
|
|
{
|
|
packetNumber = 0;
|
|
return emptyState;
|
|
}
|
|
|
|
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));
|
|
|
|
packetNumber = nativeState.PacketNumber;
|
|
return result;
|
|
}
|
|
|
|
public GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode, out bool isConnected,
|
|
out int packetNumber)
|
|
{
|
|
// TODO: deadZoneMode
|
|
|
|
isConnected = controller[(int)playerIndex].IsConnected;
|
|
if (isConnected == false)
|
|
{
|
|
packetNumber = 0;
|
|
return emptyState;
|
|
}
|
|
|
|
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);
|
|
|
|
var result = new GamePadState(leftThumb, rightThumb, nativeState.Gamepad.LeftTrigger * triggerRangeFactor,
|
|
nativeState.Gamepad.RightTrigger * triggerRangeFactor, FormatConverter.Translate(nativeState.Gamepad.Buttons));
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|