//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
// C# FAQ: How create an instance of a type using only its name
// http://en.csharp-online.net/CSharp_FAQ:_How_create_an_instance_of_a_type_using_only_its_name
namespace DarkWynter.Engine.Controllers
{
#region Using Statements
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Diagnostics;
using Microsoft.Xna.Framework.Graphics;
using System.Reflection;
#endregion
///
/// Event Publisher
/// ControllerManager requires a list of Types, which point to children of Controller
/// It creates a child controller for each Type, for each controller plugged into the system.
/// Use GetControllers to retrieve all the controllers of a particular type or a particular player.
///
public class ControllerManager
{
private List controllers;
private List controllerTypes;
private Type controllerTypeCurrent;
public int PlayerCount;
///
/// Width and height of window required for mouse to function properly.
///
public static Point clientSize;
///
/// Player must add a new controller and reset viewports.
///
/// Controller boolean event arguments
public delegate Controller OnControllerAdded(int playerNumber);
public static event OnControllerAdded onControllerAdded;
///
/// Player must add a new controller and reset viewports.
///
/// Controller boolean event arguments
public delegate Controller OnControllerRemoved(int playerNumber);
public static event OnControllerRemoved onControllerRemoved;
public ControllerManager(int screenWidth, int screenHeight, List childControllerTypes)
{
clientSize = new Point(screenWidth, screenHeight);
controllerTypes = childControllerTypes;
controllers = new List();
PlayerCount = 0;
}
///
/// Use this method to get Controllers of a particular type.
///
///
public List GetControllers(Type childControllerType)
{
List retValues = new List();
for (int i = 0; i < controllers.Count; i++)
{
if (controllers[i].GetType() == childControllerType)
{
retValues.Add(controllers[i]);
}
}
return retValues;
}
/////
///// Use this method to get Controllers from a particular player.
/////
/////
public List GetControllers(int playerNumber)
{
// Keyboard and Xbox for playerNumber = 0;
// Xbox for playerNumber 1-N
return null;
}
///
/// Checks to see if a new controller has been plugged in
/// Required method for auto-sensing new Controllers connected to the gamestate.
/// Call each frame for auto-sense controller behavior, or you might only need to search for new Controllers/Players in certain game states.
///
/// ObjectLibrary
public void Update()
{
// Get PlayerIndeciess which are already connected
List alreadyConnected = GetConnectedXBOXControllers();
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
{
// If List doesn't contain controller, create one.
if (!alreadyConnected.Contains(i))
{
CheckControllersXBOX(i);
#if !XBOX360
CheckControllersPC();
CheckControllersXBOXPC(i);
#endif
}
else if (alreadyConnected.Contains(i))
{
// Update
CheckControllersPC();
CheckControllersXBOXPC(i);
}
}
}
// Get List of existing XBOX Controller Player Indecies
private List GetConnectedXBOXControllers()
{
// Find List of already existing controllers
List alreadyConnected = new List();
for (int i = 0; i < controllers.Count; i++)
{
// If XBox or Both Controller
if (controllers[i].playerControllerType != ControllerType.PC_ONLY)
{
// If controller has been disconnected
if (!GamePad.GetState(controllers[i].playerIndex).IsConnected)
{
// Remove Controller
controllers.RemoveAt(i);
// Invoke event signal and post-decrement.
if (ControllerManager.onControllerRemoved != null)
ControllerManager.onControllerRemoved(i--);
}
else
{
// Still connected. Add to list..
alreadyConnected.Add(controllers[i].playerIndex);
}
}
}
return alreadyConnected;
}
private void CheckControllersXBOX(PlayerIndex playerIndex)
{
// Check if our gamepad is connected but not added to the list
if (GamePad.GetState(playerIndex).IsConnected)
{
// Create a controller of each type
for (int typeCount = 0; typeCount < controllerTypes.Count; typeCount++)
{
// Create controller (reflection)
Controller controllerObject = CreateController(
controllerTypes[typeCount],
new Type[] { playerIndex.GetType() },
new object[] { playerIndex }
);
}
}
}
private void CheckControllersPC()
{
#if !XBOX360
// Setup Keyboard & Mouse for player 1
if (PlayerCount == 0 && controllers.Count == 0)
{
// Create a controller of each type
for (int typeCount = 0; typeCount < controllerTypes.Count; typeCount++)
{
// Create Controller (reflection)
Controller controllerObject = CreateController(
controllerTypes[typeCount],
new Type[] { typeof(int) },
new object[] { 0 }); // HardCod3: PlayerCount = 0;
}
}
#endif
}
private void CheckControllersXBOXPC(PlayerIndex playerIndex)
{
#if !XBOX360
// If Player 1 has a controller make sure they are given the keyboard too
if (PlayerCount >= 1 && controllers[0].playerControllerType == ControllerType.XBOX_ONLY)
{
// Create a controller of each type
for (int typeCount = 0; typeCount < controllerTypes.Count; typeCount++)
{
// Create Controller (reflection)
Controller controllerObject = CreateController(
controllerTypes[typeCount],
new Type[] { typeof(int), PlayerIndex.One.GetType() },
new object[] { 0, playerIndex } // HardCod3: PlayerCount = 0; PlayerIndex =playerIndex;
);
}
if (controllers[0].playerControllerType != ControllerType.PC_ONLY)
{
controllers.RemoveRange(0, 2);
}
}
#endif
}
// Use Intellisense to create a controller of type "controllerType" with args of argTypes
public Controller CreateController(Type controllerType, Type[] argTypes, object[] args)
{
// User Supplied Type Constructor
ConstructorInfo constructorInfo = controllerType.GetConstructor(argTypes);
object controllerObject = constructorInfo.Invoke(args);
// Return or fail
if (controllerObject != null && controllerObject is Controller)
{
Controller control = controllerObject as Controller;
controllers.Add(control);
PlayerCount++;
// Signal to all registered listeners
if (ControllerManager.onControllerAdded != null)
ControllerManager.onControllerAdded(PlayerCount);
return control;
}
return null;
}
}
}