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