Here is Xbox controller input handling that I wrote for personal use to aid in rapid prototyping in XNA. More sample code is always available upon request!
//////////////////////////////////////////////////////////////////////////////////////
// file : CPlayerInput.cs
//
// author : Chase Cobb
//
// description : This class is responsible for gathering both buffered and unbuffered
// input from an xbox 360 controller
//////////////////////////////////////////////////////////////////////////////////////
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace Xbox_Input
{
class CPlayerInput
{
// This enum holds possible bit offsets for buttons
[Flags]
public enum EButtons
{
BUTTON_NONE = 0,
BUTTON_UP = 1,
BUTTON_DOWN = 2,
BUTTON_LEFT = 4,
BUTTON_RIGHT = 8,
BUTTON_A = 16,
BUTTON_B = 32,
BUTTON_X = 64,
BUTTON_Y = 128,
BUTTON_START = 256,
BUTTON_BACK = 512,
BUTTON_LEFT_SHOULDER = 1024,
BUTTON_RIGHT_SHOULDER = 2048,
}
/***********************************************************
* Private Members ****************************************/
private PlayerIndex m_eInputIndex;
private EButtons m_nCurrentState;
private EButtons m_nPreviousState;
private float m_fLeftTrigger;
private float m_fRightTrigger;
private Vector2 m_vLeftThumbstick;
private Vector2 m_vRightThumbstick;
// Constructor
public CPlayerInput(PlayerIndex eIndex)
{
m_eInputIndex = eIndex;
m_vLeftThumbstick = new Vector2();
m_vRightThumbstick = new Vector2();
}
/***********************************************************
* Propterties *********************************************/
public PlayerIndex ControllerIndex
{
get
{
return m_eInputIndex;
}
}
public float LeftTrigger
{
get
{
return m_fLeftTrigger;
}
}
public float RightTrigger
{
get
{
return m_fRightTrigger;
}
}
public Vector2 LeftThumbstick
{
get
{
return m_vLeftThumbstick;
}
}
public Vector2 RightThumbstick
{
get
{
return m_vRightThumbstick;
}
}
/***********************************************************
* Public Functions ***************************************/
///
/// Resets all input variables to unused state
///
public void FlushInput()
{
m_nCurrentState = m_nPreviousState = EButtons.BUTTON_NONE;
}
///
/// Takes in a button to and performs a buffered input check.
///
/// button to test against
/// returns true if the button was pressed this frame
public bool GetButtonPressed(EButtons eButton)
{
//if currently down and not previously down
return ((m_nCurrentState & eButton) != EButtons.BUTTON_NONE && (m_nPreviousState & eButton) == EButtons.BUTTON_NONE);
}
///
/// This input is NOT buffered - if you need buffered use GetButtonPressed
///
/// button to test against
/// true if the button passed in is currently held down
public bool GetButtonDown(EButtons eButton)
{
return ((m_nCurrentState & eButton) != EButtons.BUTTON_NONE);
}
///
/// This should be called every frame after the input has been gathered for this controller
///
public void SetPreviousState()
{
//set the previous state
m_nPreviousState = m_nCurrentState;
}
///
/// Fills out all current input
///
public bool GetCurrentState()
{
//make sure the controller is connected
if (GamePad.GetState(m_eInputIndex).IsConnected)
{
//Set the previous state to the current state
SetPreviousState();
//zero out the current button state
m_nCurrentState = EButtons.BUTTON_NONE;
//set CurrentState flags for all input this frame
GetDPad();
GetButtons();
GetTriggers();
GetThumbsticks();
//we successfully gathered our input
return true;
}
else
{
//something went wrong!
return false;
}
}
/***********************************************************
* Private Functions **************************************/
///
/// Responsible for storing D-Pad flags into the current state
///
private void GetDPad()
{
if (GamePad.GetState(m_eInputIndex).DPad.Up == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_UP;
}
if (GamePad.GetState(m_eInputIndex).DPad.Down == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_DOWN;
}
if (GamePad.GetState(m_eInputIndex).DPad.Left == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_LEFT;
}
if (GamePad.GetState(m_eInputIndex).DPad.Right == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_RIGHT;
}
}
///
/// Responsible for storing Button flags into the current state
///
private void GetButtons()
{
if (GamePad.GetState(m_eInputIndex).Buttons.A == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_A;
}
if (GamePad.GetState(m_eInputIndex).Buttons.B == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_B;
}
if (GamePad.GetState(m_eInputIndex).Buttons.X == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_X;
}
if (GamePad.GetState(m_eInputIndex).Buttons.Y == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_Y;
}
if (GamePad.GetState(m_eInputIndex).Buttons.Start == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_START;
}
if (GamePad.GetState(m_eInputIndex).Buttons.Back == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_BACK;
}
if (GamePad.GetState(m_eInputIndex).Buttons.LeftShoulder == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_LEFT_SHOULDER;
}
if (GamePad.GetState(m_eInputIndex).Buttons.RightShoulder == ButtonState.Pressed)
{
m_nCurrentState |= EButtons.BUTTON_RIGHT_SHOULDER;
}
}
///
/// Responsible for reading and storing the current trigger state.
///
private void GetTriggers()
{
m_fLeftTrigger = GamePad.GetState(m_eInputIndex).Triggers.Left;
m_fRightTrigger = GamePad.GetState(m_eInputIndex).Triggers.Right;
}
///
/// Responsible for reading and storing the current thumbstick state
///
private void GetThumbsticks()
{
m_vLeftThumbstick.X = GamePad.GetState(m_eInputIndex).ThumbSticks.Left.X;
m_vLeftThumbstick.Y = GamePad.GetState(m_eInputIndex).ThumbSticks.Left.Y;
m_vRightThumbstick.X = GamePad.GetState(m_eInputIndex).ThumbSticks.Right.X;
m_vRightThumbstick.X = GamePad.GetState(m_eInputIndex).ThumbSticks.Right.Y;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////
// file : CInputManager.cs
//
// author : Chase Cobb
//
// description : This class is responsible for determining what controller the
// player is using(PlayerIndex) and gathering their input each frame.
//////////////////////////////////////////////////////////////////////////////////////
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace Xbox_Input
{
///
/// Proper Singleton
/// Gathers all input and stores it for querying
/// Supports Xbox input unbuffered/buffered
///
class CInputManager
{
/***********************************************************
* Constants **********************************************/
private const int NUM_CONTROLLER_SLOTS = 4;
/***********************************************************
* Public Members *****************************************/
public int m_nNumberOfPlayers;
/***********************************************************
* Private Members ****************************************/
private static CInputManager instance;
private List m_cInputs;
///
/// Private constructor
///
private CInputManager()
{
m_cInputs = new List();
}
///
/// Property for accessing the instance of the input
/// manager
///
public static CInputManager GetInstance
{
get
{
if (instance == null)
{
instance = new CInputManager();
}
return instance;
}
}
/***********************************************************
* Accessors **********************************************/
public CPlayerInput GetInput(PlayerIndex nIndex)
{
if ((int)nIndex >= 0 && (int)nIndex < m_nNumberOfPlayers)
return m_cInputs[(int)nIndex];
return null;
}
/***********************************************************
* Public Functions ***************************************/
///
/// This function will tell us the index of the controller joining the game.
///
/// The index of the controller currently joining
public int FindController()
{
//iterate all unused controller indices for the player joining the game
//when a controller is added increase the number of players
for (int i = 0; i < NUM_CONTROLLER_SLOTS; ++i)
{
if (GamePad.GetState((PlayerIndex)i).IsConnected)
{
if (GamePad.GetState((PlayerIndex)i).Buttons.Start == ButtonState.Pressed)
{
//add new controller
CPlayerInput newInput = new CPlayerInput((PlayerIndex)i);
m_cInputs.Add(newInput);
++m_nNumberOfPlayers;
//return a handle to its index in the list of CPlayerInput
return m_nNumberOfPlayers - 1;
}
}
}
//something went wrong!
return -1;
}
///
/// This function will remove the requested controller
/// and decrease the number of players being tracked
///
/// Index handle to remove
public void RemoveController(int index)
{
//is this a valid index?
if (index < m_cInputs.Count && index >= 0)
{
m_cInputs.RemoveAt(index);
--m_nNumberOfPlayers;
}
}
///
/// should be called every frame before any input is handled
///
public bool GetCurrentInputState()
{
//return false if any of the inputs.GetCurrentState() returns false
return m_cInputs.All(x => x.GetCurrentState() == true);
}
///
/// should be called every frame after input has been collected and handled
///
public void SetPreviousInputState()
{
foreach (CPlayerInput input in m_cInputs)
{
input.SetPreviousState();
}
}
///
/// This will flush the input currently stored in all CPlayerInput objects
///
public void FlushAllInput()
{
//for each active CPlayerInput object call FlushInput()
foreach (CPlayerInput input in m_cInputs)
{
input.FlushInput();
}
}
///
/// This will flush the input currently stored in CPlayerInput object for the passed in index
///
/// index of the player needing their input flushed
public void FlushCPlayerInput(int playerIndex)
{
//flu-flush it real good!
m_cInputs[playerIndex].FlushInput();
}
}
}