#region File Description
//-----------------------------------------------------------------------------
// InputReporterGame.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion
namespace InputReporter
{
///
/// Displays live input values for all connected controllers.
///
partial class InputReporterGame : Microsoft.Xna.Framework.Game
{
#region Image Positions
private static readonly Vector2[] connectedControllerPositions = new Vector2[4]
{
new Vector2(606f, 60f),
new Vector2(656f, 60f),
new Vector2(606f, 110f),
new Vector2(656f, 110f),
};
private static readonly Vector2[] selectedControllerPositions = new Vector2[4]
{
new Vector2(594f, 36f),
new Vector2(686f, 36f),
new Vector2(594f, 137f),
new Vector2(686f, 137f),
};
#endregion
#region Text Positions
private static readonly Vector2 titlePosition =
new Vector2(180f, 73f);
private static readonly Vector2 typeCenterPosition =
new Vector2(660f, 270f);
private static readonly Vector2 descriptionColumn1Position =
new Vector2(65f, 135f);
private static readonly Vector2 valueColumn1Position =
new Vector2(220f, 135f);
private static readonly Vector2 descriptionColumn2Position =
new Vector2(310f, 135f);
private static readonly Vector2 valueColumn2Position =
new Vector2(472f, 135f);
private static readonly Vector2 deadZoneInstructionsPosition =
new Vector2(570f, 380f);
private static readonly Vector2 exitInstructionsPosition =
new Vector2(618f, 425f);
#endregion
#region Text Colors
private static readonly Color titleColor = new Color(60, 134, 11);
private static readonly Color typeColor = new Color(38, 108, 87);
private static readonly Color descriptionColor = new Color(33, 89, 15);
private static readonly Color valueColor = new Color(38, 108, 87);
private static readonly Color disabledColor = new Color(171, 171, 171);
private static readonly Color instructionsColor = new Color(127, 130, 127);
#endregion
#region ChargeSwitch Durations
private const float deadZoneChargeSwitchDuration = 2f;
private const float exitChargeSwitchDuration = 2f;
#endregion
#region Input Data
private int selectedPlayer;
private GamePadState[] gamePadStates = new GamePadState[4];
private GamePadCapabilities[] gamePadCapabilities = new GamePadCapabilities[4];
private KeyboardState lastKeyboardState;
#endregion
#region Dead Zone Data
private GamePadDeadZone deadZone = GamePadDeadZone.IndependentAxes;
public GamePadDeadZone DeadZone
{
get { return deadZone; }
set
{
deadZone = value;
deadZoneString = "(" + deadZone.ToString() + ")";
if (dataFont != null)
{
Vector2 deadZoneStringSize =
dataFont.MeasureString(deadZoneString);
deadZoneStringPosition = new Vector2(
(float)Math.Floor(deadZoneStringCenterPosition.X -
deadZoneStringSize.X / 2f),
(float)Math.Floor(deadZoneStringCenterPosition.Y -
deadZoneStringSize.Y / 2f));
}
}
}
private string deadZoneString;
private Vector2 deadZoneStringPosition;
private Vector2 deadZoneStringCenterPosition;
#endregion
#region ChargeSwitches
private ChargeSwitchExit exitSwitch =
new ChargeSwitchExit(exitChargeSwitchDuration);
private ChargeSwitchDeadZone deadZoneSwitch =
new ChargeSwitchDeadZone(deadZoneChargeSwitchDuration);
#endregion
#region Graphics Data
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private SpriteFont titleFont;
private SpriteFont dataFont;
private SpriteFont dataActiveFont;
private SpriteFont typeFont;
private SpriteFont instructionsFont;
private SpriteFont instructionsActiveFont;
private Texture2D backgroundTexture;
private Texture2D[] connectedControllerTextures = new Texture2D[4];
private Texture2D[] selectedControllerTextures = new Texture2D[4];
private float dataSpacing;
#endregion
#region Initialization
///
/// Primary constructor.
///
public InputReporterGame()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 853;
graphics.PreferredBackBufferHeight = 480;
Content.RootDirectory = "Content";
exitSwitch.Fire += new ChargeSwitch.FireDelegate(exitSwitch_Fire);
deadZoneSwitch.Fire += new ChargeSwitch.FireDelegate(ToggleDeadZone);
}
///
/// Allows the game to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load any
/// non-graphic related content. Calling base.Initialize will enumerate through
/// any components and initialize them as well.
///
protected override void Initialize()
{
selectedPlayer = 0;
exitSwitch.Reset(exitChargeSwitchDuration);
deadZoneSwitch.Reset(deadZoneChargeSwitchDuration);
base.Initialize();
DeadZone = GamePadDeadZone.IndependentAxes;
}
#endregion
#region Graphics Load/Unload
///
/// Load your graphics content.
///
/// Which type of content to load.
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
titleFont = Content.Load("Fonts\\TitleFont");
dataFont = Content.Load("Fonts\\DataFont");
dataActiveFont = Content.Load("Fonts\\DataActiveFont");
typeFont = Content.Load("Fonts\\TypeFont");
instructionsFont = Content.Load("Fonts\\InstructionsFont");
instructionsActiveFont =
Content.Load("Fonts\\InstructionsActiveFont");
dataSpacing = (float)Math.Floor(dataFont.LineSpacing * 1.3f);
deadZoneStringCenterPosition = new Vector2(687f,
(float)Math.Floor(deadZoneInstructionsPosition.Y +
dataFont.LineSpacing * 1.7f));
backgroundTexture = Content.Load("Textures\\background");
connectedControllerTextures[0] =
Content.Load("Textures\\connected_controller1");
connectedControllerTextures[1] =
Content.Load("Textures\\connected_controller2");
connectedControllerTextures[2] =
Content.Load("Textures\\connected_controller3");
connectedControllerTextures[3] =
Content.Load("Textures\\connected_controller4");
selectedControllerTextures[0] =
Content.Load("Textures\\select_controller1");
selectedControllerTextures[1] =
Content.Load("Textures\\select_controller2");
selectedControllerTextures[2] =
Content.Load("Textures\\select_controller3");
selectedControllerTextures[3] =
Content.Load("Textures\\select_controller4");
}
#endregion
#region Updating
///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update(GameTime gameTime)
{
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Escape))
{
this.Exit();
}
if (keyboardState.IsKeyDown(Keys.Space) &&
!lastKeyboardState.IsKeyDown(Keys.Space))
{
ToggleDeadZone();
}
bool setSelectedPlayer = false; // give preference to earlier controllers
for (int i = 0; i < 4; i++)
{
gamePadStates[i] = GamePad.GetState((PlayerIndex)i, deadZone);
gamePadCapabilities[i] = GamePad.GetCapabilities((PlayerIndex)i);
if (!setSelectedPlayer && IsActiveGamePad(ref gamePadStates[i]))
{
selectedPlayer = i;
setSelectedPlayer = true;
}
}
deadZoneSwitch.Update(gameTime, ref gamePadStates[selectedPlayer]);
exitSwitch.Update(gameTime, ref gamePadStates[selectedPlayer]);
base.Update(gameTime);
lastKeyboardState = keyboardState;
}
///
/// Determines if the provided GamePadState is "active".
///
/// The GamePadState that is checked.
///
/// "Active" currently means that at least one of the buttons is being pressed.
///
/// True if "active".
private static bool IsActiveGamePad(ref GamePadState gamePadState)
{
return (gamePadState.IsConnected &&
((gamePadState.Buttons.A == ButtonState.Pressed) ||
(gamePadState.Buttons.B == ButtonState.Pressed) ||
(gamePadState.Buttons.X == ButtonState.Pressed) ||
(gamePadState.Buttons.Y == ButtonState.Pressed) ||
(gamePadState.Buttons.Start == ButtonState.Pressed) ||
(gamePadState.Buttons.Back == ButtonState.Pressed) ||
(gamePadState.Buttons.LeftShoulder == ButtonState.Pressed) ||
(gamePadState.Buttons.RightShoulder == ButtonState.Pressed) ||
(gamePadState.Buttons.LeftStick == ButtonState.Pressed) ||
(gamePadState.Buttons.RightStick == ButtonState.Pressed) ||
(gamePadState.DPad.Up == ButtonState.Pressed) ||
(gamePadState.DPad.Left == ButtonState.Pressed) ||
(gamePadState.DPad.Right == ButtonState.Pressed) ||
(gamePadState.DPad.Down == ButtonState.Pressed)));
}
#endregion
#region Drawing
///
/// This is called when the game should draw itself.
///
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black);
base.Draw(gameTime);
spriteBatch.Begin();
// draw the background
spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
// draw the connected-controller images
for (int i = 0; i < 4; i++)
{
if (gamePadStates[i].IsConnected)
{
spriteBatch.Draw(connectedControllerTextures[i],
connectedControllerPositions[i], Color.White);
}
}
// draw the selected-player texture (numeral)
spriteBatch.Draw(selectedControllerTextures[selectedPlayer],
selectedControllerPositions[selectedPlayer], Color.White);
// draw controller title
string text = InputReporterResources.Title +
((PlayerIndex)selectedPlayer).ToString();
spriteBatch.DrawString(titleFont, text, titlePosition,
titleColor);
// draw controller type
text = gamePadCapabilities[selectedPlayer].GamePadType.ToString();
Vector2 textSize = typeFont.MeasureString(text);
spriteBatch.DrawString(typeFont, text, new Vector2(
(float)Math.Floor(typeCenterPosition.X -
textSize.X / 2f),
(float)Math.Floor(typeCenterPosition.Y -
textSize.Y / 2f)),
typeColor);
// draw the data
DrawData(ref gamePadStates[selectedPlayer],
ref gamePadCapabilities[selectedPlayer]);
// draw the instructions
spriteBatch.DrawString(deadZoneSwitch.Active ? instructionsActiveFont :
instructionsFont, InputReporterResources.DeadZoneInstructions,
deadZoneInstructionsPosition, instructionsColor);
spriteBatch.DrawString(instructionsFont, deadZoneString,
deadZoneStringPosition, instructionsColor);
spriteBatch.DrawString(exitSwitch.Active ? instructionsActiveFont :
instructionsFont, InputReporterResources.ExitInstructions,
exitInstructionsPosition, instructionsColor);
spriteBatch.End();
}
///
/// Draw all data for a set of GamePad data and capabilities.
///
/// The GamePad data.
/// The GamePad capabilities.
///
/// The GamePad structures are passed by reference for speed. They are not
/// modified in this method.
///
private void DrawData(ref GamePadState gamePadState,
ref GamePadCapabilities gamePadCapabilities)
{
//
// Draw the first column of data
//
Vector2 descriptionPosition = descriptionColumn1Position;
Vector2 valuePosition = valueColumn1Position;
// draw left thumbstick data
DrawValue(InputReporterResources.LeftThumbstickX, ref descriptionPosition,
gamePadState.ThumbSticks.Left.X.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasLeftXThumbStick,
gamePadState.ThumbSticks.Left.X != 0f);
DrawValue(InputReporterResources.LeftThumbstickY, ref descriptionPosition,
gamePadState.ThumbSticks.Left.Y.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasLeftYThumbStick,
gamePadState.ThumbSticks.Left.Y != 0f);
// draw the right thumbstick data
DrawValue(InputReporterResources.RightThumbstickX, ref descriptionPosition,
gamePadState.ThumbSticks.Right.X.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasRightXThumbStick,
gamePadState.ThumbSticks.Right.X != 0f);
DrawValue(InputReporterResources.RightThumbstickY, ref descriptionPosition,
gamePadState.ThumbSticks.Right.Y.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasRightYThumbStick,
gamePadState.ThumbSticks.Right.Y != 0f);
descriptionPosition.Y += dataSpacing;
valuePosition.Y += dataSpacing;
// draw the trigger data
DrawValue(InputReporterResources.LeftTrigger, ref descriptionPosition,
gamePadState.Triggers.Left.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasLeftTrigger,
gamePadState.Triggers.Left != 0f);
DrawValue(InputReporterResources.RightTrigger, ref descriptionPosition,
gamePadState.Triggers.Right.ToString("0.000"), ref valuePosition,
gamePadCapabilities.HasRightTrigger,
gamePadState.Triggers.Right != 0f);
descriptionPosition.Y += dataSpacing;
valuePosition.Y += dataSpacing;
// draw the directional pad data
DrawValue(InputReporterResources.DPadUp, ref descriptionPosition,
(gamePadState.DPad.Up == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasDPadUpButton,
gamePadState.DPad.Up == ButtonState.Pressed);
DrawValue(InputReporterResources.DPadDown, ref descriptionPosition,
(gamePadState.DPad.Down == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasDPadDownButton,
gamePadState.DPad.Down == ButtonState.Pressed);
DrawValue(InputReporterResources.DPadLeft, ref descriptionPosition,
(gamePadState.DPad.Left == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasDPadLeftButton,
gamePadState.DPad.Left == ButtonState.Pressed);
DrawValue(InputReporterResources.DPadRight, ref descriptionPosition,
(gamePadState.DPad.Right == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasDPadRightButton,
gamePadState.DPad.Right == ButtonState.Pressed);
descriptionPosition.Y += dataSpacing;
valuePosition.Y += dataSpacing;
// draw the vibration data
if (gamePadCapabilities.HasLeftVibrationMotor)
{
if (gamePadCapabilities.HasRightVibrationMotor)
{
spriteBatch.DrawString(dataFont,
InputReporterResources.BothVibrationMotors, descriptionPosition,
descriptionColor);
}
else
{
spriteBatch.DrawString(dataFont,
InputReporterResources.LeftVibrationMotor, descriptionPosition,
descriptionColor);
}
}
else if (gamePadCapabilities.HasRightVibrationMotor)
{
spriteBatch.DrawString(dataFont,
InputReporterResources.RightVibrationMotor, descriptionPosition,
descriptionColor);
}
else
{
spriteBatch.DrawString(dataFont, InputReporterResources.NoVibration,
descriptionPosition, descriptionColor);
}
//
// Draw the second column of data
//
descriptionPosition = descriptionColumn2Position;
valuePosition = valueColumn2Position;
// draw the button data
DrawValue(InputReporterResources.A, ref descriptionPosition,
(gamePadState.Buttons.A == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasAButton,
gamePadState.Buttons.A == ButtonState.Pressed);
DrawValue(InputReporterResources.B, ref descriptionPosition,
(gamePadState.Buttons.B == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasBButton,
gamePadState.Buttons.B == ButtonState.Pressed);
DrawValue(InputReporterResources.X, ref descriptionPosition,
(gamePadState.Buttons.X == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasXButton,
gamePadState.Buttons.X == ButtonState.Pressed);
DrawValue(InputReporterResources.Y, ref descriptionPosition,
(gamePadState.Buttons.Y == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasYButton,
gamePadState.Buttons.Y == ButtonState.Pressed);
DrawValue(InputReporterResources.LeftShoulder, ref descriptionPosition,
(gamePadState.Buttons.LeftShoulder == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasLeftShoulderButton,
gamePadState.Buttons.LeftShoulder == ButtonState.Pressed);
DrawValue(InputReporterResources.RightShoulder, ref descriptionPosition,
(gamePadState.Buttons.RightShoulder == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasRightShoulderButton,
gamePadState.Buttons.RightShoulder == ButtonState.Pressed);
DrawValue(InputReporterResources.LeftStick, ref descriptionPosition,
(gamePadState.Buttons.LeftStick == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasLeftStickButton,
gamePadState.Buttons.LeftStick == ButtonState.Pressed);
DrawValue(InputReporterResources.RightStick, ref descriptionPosition,
(gamePadState.Buttons.RightStick == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasRightStickButton,
gamePadState.Buttons.RightStick == ButtonState.Pressed);
DrawValue(InputReporterResources.Start, ref descriptionPosition,
(gamePadState.Buttons.Start == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasStartButton,
gamePadState.Buttons.Start == ButtonState.Pressed);
DrawValue(InputReporterResources.Back, ref descriptionPosition,
(gamePadState.Buttons.Back == ButtonState.Pressed ?
InputReporterResources.ButtonPressed :
InputReporterResources.ButtonReleased), ref valuePosition,
gamePadCapabilities.HasBackButton,
gamePadState.Buttons.Back == ButtonState.Pressed);
descriptionPosition.Y += dataSpacing;
valuePosition.Y += dataSpacing;
// draw the packet number data
DrawValue(InputReporterResources.PacketNumber, ref descriptionPosition,
gamePadState.PacketNumber.ToString(), ref valuePosition,
gamePadCapabilities.IsConnected, false);
}
///
/// Draw a single description/value pair.
///
/// The description of the value.
/// The position of the description.
/// The value itself.
/// The position of the value.
/// If true, the value type is supported.
/// If true, the value type is active right now.
///
/// The positions are modified by this function, moving down one line.
///
private void DrawValue(string description, ref Vector2 descriptionPosition,
string value, ref Vector2 valuePosition, bool enabled, bool active)
{
spriteBatch.DrawString(dataFont, description, descriptionPosition,
enabled ? descriptionColor : disabledColor);
descriptionPosition.Y += dataSpacing;
spriteBatch.DrawString(active ? dataActiveFont : dataFont,
value, valuePosition, enabled ? valueColor : disabledColor);
valuePosition.Y += dataSpacing;
}
#endregion
#region ChargeSwitch Event Handlers
///
/// Handles the dead-zone ChargeSwitch fire event. Toggles dead zone types.
///
private void ToggleDeadZone()
{
switch (DeadZone)
{
case GamePadDeadZone.IndependentAxes:
DeadZone = GamePadDeadZone.Circular;
break;
case GamePadDeadZone.Circular:
DeadZone = GamePadDeadZone.None;
break;
case GamePadDeadZone.None:
DeadZone = GamePadDeadZone.IndependentAxes;
break;
}
}
///
/// Handles the exit ChargeSwitch fire event. Exits the application.
///
private void exitSwitch_Fire()
{
this.Exit();
}
#endregion
// #region Entry Point
// ///
// /// The main entry point for the application.
// ///
// static void Main()
// {
// using (InputReporterGame game = new InputReporterGame())
// {
// game.Run();
// }
// }
// #endregion
}
}