/src/ois/src/win32/Win32Mouse.cpp
C++ | 216 lines | 153 code | 26 blank | 37 comment | 36 complexity | 594a5e8897797966a4e04afab8653d9f MD5 | raw file
1/* 2The zlib/libpng License 3 4Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) 5 6This software is provided 'as-is', without any express or implied warranty. In no event will 7the authors be held liable for any damages arising from the use of this software. 8 9Permission is granted to anyone to use this software for any purpose, including commercial 10applications, and to alter it and redistribute it freely, subject to the following 11restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not claim that 14 you wrote the original software. If you use this software in a product, 15 an acknowledgment in the product documentation would be appreciated but is 16 not required. 17 18 2. Altered source versions must be plainly marked as such, and must not be 19 misrepresented as being the original software. 20 21 3. This notice may not be removed or altered from any source distribution. 22*/ 23#include "win32/Win32Mouse.h" 24#include "win32/Win32InputManager.h" 25#include "OISException.h" 26#include "OISEvents.h" 27 28using namespace OIS; 29 30//--------------------------------------------------------------------------------------------------// 31Win32Mouse::Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings ) 32 : Mouse(creator->inputSystemName(), buffered, 0, creator) 33{ 34 mMouse = 0; 35 mDirectInput = pDI; 36 coopSetting = coopSettings; 37 mHwnd = 0; 38 39 static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(true); 40} 41 42//--------------------------------------------------------------------------------------------------// 43void Win32Mouse::_initialize() 44{ 45 DIPROPDWORD dipdw; 46 47 //Clear old state 48 mState.clear(); 49 50 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 51 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 52 dipdw.diph.dwObj = 0; 53 dipdw.diph.dwHow = DIPH_DEVICE; 54 dipdw.dwData = MOUSE_DX_BUFFERSIZE; 55 56 if( FAILED(mDirectInput->CreateDevice(GUID_SysMouse, &mMouse, NULL)) ) 57 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to create device" ); 58 59 if( FAILED(mMouse->SetDataFormat(&c_dfDIMouse2)) ) 60 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set format" ); 61 62 mHwnd = ((Win32InputManager*)mCreator)->getWindowHandle(); 63 64 if( FAILED(mMouse->SetCooperativeLevel(mHwnd, coopSetting)) ) 65 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set coop level" ); 66 67 if( FAILED(mMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph )) ) 68 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set property" ); 69 70 HRESULT hr = mMouse->Acquire(); 71 if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO) 72 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to aquire mouse!" ); 73} 74 75//--------------------------------------------------------------------------------------------------// 76Win32Mouse::~Win32Mouse() 77{ 78 if (mMouse) 79 { 80 mMouse->Unacquire(); 81 mMouse->Release(); 82 mMouse = 0; 83 } 84 85 static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(false); 86} 87 88//--------------------------------------------------------------------------------------------------// 89void Win32Mouse::capture() 90{ 91 //Clear old relative values 92 mState.X.rel = mState.Y.rel = mState.Z.rel = 0; 93 94 DIDEVICEOBJECTDATA diBuff[MOUSE_DX_BUFFERSIZE]; 95 DWORD entries = MOUSE_DX_BUFFERSIZE; 96 97 HRESULT hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); 98 if( hr != DI_OK ) 99 { 100 hr = mMouse->Acquire(); 101 while( hr == DIERR_INPUTLOST ) 102 hr = mMouse->Acquire(); 103 104 hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); 105 106 //Perhaps the user just tabbed away, and coop settings 107 //are nonexclusive..so just ignore 108 if( FAILED(hr) ) 109 return; 110 } 111 112 bool axesMoved = false; 113 //Accumulate all axis movements for one axesMove message.. 114 //Buttons are fired off as they are found 115 for(unsigned int i = 0; i < entries; ++i ) 116 { 117 switch( diBuff[i].dwOfs ) 118 { 119 case DIMOFS_BUTTON0: 120 if(!_doMouseClick(0, diBuff[i])) return; 121 break; 122 case DIMOFS_BUTTON1: 123 if(!_doMouseClick(1, diBuff[i])) return; 124 break; 125 case DIMOFS_BUTTON2: 126 if(!_doMouseClick(2, diBuff[i])) return; 127 break; 128 case DIMOFS_BUTTON3: 129 if(!_doMouseClick(3, diBuff[i])) return; 130 break; 131 case DIMOFS_BUTTON4: 132 if(!_doMouseClick(4, diBuff[i])) return; 133 break; 134 case DIMOFS_BUTTON5: 135 if(!_doMouseClick(5, diBuff[i])) return; 136 break; 137 case DIMOFS_BUTTON6: 138 if(!_doMouseClick(6, diBuff[i])) return; 139 break; 140 case DIMOFS_BUTTON7: 141 if(!_doMouseClick(7, diBuff[i])) return; 142 break; 143 case DIMOFS_X: 144 mState.X.rel += diBuff[i].dwData; 145 axesMoved = true; 146 break; 147 case DIMOFS_Y: 148 mState.Y.rel += diBuff[i].dwData; 149 axesMoved = true; 150 break; 151 case DIMOFS_Z: 152 mState.Z.rel += diBuff[i].dwData; 153 axesMoved = true; 154 break; 155 default: break; 156 } //end switch 157 }//end for 158 159 if( axesMoved ) 160 { 161 if( coopSetting & DISCL_NONEXCLUSIVE ) 162 { 163 //DirectInput provides us with meaningless values, so correct that 164 POINT point; 165 GetCursorPos(&point); 166 ScreenToClient(mHwnd, &point); 167 mState.X.abs = point.x; 168 mState.Y.abs = point.y; 169 } 170 else 171 { 172 mState.X.abs += mState.X.rel; 173 mState.Y.abs += mState.Y.rel; 174 } 175 mState.Z.abs += mState.Z.rel; 176 177 //Clip values to window 178 if( mState.X.abs < 0 ) 179 mState.X.abs = 0; 180 else if( mState.X.abs > mState.width ) 181 mState.X.abs = mState.width; 182 if( mState.Y.abs < 0 ) 183 mState.Y.abs = 0; 184 else if( mState.Y.abs > mState.height ) 185 mState.Y.abs = mState.height; 186 187 //Do the move 188 if( mListener && mBuffered ) 189 mListener->mouseMoved( MouseEvent( this, mState ) ); 190 } 191} 192 193//--------------------------------------------------------------------------------------------------// 194bool Win32Mouse::_doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di ) 195{ 196 if( di.dwData & 0x80 ) 197 { 198 mState.buttons |= 1 << mouseButton; //turn the bit flag on 199 if( mListener && mBuffered ) 200 return mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton ); 201 } 202 else 203 { 204 mState.buttons &= ~(1 << mouseButton); //turn the bit flag off 205 if( mListener && mBuffered ) 206 return mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton ); 207 } 208 209 return true; 210} 211 212//--------------------------------------------------------------------------------------------------// 213void Win32Mouse::setBuffered(bool buffered) 214{ 215 mBuffered = buffered; 216}