Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreWin32Input8.cpp

Go to the documentation of this file.
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