//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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 } } } }