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

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:51 2004