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 (mUseKeyboard)
00418         {
00419             if (mUseBufferedKeys )
00420             {
00421                 readBufferedKeyboardData();
00422             }
00423             else
00424             {
00425                 mModifiers = getKeyModifiers();
00426                 captureKeyboard();
00427             }
00428         }
00429         if (mUseMouse)
00430         {
00431             if (mUseBufferedMouse )
00432             {
00433                 readBufferedMouseData();
00434             }
00435             else
00436             {
00437                 captureMouse();
00438             }
00439         }
00440 
00441     }
00442     //-----------------------------------------------------------------------
00443     void Win32Input8::captureKeyboard(void)
00444     {
00445         HRESULT  hr;
00446 
00447         // Get keyboard state
00448         hr = mlpDIKeyboard->GetDeviceState(sizeof(mKeyboardBuffer),(LPVOID)&mKeyboardBuffer);
00449         if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
00450         {
00451             hr = mlpDIKeyboard->Acquire();
00452             if (hr == DIERR_OTHERAPPHASPRIO)
00453             {
00454                 hr = 0;
00455             }
00456             else
00457             {
00458                 hr = mlpDIKeyboard->GetDeviceState(sizeof(mKeyboardBuffer),(LPVOID)&mKeyboardBuffer);
00459             }
00460         }
00461         else if (hr == DIERR_OTHERAPPHASPRIO)
00462         {
00463             // We've gone into the background - ignore
00464             hr = 0;
00465         }
00466         else if (hr == DIERR_NOTINITIALIZED)
00467         {
00468             hr = 0;
00469         }
00470         else if (hr == E_PENDING)
00471         {
00472             hr = 0;
00473         }
00474         else if (FAILED(hr))
00475         {
00476             // Ignore for now
00477             // TODO - sort this out
00478             hr = 0;
00479         }
00480 
00481     }
00482 
00483     //-----------------------------------------------------------------------
00484     void Win32Input8::captureMouse(void)
00485     {
00486         DIMOUSESTATE2 mouseState;
00487         HRESULT hr;
00488 
00489         // Get mouse state
00490         hr = mlpDIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ), (LPVOID)&mouseState );
00491 
00492         if( SUCCEEDED( hr ) ||
00493             ( ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED ) &&
00494               SUCCEEDED( mlpDIMouse->Acquire() ) && 
00495               SUCCEEDED( mlpDIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ), (LPVOID)&mouseState ) ) ) )
00496         {
00497             /* Register the new 'origin'. */
00498             mMouseCenterX = mMouseState.Xabs;
00499             mMouseCenterY = mMouseState.Yabs;
00500             mMouseCenterZ = mMouseState.Zabs;
00501 
00502             /* Get the new absolute position. */
00503             mMouseState.Xabs = mouseState.lX;
00504             mMouseState.Yabs = mouseState.lY;
00505             mMouseState.Zabs = mouseState.lZ;            
00506 
00507             /* Compute the new relative position. */
00508             mMouseState.Xrel = mMouseState.Xabs - mMouseCenterX;
00509             mMouseState.Yrel = mMouseState.Yabs - mMouseCenterY;
00510             mMouseState.Zrel = mMouseState.Zabs - mMouseCenterZ;
00511 
00512             /* Get the mouse buttons. This for loop can be unwrapped for speed. */
00513             mMouseState.Buttons = 0;
00514             for( size_t i = 0; i < 8; i++ )
00515                 if( mouseState.rgbButtons[ i ] & 0x80 )
00516                     mMouseState.Buttons |= ( 1 << i );
00517         }
00518         else if (hr == DIERR_OTHERAPPHASPRIO)
00519         {
00520             // We've gone into the background - ignore
00521             hr = 0;
00522         }
00523         else if (hr == DIERR_NOTINITIALIZED)
00524         {
00525             hr = 0;
00526         }
00527         else if (hr == E_PENDING)
00528         {
00529             hr = 0;
00530         }
00531         else if (FAILED(hr))
00532         {
00533             // Ignore for now
00534             // TODO - sort this out
00535             hr = 0;
00536         }
00537  
00538    }
00539 
00540 
00541 
00542     //-----------------------------------------------------------------------------
00543     // Name: readBufferedData()
00544     // Desc: Read the input device's state when in buffered mode and display it.
00545     //-----------------------------------------------------------------------------
00546     bool Win32Input8::readBufferedKeyboardData()
00547     {
00548         DIDEVICEOBJECTDATA didod[ DINPUT_BUFFERSIZE ];  // Receives buffered data 
00549         DWORD              dwElements;
00550         HRESULT            hr;
00551 
00552         if( NULL == mlpDIKeyboard ) 
00553             return true;
00554     
00555         dwElements = DINPUT_BUFFERSIZE;
00556 
00557         hr = mlpDIKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
00558                                          didod, &dwElements, 0 );
00559         if( hr != DI_OK ) 
00560         {
00561             // We got an error or we got DI_BUFFEROVERFLOW.
00562             //
00563             // Either way, it means that continuous contact with the
00564             // device has been lost, either due to an external
00565             // interruption, or because the buffer overflowed
00566             // and some events were lost.
00567             //
00568             // Consequently, if a button was pressed at the time
00569             // the buffer overflowed or the connection was broken,
00570             // the corresponding "up" message might have been lost.
00571             //
00572             // But since our simple sample doesn't actually have
00573             // any state associated with button up or down events,
00574             // there is no state to reset.  (In a real game, ignoring
00575             // the buffer overflow would result in the game thinking
00576             // a key was held down when in fact it isn't; it's just
00577             // that the "up" event got lost because the buffer
00578             // overflowed.)
00579             //
00580             // If we want to be cleverer, we could do a
00581             // GetDeviceState() and compare the current state
00582             // against the state we think the device is in,
00583             // and process all the states that are currently
00584             // different from our private state.
00585             hr = mlpDIKeyboard->Acquire();
00586             while( hr == DIERR_INPUTLOST ) 
00587                 hr = mlpDIKeyboard->Acquire();
00588 
00589             // Update the dialog text 
00590     /*        if( hr == DIERR_OTHERAPPHASPRIO || 
00591                 hr == DIERR_NOTACQUIRED ) 
00592                 SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") );
00593     */
00594             // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
00595             // may occur when the app is minimized or in the process of 
00596             // switching, so just try again later 
00597             return S_OK; 
00598         }
00599 
00600         if( FAILED(hr) )  
00601             return false;
00602 
00603         for(unsigned int i = 0; i < dwElements; i++ ) 
00604         {
00605             keyChanged( didod[ i ].dwOfs, (didod[ i ].dwData & 0x80) != 0);
00606         }
00607         return true;
00608     }
00609 
00610     //-----------------------------------------------------------------------------
00611     // Name: readBufferedData()
00612     // Desc: Read the input device's state when in buffered mode and display it.
00613     //-----------------------------------------------------------------------------
00614     bool Win32Input8::readBufferedMouseData()
00615     {
00616         DIDEVICEOBJECTDATA didod[ DINPUT_BUFFERSIZE ];  // Receives buffered data 
00617         DWORD              dwElements;
00618         HRESULT            hr;
00619 
00620         if( NULL == mlpDIMouse ) 
00621             return true;
00622     
00623         dwElements = DINPUT_BUFFERSIZE;
00624 
00625         hr = mlpDIMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
00626                                          didod, &dwElements, 0 );
00627         if( hr != DI_OK ) 
00628         {
00629             // We got an error or we got DI_BUFFEROVERFLOW.
00630             //
00631             // Either way, it means that continuous contact with the
00632             // device has been lost, either due to an external
00633             // interruption, or because the buffer overflowed
00634             // and some events were lost.
00635             //
00636             // Consequently, if a button was pressed at the time
00637             // the buffer overflowed or the connection was broken,
00638             // the corresponding "up" message might have been lost.
00639             //
00640             // But since our simple sample doesn't actually have
00641             // any state associated with button up or down events,
00642             // there is no state to reset.  (In a real game, ignoring
00643             // the buffer overflow would result in the game thinking
00644             // a key was held down when in fact it isn't; it's just
00645             // that the "up" event got lost because the buffer
00646             // overflowed.)
00647             //
00648             // If we want to be cleverer, we could do a
00649             // GetDeviceState() and compare the current state
00650             // against the state we think the device is in,
00651             // and process all the states that are currently
00652             // different from our private state.
00653             hr = mlpDIMouse->Acquire();
00654             while( hr == DIERR_INPUTLOST ) 
00655                 hr = mlpDIMouse->Acquire();
00656 
00657             // Update the dialog text 
00658     /*        if( hr == DIERR_OTHERAPPHASPRIO || 
00659                 hr == DIERR_NOTACQUIRED ) 
00660                 SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") );
00661     */
00662             // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
00663             // may occur when the app is minimized or in the process of 
00664             // switching, so just try again later 
00665             return S_OK; 
00666         }
00667 
00668         if( FAILED(hr) )  
00669             return false;
00670 
00671         bool xSet = false;
00672         bool ySet = false;
00673         bool zSet = false;
00674 
00675         for(unsigned int i = 0; i < dwElements; i++ ) 
00676         {
00677             int nMouseCode = -1;        // not set
00678 
00679             // this will display then scan code of the key
00680             // plus a 'D' - meaning the key was pressed 
00681             //   or a 'U' - meaning the key was released
00682             switch( didod [ i ].dwOfs )
00683             {
00684                 case DIMOFS_BUTTON0:
00685                     nMouseCode = InputEvent::BUTTON0_MASK;
00686                     break;
00687 
00688                 case DIMOFS_BUTTON1:
00689                     nMouseCode = InputEvent::BUTTON1_MASK;
00690                     break;
00691 
00692                 case DIMOFS_BUTTON2:
00693                     nMouseCode = InputEvent::BUTTON2_MASK;
00694                     break;
00695 
00696                 case DIMOFS_BUTTON3:
00697                     nMouseCode = InputEvent::BUTTON3_MASK;
00698                     break;
00699 
00700                 case DIMOFS_X:
00701                     if (xSet) 
00702                     {   // process the last X move since we have a new one
00703                         mouseMoved(); 
00704                         xSet = false;
00705                     }
00706                     mCursor->addToX(getScaled(didod[i].dwData));
00707                     xSet = true;
00708                     break;
00709 
00710                 case DIMOFS_Y:
00711                     if (ySet) 
00712                     {
00713                         mouseMoved(); 
00714                         ySet = false;
00715                     }
00716                     mCursor->addToY(getScaled(didod[i].dwData));  
00717                     ySet = true;
00718                     break;
00719 
00720                 case DIMOFS_Z:
00721                     if (zSet) 
00722                     {
00723                         mouseMoved(); 
00724                         zSet = false;
00725                     }
00726                     mCursor->addToZ(getScaled(didod[i].dwData));
00727                     zSet = true;
00728                     break;
00729 
00730                 default:
00731                     break;
00732             }
00733             if (nMouseCode != -1)
00734             {
00735                 triggerMouseButton(nMouseCode, (didod [ i ].dwData & 0x80) != 0);
00736             }
00737             if (xSet && ySet)   // don't create 2 mousemove events for an single X and Y move, just create 1.
00738             {
00739                 mouseMoved(); 
00740                 ySet = false;
00741                 xSet = false;
00742             }
00743 
00744 
00745         }
00746         if (zSet || xSet || ySet) // check for last moved at end
00747         {
00748             mouseMoved(); 
00749         }
00750 
00751         return true;
00752     }
00753     //-----------------------------------------------------------------------
00754 
00755     Real Win32Input8::getScaled(DWORD dwVal) const
00756     {
00757         return (Real)((int)dwVal) * mScale;
00758     }
00759 
00760     //-----------------------------------------------------------------------
00761     bool Win32Input8::isKeyDown(KeyCode kc) const
00762     {
00763         return ( mKeyboardBuffer[ kc ] & 0x80 ) != 0;
00764     }
00765 
00766     //---------------------------------------------------------------------------------------------
00767     long Win32Input8::getMouseRelX() const
00768     {
00769         return mMouseState.Xrel;
00770     }
00771 
00772     //---------------------------------------------------------------------------------------------
00773     long Win32Input8::getMouseRelY() const
00774     {
00775         return mMouseState.Yrel;
00776     }
00777 
00778     //---------------------------------------------------------------------------------------------
00779     long Win32Input8::getMouseRelZ() const
00780     {
00781         return mMouseState.Zrel;
00782     }
00783 
00784     long Win32Input8::getMouseAbsX() const
00785     {
00786         return mMouseState.Xabs;
00787     }
00788 
00789     long Win32Input8::getMouseAbsY() const
00790     {
00791         return mMouseState.Yabs;
00792     }
00793 
00794     long Win32Input8::getMouseAbsZ() const
00795     {
00796         return mMouseState.Zabs;
00797     }
00798 
00799     //---------------------------------------------------------------------------------------------
00800     bool Win32Input8::getMouseButton( uchar button ) const
00801     {
00802         return mMouseState.isButtonDown( button ) != 0;
00803     }
00804 
00805     //---------------------------------------------------------------------------------------------
00806     void Win32Input8::getMouseState( MouseState& state ) const
00807     {
00808         memcpy( &state, &mMouseState, sizeof( MouseState ) );
00809     }
00810 
00811     //---------------------------------------------------------------------------------------------
00812     long Win32Input8::getKeyModifiers() const
00813     {
00814         long ret = mModifiers;
00815 
00816         if (mModifiers == 16)
00817         {
00818             int x=5;
00819 
00820         }
00821 
00822         if (isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU))
00823         {
00824             ret |= InputEvent::ALT_MASK;
00825         }
00826         else
00827         {
00828             ret &= ~InputEvent::ALT_MASK;
00829         }
00830 
00831         if (isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT))
00832         {
00833             ret |= InputEvent::SHIFT_MASK;
00834         }
00835         else
00836         {
00837             ret &= ~InputEvent::SHIFT_MASK;
00838         }
00839 
00840         if (isKeyDown(KC_LCONTROL) || isKeyDown(KC_LCONTROL))
00841         {
00842             ret |= InputEvent::CTRL_MASK;
00843         }
00844         else
00845         {
00846             ret &= ~InputEvent::CTRL_MASK;
00847         }
00848 
00849         return ret;
00850     }
00851 
00852 } // namespace

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:55 2004