CSC8503_Advanced_Game_Technologies / Common / Win32Mouse.cpp
Win32Mouse.cpp
Raw
#include "Win32Mouse.h"
#ifdef _WIN32

using namespace NCL;
using namespace Win32Code;

Win32Mouse::Win32Mouse(HWND &hwnd)	{
	rid.usUsagePage = HID_USAGE_PAGE_GENERIC; 
    rid.usUsage		= HID_USAGE_GENERIC_MOUSE; 
    rid.dwFlags		= RIDEV_INPUTSINK;   
    rid.hwndTarget	= hwnd;
    RegisterRawInputDevices(&rid, 1, sizeof(rid));

	setAbsolute = false;
}

void Win32Mouse::UpdateRAW(RAWINPUT* raw)	{
	if(isAwake)	{
		bool virtualDesktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) > 0;
		bool isAbsolute		= (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) > 0;

		if (isAbsolute) {
			const int screenWidth  = GetSystemMetrics(virtualDesktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
			const int screenHeight = GetSystemMetrics(virtualDesktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);

			Vector2 prevAbsolute = absolutePosition;
			absolutePosition.x = (raw->data.mouse.lLastX / (float)USHRT_MAX) * screenWidth;
			absolutePosition.y = (raw->data.mouse.lLastY / (float)USHRT_MAX) * screenHeight;

			if (setAbsolute) {
				relativePosition.x = (absolutePosition.x - prevAbsolute.x) * sensitivity;
				relativePosition.y = (absolutePosition.y - prevAbsolute.y) * sensitivity;
			}
			setAbsolute = true;
		}
		else {
			/*
			Update the absolute and relative mouse movements
			*/
			relativePosition.x += ((float)raw->data.mouse.lLastX) * sensitivity;
			relativePosition.y += ((float)raw->data.mouse.lLastY) * sensitivity;

			absolutePosition.x += (float)raw->data.mouse.lLastX;
			absolutePosition.y += (float)raw->data.mouse.lLastY;

			/*
			Bounds check the absolute position of the mouse, so it doesn't disappear off screen edges...
			*/
			absolutePosition.x = std::max(absolutePosition.x, 0.0f);
			absolutePosition.x = std::min(absolutePosition.x, absolutePositionBounds.x);

			absolutePosition.y = std::max(absolutePosition.y, 0.0f);
			absolutePosition.y = std::min(absolutePosition.y, absolutePositionBounds.y);
		}

		/*
		TODO: How framerate independent is this?
		*/
		if(raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL)	{		
			if(raw->data.mouse.usButtonData == 120) {
				frameWheel = 1;
			}
			else {
				frameWheel = -1;
			}
		}

		/*
		Oh, Microsoft...
		*/
		static int buttondowns [5] = {	RI_MOUSE_BUTTON_1_DOWN,
										RI_MOUSE_BUTTON_2_DOWN,
										RI_MOUSE_BUTTON_3_DOWN,
										RI_MOUSE_BUTTON_4_DOWN,
										RI_MOUSE_BUTTON_5_DOWN};

		static int buttonps [5] = {		RI_MOUSE_BUTTON_1_UP,
										RI_MOUSE_BUTTON_2_UP,
										RI_MOUSE_BUTTON_3_UP,
										RI_MOUSE_BUTTON_4_UP,
										RI_MOUSE_BUTTON_5_UP};
		
		for(int i = 0; i < 5; ++i) {
			if(raw->data.mouse.usButtonFlags & buttondowns[i])	{
				//The button was pressed!
				buttons[i] = true;

				/*
				If it wasn't too long ago since we last clicked, we trigger a double click!
				*/
				if(lastClickTime[i] > 0) {
					doubleClicks[i] = true;
				}

				/*
				No matter whether the mouse was double clicked or not, we reset the clicklimit
				*/
				lastClickTime[i] = clickLimit;
			}
			else if(raw->data.mouse.usButtonFlags & buttonps[i])	{
				//The button has been released!
				buttons[i]		= false;
				holdButtons[i]	= false;
			}
		}
	}
}
#endif //_WIN32