//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine.Controllers
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Diagnostics;
using DarkWynter.Engine.ObjectLib;
using DarkWynter.Engine.Menus;
using Globals;
#endregion
///
/// Xbox analog event class for mapping an analog button/motion to an event
///
public class XboxAnalogControl
{
private float GAMEPAD_ROTATION_SCALE_Y = 0.03f;
private float GAMEPAD_ROTATION_SCALE_X = 0.03f;
// Time delay between key presses to avoid double input
private int KEY_TIMER_MAX_MILLI = 100;
private Stopwatch controlTimer = new Stopwatch();
///
/// On stick delegate type
///
/// Controller vector2 event arguments
public delegate void OnStickHandler(ControllerVec2EventArgs args);
private event OnStickHandler stick;
///
/// On trigger delegate type
///
/// Controller float event arguments
public delegate void OnTriggerHandler(ControllerFloatEventArgs args);
private event OnTriggerHandler trigger;
///
/// Type of control for this event
///
public Enums_Engine.XboxAnalogControlType controlType;
///
/// Stick constructor
///
/// Stick control type
/// Stick handler
/// Time delay between multiple invocations
public XboxAnalogControl(Enums_Engine.XboxAnalogControlType type, OnStickHandler onStickHandler, int timerValue)
{
controlType = type;
controlTimer.Start();
KEY_TIMER_MAX_MILLI = timerValue;
stick += new OnStickHandler(onStickHandler);
}
///
/// Trigger constructor
///
/// Trigger control type
/// Trigger handler
/// Time delay between multiple invocations
public XboxAnalogControl(Enums_Engine.XboxAnalogControlType type, OnTriggerHandler onTriggerHandler, int timerValue)
{
controlType = type;
controlTimer.Start();
KEY_TIMER_MAX_MILLI = timerValue;
trigger += new OnTriggerHandler(onTriggerHandler);
}
///
/// Update Method
///
/// Updated game pad state
/// Object Library
/// Menu System
public void Update(GamePadState gamePadState, ref ObjectLibrary objectLibrary, ref MenuSystem menuSystem)
{
// Check double-input timer
if (controlTimer.ElapsedMilliseconds > KEY_TIMER_MAX_MILLI)
{
// Reset timer
controlTimer.Reset();
controlTimer.Start();
#region JoySticks
if (controlType == Enums_Engine.XboxAnalogControlType.LEFT_STICK)
{
if (stick != null)
{
// Store sign (+/-) of input
int xSign = (int)(gamePadState.ThumbSticks.Right.X / Math.Abs(gamePadState.ThumbSticks.Right.X));
int ySign = (int)(gamePadState.ThumbSticks.Right.Y / Math.Abs(gamePadState.ThumbSticks.Right.Y));
// Calc motion by squaring input (x^2 input curve)
Vector2 stickRotation = new Vector2(
GAMEPAD_ROTATION_SCALE_X * (gamePadState.ThumbSticks.Right.X * gamePadState.ThumbSticks.Right.X) * xSign,
GAMEPAD_ROTATION_SCALE_Y * (gamePadState.ThumbSticks.Right.Y * gamePadState.ThumbSticks.Right.Y) * ySign);
stick(new ControllerVec2EventArgs(stickRotation, ref objectLibrary, ref menuSystem));
}
}
else if (controlType == Enums_Engine.XboxAnalogControlType.RIGHT_STICK)
{
if (stick != null)
{
// Store sign (+/-) of input
int xSign = (int)(gamePadState.ThumbSticks.Right.X / Math.Abs(gamePadState.ThumbSticks.Right.X));
int ySign = (int)(gamePadState.ThumbSticks.Right.Y / Math.Abs(gamePadState.ThumbSticks.Right.Y));
// Calc motion by squaring input (x^2 input curve)
Vector2 stickRotation = new Vector2(
GAMEPAD_ROTATION_SCALE_X * (gamePadState.ThumbSticks.Right.X * gamePadState.ThumbSticks.Right.X) * xSign,
GAMEPAD_ROTATION_SCALE_Y * (gamePadState.ThumbSticks.Right.Y * gamePadState.ThumbSticks.Right.Y) * ySign);
stick(new ControllerVec2EventArgs(stickRotation, ref objectLibrary, ref menuSystem));
}
}
#endregion
#region Triggers
else if (controlType == Enums_Engine.XboxAnalogControlType.LEFT_TRIGGER)
{
if (stick != null)
{
trigger(new ControllerFloatEventArgs(gamePadState.Triggers.Left, ref objectLibrary, ref menuSystem));
}
}
else if (controlType == Enums_Engine.XboxAnalogControlType.RIGHT_TRIGGER)
{
if (stick != null)
{
trigger(new ControllerFloatEventArgs(gamePadState.Triggers.Right, ref objectLibrary, ref menuSystem));
}
}
#endregion
}
}
}
}