Sample Code

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();
        }
    }
}