//--------------------------------------------------------------------------- // // MechCommander 2 // // UserInput Class -- Polls the state of keyboard, mouse, joystick // for this frame and stores values. // //---------------------------------------------------------------------------// // Copyright (C) Microsoft Corporation. All rights reserved. // //===========================================================================// #ifndef USERINPUT_H #define USERINPUT_H #ifndef DSTD_H #include "dstd.h" #endif #ifndef MATHFUNC_H #include "mathfunc.h" #endif #ifndef UTILITIES_H #include "Utilities.h" #endif #include #include //--------------------------------------------------------------------------- #define MC2_MOUSE_UP 0 #define MC2_MOUSE_DOWN 1 #define MOUSE_WIDTH 32 #define MAX_MOUSE_STATES 256 #define mState_MOVE 0 #define mState_MOVE_LOS 1 #define mState_RUN 2 #define mState_RUN_LOS 3 #define mState_JUMP 4 #define mState_JUMP_LOS 5 #define mState_WALKWAYPT 6 #define mState_WALKWAYPT_LOS 7 #define mState_RUNWAYPT 8 #define mState_RUNWAYPT_LOS 9 #define mState_JUMPWAYPT 10 #define mState_JUMPWAYPT_LOS 11 #define mState_LINK 12 #define mState_GENERIC_ATTACK 13 #define mState_ATTACK_LOS 14 #define mState_CURPOS_ATTACK 15 #define mState_CURPOS_ATTACK_LOS 16 #define mState_ENERGY_WEAPONS 17 #define mState_ENERGY_WEAPONS_LOS 18 #define mState_AIMED_ATTACK 19 #define mState_AIMED_ATTACK_LOS 20 #define mState_NORMAL 21 #define mState_INFO 22 #define mState_LAYMINES 23 #define mState_ROTATE_CAMERA 24 #define mState_UNCERTAIN_AIRSTRIKE 25 #define mState_AIRSTRIKE 26 #define mState_SENSORSTRIKE 27 #define mState_VEHICLE 28 #define mState_CANTVEHICLE 29 #define mState_DONT 30 #define mState_REPAIR 31 #define mState_XREPAIR 32 #define mState_EJECT 33 #define mState_XEJECT 34 #define mState_CAPTURE 35 #define mState_XCAPTURE 36 #define mState_SALVAGE 37 #define mState_XSALVAGE 38 #define mState_GUARD 39 #define mState_GUARD_LOS 39 #define mState_GUARDTOWER 40 #define mState_GUARDTOWER_LOS 41 #define mState_XMINES 42 #define mState_LOGISTICS 43 #define mState_TUTORIALS 44 #define mState_LONGRNG_ATTACK 45 #define mState_SHRTRNG_ATTACK 46 #define mState_MEDRNG_ATTACK 47 #define mState_WALK1 48 #define mState_WALKLOS1 80 #define mState_RUN1 112 #define mState_RUNLOS1 144 #define mState_JUMP1 176 #define mState_JUMPLOS1 208 #define mState_LONGRNG_LOS 240 #define mState_MEDRNG_LOS 241 #define mState_SHRTRNG_LOS 242 #define mState_NUMMOUSESTATES 243 //Add states BETWEEN this one and above!!! //Used to keep from setting cursor to STUPID!! #define mouseFrameRate 0.10 extern volatile char mc2MouseHotSpotX; extern volatile char mc2MouseHotSpotY; extern volatile char mc2MouseWidth; extern volatile char mc2MouseHeight; extern volatile bool mc2UseAsyncMouse; //Should mouse draw and update in separate thread? extern volatile bool mc2MouseThreadStarted; //Has the thread starting running yet? extern volatile MemoryPtr mc2MouseData; //--------------------------------------------------------------------------- class MouseCursorData { protected: //--------------------------------------------------------------- // Mouse textures are assumed 32x32. Animating mice are stored // on the smallest texture that will hold their shape. Thus if // have a mouse with four frames of animation it will be stored // on a 64x64. long numCursors; StaticInfo* cursorInfos; // gotta be pointer, so destructor is called before texmgr quits char mouseHS[MAX_MOUSE_STATES][2]; unsigned long numFrames[MAX_MOUSE_STATES]; float frameLengths[MAX_MOUSE_STATES]; friend class UserInput; public: MouseCursorData (void) { init(); } ~MouseCursorData (void) { destroy(); } void destroy (void); void init (void) { numCursors = 0; cursorInfos = 0; memset( mouseHS, 0, sizeof( mouseHS ) ); memset( numFrames, 0, sizeof( numFrames ) ); memset( frameLengths, 0, sizeof( frameLengths ) ); } long getNumFrames (long state) { if ((state >= 0) && (state < numCursors)) return numFrames[state]; // no animating for now return 0; } char getMouseHSX (long state) { if ((state >= 0) && (state < numCursors)) return mouseHS[state][0]; return 0; } char getMouseHSY (long state) { if ((state >= 0) && (state < numCursors)) return mouseHS[state][1]; return 0; } void initCursors (char *cursorFile); }; //--------------------------------------------------------------------------- class UserInput { protected: //-------------------- // Mouse Information float mouseXPosition; //Current Mouse X Position. float mouseYPosition; //Current Mouse Y position. long mouseXDelta; //Amount mouse has moved in x since last poll long mouseYDelta; //Amount mouse has moved in y since last poll long mouseWheelDelta; //Amount Mouse wheel has moved since last poll long leftMouseButtonState; //Mouse Current Left Button State long rightMouseButtonState; //Mouse Current Right Button State long middleMouseButtonState; //Mouse Current Middle Button State bool leftClick; //Mouse has been left clicked bool rightClick; //Mouse has been right clicked bool leftDoubleClick; //Mouse has been left double clicked bool rightDoubleClick; //Mouse has been right double clicked bool middleClick; //Mouse has been middle clicked bool middleDoubleClick; //Mouse has been middle Double Clicked bool leftMouseDrag; //Mouse is left Dragging bool rightMouseDrag; //Mouse is right Dragging bool wasLeftMouseDrag; //Mouse is left Dragging bool wasRightMouseDrag; //Mouse is right Dragging float mouseDragX; //Where we started Dragging float mouseDragY; //Where we started Dragging; float mouseDragThreshold; //Distance mouse MUST move before a drag is assumed. float mouseDblClickThreshold; //Time between clicks maximum to assume double click. float mouseLeftUpTime; //Time since last left mouse up. float mouseRightUpTime; //Time since last right mouse up. float mouseMiddleUpTime; //Time since last right mouse up. float mouseLeftHeldTime; //How long the mouse has been down float mouseRightHeldTime; //How long the mouse has been down long lastLeftMouseButtonState; //Last Left Mouse Button State long lastRightMouseButtonState; //Last Right Mouse Button State long lastMiddleMouseButtonState; //Last Middle Mouse Button State float lastMouseXPosition; //Last Mouse X Position. float lastMouseYPosition; //Last Mouse Y Position. MouseCursorData *cursors; //Stores the actual cursor data and Info bool drawTerrainPointer; //Draw an inverse project cross long mouseState; //Which cursor should I draw? long mouseFrame; //current Mouse Frame DWORD mouseTextureHandle; //current Mouse Texture handle. float mouseFrameLength; //Time in Current Mouse Frame float mouseScale; //Scale factor for cursor for depth cueing. float viewMulX; float viewAddX; float viewMulY; float viewAddY; bool leftMouseJustUp; // leftButtonUp message equivalent bool rightMouseJustUp; // right up equivalent DWORD attilaIndex; // Set to 0xffffffff if no Attila Present. public: //Need to have the mouse draw here static volatile bool drawMouse; //Should I draw the Mouse Cursor? UserInput (void) { init(); } ~UserInput (void) { destroy(); } void init (void) { mouseScale = 1.0f; mouseXPosition = mouseYPosition = 0.0; mouseXDelta = mouseYDelta = mouseWheelDelta = 0; leftClick = rightClick = middleClick = false; leftMouseButtonState = rightMouseButtonState = middleMouseButtonState = MC2_MOUSE_UP; leftMouseDrag = rightMouseDrag = false; leftDoubleClick = rightDoubleClick = middleDoubleClick = false; mouseDragThreshold = 0.0166667f; mouseDblClickThreshold = 0.2f; mouseLeftUpTime = mouseRightUpTime = mouseMiddleUpTime = 0.0; mouseDragX = mouseDragY = 0.0; lastLeftMouseButtonState = lastRightMouseButtonState = lastMiddleMouseButtonState = MC2_MOUSE_UP; lastMouseYPosition = lastMouseXPosition = 0.0; drawTerrainPointer = false; mouseState = -1; mouseFrameLength = 0.0; viewMulX = viewMulY = viewAddX = viewAddY = 0.0f; leftMouseJustUp = 0; rightMouseJustUp = 0; attilaIndex = 0xffffffff; mouseLeftHeldTime = 0.f; mouseRightHeldTime = 0.f; cursors = NULL; } void initMouseCursors (char *mouseFile); void destroy (void) { if ( cursors ) { delete cursors; cursors = NULL; } init(); } void setViewport(float mulX, float mulY, float addX, float addY) { viewMulX = mulX; viewMulY = mulY; viewAddX = addX; viewAddY = addY; } //------------------------ // Keyboard Functionality bool getKeyDown (gosEnum_KeyIndex index) { if ((gos_GetKeyStatus(index) == KEY_HELD) || (gos_GetKeyStatus(index) == KEY_PRESSED)) return true; return(false); } bool leftShift (void) { return (getKeyDown(KEY_LSHIFT)); } bool rightShift (void) { return (getKeyDown(KEY_RSHIFT)); } bool shift (void) { return (leftShift() || rightShift()); } bool leftAlt (void) { return (getKeyDown(KEY_LMENU)); } bool rightAlt (void) { return (getKeyDown(KEY_RMENU)); } bool alt (void) { return (leftAlt() || rightAlt()); } bool leftCtrl (void) { return (getKeyDown(KEY_LCONTROL)); } bool rightCtrl (void) { return (getKeyDown(KEY_RCONTROL)); } bool ctrl (void) { return (leftCtrl() || rightCtrl()); } //--------------------------------- // Mouse Functionality void setMouseDoubleClickThreshold (float time) { mouseDblClickThreshold = time; } void setMouseDragThreshold (float distance) { mouseDragThreshold = distance; } long getMouseX (void) { return float2long(mouseXPosition * viewMulX); } long getMouseY (void) { return float2long(mouseYPosition * viewMulY); } float realMouseX (void) { return (mouseXPosition * viewMulX); } float realMouseY (void) { return (mouseYPosition * viewMulY); } void setMousePos (float x, float y) { float xRes = 0.0f; float yRes = 0.0f; if ((fabs(viewMulX) > Stuff::SMALL) && (fabs(viewMulY) > Stuff::SMALL)) { xRes = x/viewMulX; yRes = y/viewMulY; } gos_SetMousePosition(xRes,yRes); } long getMouseXDelta (void) { return mouseXDelta; } long getMouseYDelta (void) { return mouseYDelta; } long getMouseWheelDelta (void) { return mouseWheelDelta; } long getMouseLeftButtonState (void) { return leftMouseButtonState; } long getMouseRightButtonState (void) { return rightMouseButtonState; } bool isLeftDrag (void) { return leftMouseDrag; } bool isRightDrag (void) { return rightMouseDrag; } bool wasLeftDrag (void) { return wasLeftMouseDrag; } bool wasRightDrag (void) { return wasRightMouseDrag; } float getMouseDragX (void) { return mouseDragX * viewMulX; } float getMouseDragY (void) { return mouseDragY * viewMulY; } bool isLeftClick (void) { return(leftClick); } bool isRightClick (void) { return(rightClick); } // bool isLeftHeld() { // return isLeftClick && lastLeftMouseButtonState == MC2_MOUSE_DOWN; // } bool isLeftDoubleClick (void) { return leftDoubleClick; } bool isRightDoubleClick (void) { return rightDoubleClick; } bool isMiddleClick (void) { return middleClick; } bool isMiddleDoubleClick (void) { return middleDoubleClick; } void setMouseCursor (long state); long getMouseCursor (void) { return (mouseState); } void setMouseFrame (long frameNum) { mouseFrame = frameNum; } long getMouseFrame (void) { return (mouseFrame); } void mouseOn (void); //Draw Mouse Cursor void mouseOff (void); //Don't Draw Mouse Cursor void pointerOn (void) { drawTerrainPointer = true; } void pointerOff (void) { drawTerrainPointer = false; } bool leftMouseReleased() { return leftMouseJustUp; } bool rightMouseReleased() { return rightMouseJustUp; } //------------------------------------------------------------------------------------ // Used to make mouse move off into distance in perspective to help depth perception void setMouseScale (float scaleFactor); //---------------------------------------------------------- // Attila Functionality. void addAttila (DWORD joyIndex) { attilaIndex = joyIndex; } float getAttilaXAxis (void) //Left/Right Scroll { float result = 0.0f; if (attilaIndex != 0xffffffff) result = gosJoystick_GetAxis(attilaIndex, JOY_XAXIS); return result; } float getAttilaYAxis (void) //Up/Down Scroll { float result = 0.0f; if (attilaIndex != 0xffffffff) result = gosJoystick_GetAxis(attilaIndex, JOY_YAXIS); return result; } float getAttilaRAxis (void) //Camera Rotation { float result = 0.0f; if (attilaIndex != 0xffffffff) result = gosJoystick_GetAxis(attilaIndex, JOY_RZAXIS); return result; } float getMouseRightHeld() { return mouseRightHeldTime; } float getMouseLeftHeld() { return mouseLeftHeldTime; } //------------------------ // Poller void update (void); void render (void); //Last thing rendered. Draws Mouse. }; extern UserInput *userInput; //--------------------------------------------------------------------------- #endif