//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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.Stream; //using DarkWynter.Engine.ObjectLib; //using DarkWynter.Engine.Menus; //using Globals; #endregion /// /// Mouse event class for mapping a Mouse button/motion to an event /// public class MouseControl { // Time delay between key presses to avoid double input private int KEY_TIMER_MAX_MILLI = 10; private Stopwatch controlTimer = new Stopwatch(); private float MOUSE_ROTATION_SCALE = 0.005f; private float lastMouseX, lastMouseY; private int windowHeight, windowWidth; // Game window Height and Width for resetting the Mouse position private int lastMouseWheelPos = 0; // Position of mouse wheel on element list /// /// On click delegate type /// /// Controller boolean event arguments public delegate void OnClickHandler(ControllerBoolEventArgs args); private event OnClickHandler click; /// /// Off click delegate type /// /// Controller boolean event arguments public delegate void OnReleaseHandler(ControllerBoolEventArgs args); private event OnReleaseHandler offClick; /// /// On motion delegate type /// /// Controller vector2 event arguments public delegate void OnMotionHandler(ControllerVec2EventArgs args); private event OnMotionHandler motion; /// /// On scroll delegate type /// /// Controller integer event arguments public delegate void OnScrollHandler(ControllerIntEventArgs args); private event OnScrollHandler scroll; /// /// Type of control for this event /// public ControlType controlType; /// /// Click constructor /// /// Click control type /// Click handler /// Time delay between multiple invocations public MouseControl(ControlType type, OnClickHandler onClickHandler, int timerValue) { controlType = type; click += new OnClickHandler(onClickHandler); controlTimer.Start(); KEY_TIMER_MAX_MILLI = timerValue; } /// /// Off Click constructor /// /// Off Click control type /// On Release handler /// Time delay between multiple invocations public MouseControl(ControlType type, OnReleaseHandler onReleaseHandler, int timerValue, int x) { controlType = type; offClick += new OnReleaseHandler(onReleaseHandler); controlTimer.Start(); KEY_TIMER_MAX_MILLI = timerValue; x = 0; } /// /// Motion constructor /// /// Motion control type /// Motion handler /// Time delay between multiple invocations public MouseControl(ControlType type, OnMotionHandler onMotionHandler, int timerValue) { controlType = type; motion += new OnMotionHandler(onMotionHandler); controlTimer.Start(); KEY_TIMER_MAX_MILLI = timerValue; lastMouseX = Mouse.GetState().X; lastMouseY = Mouse.GetState().Y; } /// /// Scroll constructor /// /// Scroll control type /// Scroll handler /// Time delay between multiple invocations public MouseControl(ControlType type, OnScrollHandler onScrollHandler, int timerValue) { controlType = type; scroll += new OnScrollHandler(onScrollHandler); controlTimer.Start(); KEY_TIMER_MAX_MILLI = timerValue; lastMouseWheelPos = Mouse.GetState().ScrollWheelValue; } /// /// Update Method /// /// Updated mouse state /// Object Library /// Menu System public void Update(MouseState mouseState, ref List argObjects) { // Check double-input timer if (controlTimer.ElapsedMilliseconds > KEY_TIMER_MAX_MILLI) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Get updated window dimensions windowWidth = ControllerManager.clientSize.X; windowHeight = ControllerManager.clientSize.Y; #region Check Mouse Key States if (controlType == ControlType.Motion) { CheckMotion(ref mouseState, ref argObjects); } if (controlType == ControlType.LeftButton) { CheckLeftButton(ref mouseState, ref argObjects); } if (controlType == ControlType.RightButton) { CheckRightButton(ref mouseState, ref argObjects); } if (controlType == ControlType.MiddleButton) { CheckMiddleButton(ref mouseState, ref argObjects); } if (controlType == ControlType.ScrollWheel) { CheckScrollWheel(ref mouseState, ref argObjects); } #endregion } } private void CheckMotion(ref MouseState mouseState, ref List argObjects) { // Calculate Mouse movement since last frame // If mouse is in the window if ((mouseState.X > 0) && (mouseState.X < windowWidth - 1) && (mouseState.Y > 0) && (mouseState.Y < windowHeight - 1)) { // Find change in mouse position since last frame float diffX = mouseState.X - windowWidth / 2; float diffY = mouseState.Y - windowHeight / 2; // Scale difference Vector2 mouseRotation = new Vector2( MOUSE_ROTATION_SCALE * diffX, -MOUSE_ROTATION_SCALE * diffY ); // Set up Event ControllerVec2EventArgs args = new ControllerVec2EventArgs(mouseRotation, new Vector2(mouseState.X, mouseState.Y), ref argObjects); // Set mouse back to center of screen (eg-1st person shooter games) // Mouse.SetPosition(windowWidth / 2, windowHeight / 2); // Send delegate signals if (motion != null) motion(args); } } private void CheckMiddleButton(ref MouseState mouseState, ref List argObjects) { if (mouseState.MiddleButton == ButtonState.Pressed) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (click != null) click(new ControllerBoolEventArgs(true, ref argObjects)); } if (mouseState.MiddleButton == ButtonState.Released) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (offClick != null) offClick(new ControllerBoolEventArgs(true, ref argObjects)); } } private void CheckRightButton(ref MouseState mouseState, ref List argObjects) { if (mouseState.RightButton == ButtonState.Pressed) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (click != null) click(new ControllerBoolEventArgs(true, ref argObjects)); } if (mouseState.RightButton == ButtonState.Released) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (offClick != null) offClick(new ControllerBoolEventArgs(true, ref argObjects)); } } private void CheckLeftButton(ref MouseState mouseState, ref List argObjects) { if (mouseState.LeftButton == ButtonState.Pressed) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (click != null) click(new ControllerBoolEventArgs(true, ref argObjects)); } if (mouseState.LeftButton == ButtonState.Released) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Send event signal(s) if (offClick != null) offClick(new ControllerBoolEventArgs(true, ref argObjects)); } } private void CheckScrollWheel(ref MouseState mouseState, ref List argObjects) { if (mouseState.ScrollWheelValue != lastMouseWheelPos) { // Reset timer controlTimer.Reset(); controlTimer.Start(); // Return Wheel motion as Up=1 or Down=-1. // note: (bool) diff = dx/dt - change in position over time cast to bool // mod to (float) diff if requiring accelerometer mouse-wheel behavior int diff; if (mouseState.ScrollWheelValue > lastMouseWheelPos) {diff = 1;} else {diff = -1;} // Save State lastMouseWheelPos = mouseState.ScrollWheelValue; // Send event signal(s) if (scroll != null) scroll(new ControllerIntEventArgs(diff, ref argObjects)); } } } }