00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreWin32Input8.h" 00026 #include "OgreRenderWindow.h" 00027 #include "OgreLogManager.h" 00028 #include "OgreException.h" 00029 #include "OgreRoot.h" 00030 #include "OgreRenderSystem.h" 00031 #include "OgreMouseEvent.h" 00032 #include "OgreInputEvent.h" 00033 #include "OgreEventQueue.h" 00034 #include "OgreCursor.h" 00035 #include <dxerr8.h> 00036 00037 #define DINPUT_BUFFERSIZE 16 00038 //#define DIPROP_BUFFERSIZE 256 00039 00040 namespace Ogre { 00041 //----------------------------------------------------------------------- 00042 Win32Input8::Win32Input8() : 00043 InputReader() 00044 { 00045 mlpDI = 0; 00046 mlpDIKeyboard = 0; 00047 mlpDIMouse = 0; 00048 mEventQueue = 0; 00049 mScale = 0.001; 00050 00051 memset(mKeyboardBuffer,0,256); 00052 } 00053 //----------------------------------------------------------------------- 00054 Win32Input8::~Win32Input8() 00055 { 00056 // Shutdown 00057 if (mlpDIKeyboard) 00058 { 00059 mlpDIKeyboard->Unacquire(); 00060 mlpDIKeyboard->Release(); 00061 mlpDIKeyboard = 0; 00062 } 00063 if (mlpDIMouse) 00064 { 00065 mlpDIMouse->Unacquire(); 00066 mlpDIMouse->Release(); 00067 mlpDIMouse = 0; 00068 } 00069 if (mlpDI) 00070 { 00071 mlpDI->Release(); 00072 mlpDI = 0; 00073 } 00074 00075 } 00076 00077 //----------------------------------------------------------------------- 00078 void Win32Input8::initialiseBufferedKeyboard() 00079 { 00080 00081 HRESULT hr; 00082 LogManager::getSingleton().logMessage("Win32Input8: Establishing keyboard input."); 00083 00084 // Create keyboard device 00085 hr = mlpDI->CreateDevice(GUID_SysKeyboard, &mlpDIKeyboard, NULL); 00086 00087 00088 if (FAILED(hr)) 00089 throw Exception(hr, "Unable to create DirectInput keyboard device.", 00090 "Win32Input8 - initialise"); 00091 00092 // Set data format 00093 hr = mlpDIKeyboard->SetDataFormat(&c_dfDIKeyboard); 00094 if (FAILED(hr)) 00095 throw Exception(hr, "Unable to set DirectInput keyboard device data format.", 00096 "Win32Input8 - initialise"); 00097 00098 // Make the window grab keyboard behaviour when foreground 00099 hr = mlpDIKeyboard->SetCooperativeLevel(mHWnd, 00100 DISCL_FOREGROUND | DISCL_EXCLUSIVE); 00101 if (FAILED(hr)) 00102 throw Exception(hr, "Unable to set DirectInput keyboard device co-operative level.", 00103 "Win32Input8 - initialise"); 00104 00105 00106 // IMPORTANT STEP TO USE BUFFERED DEVICE DATA! 00107 // 00108 // DirectInput uses unbuffered I/O (buffer size = 0) by default. 00109 // If you want to read buffered data, you need to set a nonzero 00110 // buffer size. 00111 // 00112 // Set the buffer size to SAMPLE_BUFFER_SIZE (defined above) elements. 00113 // 00114 // The buffer size is a DWORD property associated with the device. 00115 DIPROPDWORD dipdw; 00116 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 00117 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 00118 dipdw.diph.dwObj = 0; 00119 dipdw.diph.dwHow = DIPH_DEVICE; 00120 dipdw.dwData = DINPUT_BUFFERSIZE; // Arbitary buffer size 00121 00122 hr = mlpDIKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ); 00123 00124 if (FAILED(hr)) 00125 throw Exception(hr, "Unable to create DirectInput keyboard buffer.", 00126 "Win32Input8 - initialise"); 00127 00128 // Acquire input 00129 hr = mlpDIKeyboard->Acquire(); 00130 if (FAILED(hr)) 00131 throw Exception(hr, "Unable to set aquire DirectInput keyboard device.", 00132 "Win32Input8 - initialise"); 00133 00134 LogManager::getSingleton().logMessage("Win32Input8: Keyboard input established."); 00135 } 00136 00137 //----------------------------------------------------------------------- 00138 void Win32Input8::initialiseImmediateKeyboard() 00139 { 00140 HRESULT hr; 00141 LogManager::getSingleton().logMessage("Win32Input8: Establishing keyboard input."); 00142 00143 // Create keyboard device 00144 hr = mlpDI->CreateDevice(GUID_SysKeyboard, &mlpDIKeyboard, NULL); 00145 00146 00147 if (FAILED(hr)) 00148 throw Exception(hr, "Unable to create DirectInput keyboard device.", 00149 "Win32Input8 - initialise"); 00150 00151 // Set data format 00152 hr = mlpDIKeyboard->SetDataFormat(&c_dfDIKeyboard); 00153 if (FAILED(hr)) 00154 throw Exception(hr, "Unable to set DirectInput keyboard device data format.", 00155 "Win32Input8 - initialise"); 00156 00157 // Make the window grab keyboard behaviour when foreground 00158 // NB Keyboard is never exclusive 00159 hr = mlpDIKeyboard->SetCooperativeLevel(mHWnd, 00160 DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); 00161 if (FAILED(hr)) 00162 throw Exception(hr, "Unable to set DirectInput keyboard device co-operative level.", 00163 "Win32Input8 - initialise"); 00164 00165 // IMPORTANT STEP TO USE BUFFERED DEVICE DATA! 00166 // 00167 // DirectInput uses unbuffered I/O (buffer size = 0) by default. 00168 // If you want to read buffered data, you need to set a nonzero 00169 // buffer size. 00170 // 00171 // Set the buffer size to DINPUT_BUFFERSIZE (defined above) elements. 00172 // 00173 // The buffer size is a DWORD property associated with the device. 00174 DIPROPDWORD dipdw; 00175 00176 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 00177 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 00178 dipdw.diph.dwObj = 0; 00179 dipdw.diph.dwHow = DIPH_DEVICE; 00180 dipdw.dwData = DINPUT_BUFFERSIZE ; // Arbitary buffer size 00181 00182 hr = mlpDIKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ; 00183 00184 if (FAILED(hr)) 00185 throw Exception(hr, "Unable to create DirectInput keyboard buffer.", 00186 "Win32Input8 - initialise"); 00187 00188 00189 // Acquire input 00190 hr = mlpDIKeyboard->Acquire(); 00191 if (FAILED(hr)) 00192 throw Exception(hr, "Unable to set aquire DirectInput keyboard device.", 00193 "Win32Input8 - initialise"); 00194 00195 LogManager::getSingleton().logMessage("Win32Input8: Keyboard input established."); 00196 } 00197 //----------------------------------------------------------------------- 00198 void Win32Input8::initialiseImmediateMouse() 00199 { 00200 OgreGuard( "Win32Input8::initialiseImmediateMouse" ); 00201 00202 HRESULT hr; 00203 DIPROPDWORD dipdw; 00204 LogManager::getSingleton().logMessage( "Win32Input8: Initializing mouse input in immediate mode." ); 00205 00206 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 00207 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 00208 dipdw.diph.dwObj = 0; 00209 dipdw.diph.dwHow = DIPH_DEVICE; 00210 dipdw.dwData = DIPROPAXISMODE_ABS; 00211 00212 if( /* Create the DI Device. */ 00213 FAILED( hr = mlpDI->CreateDevice( GUID_SysMouse, &mlpDIMouse, NULL ) ) || 00214 /* Set the data format so that it knows it's a mouse. */ 00215 FAILED( hr = mlpDIMouse->SetDataFormat( &c_dfDIMouse2 ) ) || 00216 /* Absolute mouse input. We can derive the relative input from this. */ 00217 FAILED( hr = mlpDIMouse->SetProperty( DIPROP_AXISMODE, &dipdw.diph ) ) || 00218 /* Exclusive when in foreground, steps back when in background. */ 00219 FAILED( hr = mlpDIMouse->SetCooperativeLevel( mHWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE ) ) ) 00220 { 00221 Except( hr, "Unable to initialise mouse", "Win32Input8::initialiseImmediateMouse" ); 00222 } 00223 /* Note that we did not acquire the mouse in the code above, since the call may fail (ie you're in the 00224 debugger) and an exception would be thrown. Acquisition happens in the captureMouse() function. */ 00225 00226 /* Get initial mouse data. We might as well fail this initial attempt, so no biggie. */ 00227 captureMouse(); 00228 00229 /* Clear any relative mouse data. */ 00230 mMouseState.Xrel = mMouseState.Yrel = mMouseState.Zrel = 0; 00231 00232 LogManager::getSingleton().logMessage( "Win32Input8: Mouse input in immediate mode initialized." ); 00233 00234 OgreUnguard(); 00235 } 00236 00237 //----------------------------------------------------------------------- 00238 void Win32Input8::initialiseBufferedMouse() 00239 { 00240 HRESULT hr; 00241 LogManager::getSingleton().logMessage("Win32Input8: Establishing mouse input."); 00242 00243 // Create mouse device 00244 hr = mlpDI->CreateDevice(GUID_SysMouse, &mlpDIMouse, NULL); 00245 00246 00247 if (FAILED(hr)) 00248 throw Exception(hr, "Unable to create DirectInput mouse device.", 00249 "Win32Input8 - initialise"); 00250 00251 // Set data format 00252 hr = mlpDIMouse->SetDataFormat(&c_dfDIMouse2); 00253 if (FAILED(hr)) 00254 throw Exception(hr, "Unable to set DirectInput mouse device data format.", 00255 "Win32Input8 - initialise"); 00256 00257 // Make the window grab mouse behaviour when foreground 00258 hr = mlpDIMouse->SetCooperativeLevel(mHWnd, 00259 DISCL_FOREGROUND | DISCL_EXCLUSIVE); 00260 if (FAILED(hr)) 00261 throw Exception(hr, "Unable to set DirectInput mouse device co-operative level.", 00262 "Win32Input8 - initialise"); 00263 00264 00265 // IMPORTANT STEP TO USE BUFFERED DEVICE DATA! 00266 // 00267 // DirectInput uses unbuffered I/O (buffer size = 0) by default. 00268 // If you want to read buffered data, you need to set a nonzero 00269 // buffer size. 00270 // 00271 // Set the buffer size to SAMPLE_BUFFER_SIZE (defined above) elements. 00272 // 00273 // The buffer size is a DWORD property associated with the device. 00274 DIPROPDWORD dipdw; 00275 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 00276 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 00277 dipdw.diph.dwObj = 0; 00278 dipdw.diph.dwHow = DIPH_DEVICE; 00279 dipdw.dwData = DINPUT_BUFFERSIZE; // Arbitary buffer size 00280 00281 hr = mlpDIMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ); 00282 00283 if (FAILED(hr)) 00284 throw Exception(hr, "Unable to create DirectInput mouse buffer.", 00285 "Win32Input8 - initialise"); 00286 00287 // Acquire input 00288 hr = mlpDIMouse->Acquire(); 00289 if (FAILED(hr)) 00290 throw Exception(hr, "Unable to set aquire DirectInput mouse device.", 00291 "Win32Input8 - initialise"); 00292 00293 LogManager::getSingleton().logMessage("Win32Input8: Mouse input established."); 00294 00295 } 00296 00297 //----------------------------------------------------------------------- 00298 void Win32Input8::initialise(RenderWindow* pWindow, bool useKeyboard, bool useMouse, bool useGameController) 00299 { 00300 HRESULT hr; 00301 00302 mUseKeyboard = useKeyboard; 00303 mUseMouse = useMouse; 00304 LogManager::getSingleton().logMessage("Win32Input8: DirectInput Activation Starts"); 00305 00306 // Get HINST 00307 HINSTANCE hInst = GetModuleHandle("OgrePlatform.dll"); 00308 00309 // Get HWND 00310 HWND hWnd = GetActiveWindow(); 00311 00312 mHWnd = hWnd; 00313 00314 ShowCursor(FALSE); 00315 00316 00317 // Register with the DirectInput subsystem and get a pointer 00318 // to a IDirectInput interface we can use. 00319 // Create a DInput object 00320 hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mlpDI, NULL ); 00321 if (FAILED(hr)) 00322 throw Exception(hr, "Unable to initialise DirectInput.", 00323 "Win32Input8 - initialise"); 00324 00325 if (useKeyboard) 00326 { 00327 if (mUseBufferedKeys) 00328 { 00329 initialiseBufferedKeyboard(); 00330 } 00331 else 00332 { 00333 initialiseImmediateKeyboard(); 00334 } 00335 } 00336 00337 if (useMouse) 00338 { 00339 if (mUseBufferedMouse) 00340 { 00341 initialiseBufferedMouse(); 00342 } 00343 else 00344 { 00345 initialiseImmediateMouse(); 00346 } 00347 } 00348 00349 00350 LogManager::getSingleton().logMessage("Win32Input8: DirectInput OK."); 00351 00352 } 00353 00354 /* void Win32Input8::setBufferedInput(bool keys, bool mouse) 00355 { 00356 flushAllBuffers(); 00357 InputReader::setBufferedInput(keys, mouse); 00358 } 00359 */ 00360 void Win32Input8::flushAllBuffers() 00361 { 00362 00363 DWORD dwItems = INFINITE; 00364 HRESULT hr = mlpDIKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 00365 NULL, &dwItems, 0 ); 00366 hr = mlpDIMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 00367 NULL, &dwItems, 0 ); 00368 } 00369 00370 //----------------------------------------------------------------------- 00371 00372 // this function is not needed at the moment because we are making everything buffered 00373 void Win32Input8::setBufferedInput(bool keys, bool mouse) 00374 { 00375 if (mUseKeyboard && mUseBufferedKeys != keys) 00376 { 00377 if (mlpDIKeyboard) 00378 { 00379 mlpDIKeyboard->Unacquire(); 00380 mlpDIKeyboard->Release(); 00381 mlpDIKeyboard = 0; 00382 } 00383 if (keys) 00384 { 00385 initialiseBufferedKeyboard(); 00386 } 00387 else 00388 { 00389 initialiseImmediateKeyboard(); 00390 } 00391 00392 } 00393 if (mUseMouse && mUseBufferedMouse != mouse) 00394 { 00395 if (mlpDIMouse) 00396 { 00397 mlpDIMouse->Unacquire(); 00398 mlpDIMouse->Release(); 00399 mlpDIMouse= 0; 00400 } 00401 if (mouse) 00402 { 00403 initialiseBufferedMouse(); 00404 } 00405 else 00406 { 00407 initialiseImmediateMouse(); 00408 } 00409 00410 } 00411 InputReader::setBufferedInput(keys,mouse); 00412 } 00413 00414 //----------------------------------------------------------------------- 00415 void Win32Input8::capture(void) 00416 { 00417 if (mUseBufferedKeys ) 00418 { 00419 readBufferedKeyboardData(); 00420 } 00421 else 00422 { 00423 mModifiers = getKeyModifiers(); 00424 captureKeyboard(); 00425 } 00426 if (mUseBufferedMouse ) 00427 { 00428 readBufferedMouseData(); 00429 } 00430 else 00431 { 00432 captureMouse(); 00433 } 00434 00435 } 00436 //----------------------------------------------------------------------- 00437 void Win32Input8::captureKeyboard(void) 00438 { 00439 HRESULT hr; 00440 00441 // Get keyboard state 00442 hr = mlpDIKeyboard->GetDeviceState(sizeof(mKeyboardBuffer),(LPVOID)&mKeyboardBuffer); 00443 if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) 00444 { 00445 hr = mlpDIKeyboard->Acquire(); 00446 if (hr == DIERR_OTHERAPPHASPRIO) 00447 { 00448 hr = 0; 00449 } 00450 else 00451 { 00452 hr = mlpDIKeyboard->GetDeviceState(sizeof(mKeyboardBuffer),(LPVOID)&mKeyboardBuffer); 00453 } 00454 } 00455 else if (hr == DIERR_OTHERAPPHASPRIO) 00456 { 00457 // We've gone into the background - ignore 00458 hr = 0; 00459 } 00460 else if (hr == DIERR_NOTINITIALIZED) 00461 { 00462 hr = 0; 00463 } 00464 else if (hr == E_PENDING) 00465 { 00466 hr = 0; 00467 } 00468 else if (FAILED(hr)) 00469 { 00470 // Ignore for now 00471 // TODO - sort this out 00472 hr = 0; 00473 } 00474 00475 } 00476 00477 //----------------------------------------------------------------------- 00478 void Win32Input8::captureMouse(void) 00479 { 00480 DIMOUSESTATE2 mouseState; 00481 HRESULT hr; 00482 00483 // Get mouse state 00484 hr = mlpDIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ), (LPVOID)&mouseState ); 00485 00486 if( SUCCEEDED( hr ) || 00487 ( ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED ) && 00488 SUCCEEDED( mlpDIMouse->Acquire() ) && 00489 SUCCEEDED( mlpDIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ), (LPVOID)&mouseState ) ) ) ) 00490 { 00491 /* Register the new 'origin'. */ 00492 mMouseCenterX = mMouseState.Xabs; 00493 mMouseCenterY = mMouseState.Yabs; 00494 mMouseCenterZ = mMouseState.Zabs; 00495 00496 /* Get the new absolute position. */ 00497 mMouseState.Xabs = mouseState.lX; 00498 mMouseState.Yabs = mouseState.lY; 00499 mMouseState.Zabs = mouseState.lZ; 00500 00501 /* Compute the new relative position. */ 00502 mMouseState.Xrel = mMouseState.Xabs - mMouseCenterX; 00503 mMouseState.Yrel = mMouseState.Yabs - mMouseCenterY; 00504 mMouseState.Zrel = mMouseState.Zabs - mMouseCenterZ; 00505 00506 /* Get the mouse buttons. This for loop can be unwrapped for speed. */ 00507 mMouseState.Buttons = 0; 00508 for( size_t i = 0; i < 8; i++ ) 00509 if( mouseState.rgbButtons[ i ] & 0x80 ) 00510 mMouseState.Buttons |= ( 1 << i ); 00511 } 00512 else if (hr == DIERR_OTHERAPPHASPRIO) 00513 { 00514 // We've gone into the background - ignore 00515 hr = 0; 00516 } 00517 else if (hr == DIERR_NOTINITIALIZED) 00518 { 00519 hr = 0; 00520 } 00521 else if (hr == E_PENDING) 00522 { 00523 hr = 0; 00524 } 00525 else if (FAILED(hr)) 00526 { 00527 // Ignore for now 00528 // TODO - sort this out 00529 hr = 0; 00530 } 00531 00532 } 00533 00534 00535 00536 //----------------------------------------------------------------------------- 00537 // Name: readBufferedData() 00538 // Desc: Read the input device's state when in buffered mode and display it. 00539 //----------------------------------------------------------------------------- 00540 bool Win32Input8::readBufferedKeyboardData() 00541 { 00542 DIDEVICEOBJECTDATA didod[ DINPUT_BUFFERSIZE ]; // Receives buffered data 00543 DWORD dwElements; 00544 HRESULT hr; 00545 00546 if( NULL == mlpDIKeyboard ) 00547 return true; 00548 00549 dwElements = DINPUT_BUFFERSIZE; 00550 00551 hr = mlpDIKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 00552 didod, &dwElements, 0 ); 00553 if( hr != DI_OK ) 00554 { 00555 // We got an error or we got DI_BUFFEROVERFLOW. 00556 // 00557 // Either way, it means that continuous contact with the 00558 // device has been lost, either due to an external 00559 // interruption, or because the buffer overflowed 00560 // and some events were lost. 00561 // 00562 // Consequently, if a button was pressed at the time 00563 // the buffer overflowed or the connection was broken, 00564 // the corresponding "up" message might have been lost. 00565 // 00566 // But since our simple sample doesn't actually have 00567 // any state associated with button up or down events, 00568 // there is no state to reset. (In a real game, ignoring 00569 // the buffer overflow would result in the game thinking 00570 // a key was held down when in fact it isn't; it's just 00571 // that the "up" event got lost because the buffer 00572 // overflowed.) 00573 // 00574 // If we want to be cleverer, we could do a 00575 // GetDeviceState() and compare the current state 00576 // against the state we think the device is in, 00577 // and process all the states that are currently 00578 // different from our private state. 00579 hr = mlpDIKeyboard->Acquire(); 00580 while( hr == DIERR_INPUTLOST ) 00581 hr = mlpDIKeyboard->Acquire(); 00582 00583 // Update the dialog text 00584 /* if( hr == DIERR_OTHERAPPHASPRIO || 00585 hr == DIERR_NOTACQUIRED ) 00586 SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") ); 00587 */ 00588 // hr may be DIERR_OTHERAPPHASPRIO or other errors. This 00589 // may occur when the app is minimized or in the process of 00590 // switching, so just try again later 00591 return S_OK; 00592 } 00593 00594 if( FAILED(hr) ) 00595 return false; 00596 00597 for(unsigned int i = 0; i < dwElements; i++ ) 00598 { 00599 keyChanged( didod[ i ].dwOfs, (didod[ i ].dwData & 0x80) != 0); 00600 } 00601 return true; 00602 } 00603 00604 //----------------------------------------------------------------------------- 00605 // Name: readBufferedData() 00606 // Desc: Read the input device's state when in buffered mode and display it. 00607 //----------------------------------------------------------------------------- 00608 bool Win32Input8::readBufferedMouseData() 00609 { 00610 DIDEVICEOBJECTDATA didod[ DINPUT_BUFFERSIZE ]; // Receives buffered data 00611 DWORD dwElements; 00612 HRESULT hr; 00613 00614 if( NULL == mlpDIMouse ) 00615 return true; 00616 00617 dwElements = DINPUT_BUFFERSIZE; 00618 00619 hr = mlpDIMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 00620 didod, &dwElements, 0 ); 00621 if( hr != DI_OK ) 00622 { 00623 // We got an error or we got DI_BUFFEROVERFLOW. 00624 // 00625 // Either way, it means that continuous contact with the 00626 // device has been lost, either due to an external 00627 // interruption, or because the buffer overflowed 00628 // and some events were lost. 00629 // 00630 // Consequently, if a button was pressed at the time 00631 // the buffer overflowed or the connection was broken, 00632 // the corresponding "up" message might have been lost. 00633 // 00634 // But since our simple sample doesn't actually have 00635 // any state associated with button up or down events, 00636 // there is no state to reset. (In a real game, ignoring 00637 // the buffer overflow would result in the game thinking 00638 // a key was held down when in fact it isn't; it's just 00639 // that the "up" event got lost because the buffer 00640 // overflowed.) 00641 // 00642 // If we want to be cleverer, we could do a 00643 // GetDeviceState() and compare the current state 00644 // against the state we think the device is in, 00645 // and process all the states that are currently 00646 // different from our private state. 00647 hr = mlpDIMouse->Acquire(); 00648 while( hr == DIERR_INPUTLOST ) 00649 hr = mlpDIMouse->Acquire(); 00650 00651 // Update the dialog text 00652 /* if( hr == DIERR_OTHERAPPHASPRIO || 00653 hr == DIERR_NOTACQUIRED ) 00654 SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") ); 00655 */ 00656 // hr may be DIERR_OTHERAPPHASPRIO or other errors. This 00657 // may occur when the app is minimized or in the process of 00658 // switching, so just try again later 00659 return S_OK; 00660 } 00661 00662 if( FAILED(hr) ) 00663 return false; 00664 00665 bool xSet = false; 00666 bool ySet = false; 00667 bool zSet = false; 00668 00669 for(unsigned int i = 0; i < dwElements; i++ ) 00670 { 00671 int nMouseCode = -1; // not set 00672 00673 // this will display then scan code of the key 00674 // plus a 'D' - meaning the key was pressed 00675 // or a 'U' - meaning the key was released 00676 switch( didod [ i ].dwOfs ) 00677 { 00678 case DIMOFS_BUTTON0: 00679 nMouseCode = InputEvent::BUTTON0_MASK; 00680 break; 00681 00682 case DIMOFS_BUTTON1: 00683 nMouseCode = InputEvent::BUTTON1_MASK; 00684 break; 00685 00686 case DIMOFS_BUTTON2: 00687 nMouseCode = InputEvent::BUTTON2_MASK; 00688 break; 00689 00690 case DIMOFS_BUTTON3: 00691 nMouseCode = InputEvent::BUTTON3_MASK; 00692 break; 00693 00694 case DIMOFS_X: 00695 if (xSet) 00696 { // process the last X move since we have a new one 00697 mouseMoved(); 00698 xSet = false; 00699 } 00700 mCursor->addToX(getScaled(didod[i].dwData)); 00701 xSet = true; 00702 break; 00703 00704 case DIMOFS_Y: 00705 if (ySet) 00706 { 00707 mouseMoved(); 00708 ySet = false; 00709 } 00710 mCursor->addToY(getScaled(didod[i].dwData)); 00711 ySet = true; 00712 break; 00713 00714 case DIMOFS_Z: 00715 if (zSet) 00716 { 00717 mouseMoved(); 00718 zSet = false; 00719 } 00720 mCursor->addToZ(getScaled(didod[i].dwData)); 00721 zSet = true; 00722 break; 00723 00724 default: 00725 break; 00726 } 00727 if (nMouseCode != -1) 00728 { 00729 triggerMouseButton(nMouseCode, (didod [ i ].dwData & 0x80) != 0); 00730 } 00731 if (xSet && ySet) // don't create 2 mousemove events for an single X and Y move, just create 1. 00732 { 00733 mouseMoved(); 00734 ySet = false; 00735 xSet = false; 00736 } 00737 00738 00739 } 00740 if (zSet || xSet || ySet) // check for last moved at end 00741 { 00742 mouseMoved(); 00743 } 00744 00745 return true; 00746 } 00747 //----------------------------------------------------------------------- 00748 00749 Real Win32Input8::getScaled(DWORD dwVal) const 00750 { 00751 return (Real)((int)dwVal) * mScale; 00752 } 00753 00754 //----------------------------------------------------------------------- 00755 bool Win32Input8::isKeyDown(KeyCode kc) const 00756 { 00757 return ( mKeyboardBuffer[ kc ] & 0x80 ) != 0; 00758 } 00759 00760 //--------------------------------------------------------------------------------------------- 00761 long Win32Input8::getMouseRelX() const 00762 { 00763 return mMouseState.Xrel; 00764 } 00765 00766 //--------------------------------------------------------------------------------------------- 00767 long Win32Input8::getMouseRelY() const 00768 { 00769 return mMouseState.Yrel; 00770 } 00771 00772 //--------------------------------------------------------------------------------------------- 00773 long Win32Input8::getMouseRelZ() const 00774 { 00775 return mMouseState.Zrel; 00776 } 00777 00778 long Win32Input8::getMouseAbsX() const 00779 { 00780 return mMouseState.Xabs; 00781 } 00782 00783 long Win32Input8::getMouseAbsY() const 00784 { 00785 return mMouseState.Yabs; 00786 } 00787 00788 long Win32Input8::getMouseAbsZ() const 00789 { 00790 return mMouseState.Zabs; 00791 } 00792 00793 //--------------------------------------------------------------------------------------------- 00794 bool Win32Input8::getMouseButton( uchar button ) const 00795 { 00796 return mMouseState.isButtonDown( button ) != 0; 00797 } 00798 00799 //--------------------------------------------------------------------------------------------- 00800 void Win32Input8::getMouseState( MouseState& state ) const 00801 { 00802 memcpy( &state, &mMouseState, sizeof( MouseState ) ); 00803 } 00804 00805 //--------------------------------------------------------------------------------------------- 00806 long Win32Input8::getKeyModifiers() const 00807 { 00808 long ret = mModifiers; 00809 00810 if (mModifiers == 16) 00811 { 00812 int x=5; 00813 00814 } 00815 00816 if (isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU)) 00817 { 00818 ret |= InputEvent::ALT_MASK; 00819 } 00820 else 00821 { 00822 ret &= ~InputEvent::ALT_MASK; 00823 } 00824 00825 if (isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT)) 00826 { 00827 ret |= InputEvent::SHIFT_MASK; 00828 } 00829 else 00830 { 00831 ret &= ~InputEvent::SHIFT_MASK; 00832 } 00833 00834 if (isKeyDown(KC_LCONTROL) || isKeyDown(KC_LCONTROL)) 00835 { 00836 ret |= InputEvent::CTRL_MASK; 00837 } 00838 else 00839 { 00840 ret &= ~InputEvent::CTRL_MASK; 00841 } 00842 00843 return ret; 00844 } 00845 00846 } // namespace
Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:32 2004