E:/Download/ois-1.0RC1/src/win32/Copy of Win32JoyStick.cpp

Go to the documentation of this file.
00001 /*
00002 The zlib/libpng License
00003 
00004 Copyright (c) 2006 Phillip Castaneda (pjcast -- www.wreckedgames.com)
00005 
00006 This software is provided 'as-is', without any express or implied warranty. In no event will
00007 the authors be held liable for any damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any purpose, including commercial 
00010 applications, and to alter it and redistribute it freely, subject to the following
00011 restrictions:
00012 
00013     1. The origin of this software must not be misrepresented; you must not claim that 
00014                 you wrote the original software. If you use this software in a product, 
00015                 an acknowledgment in the product documentation would be appreciated but is 
00016                 not required.
00017 
00018     2. Altered source versions must be plainly marked as such, and must not be 
00019                 misrepresented as being the original software.
00020 
00021     3. This notice may not be removed or altered from any source distribution.
00022 */
00023 #include "Win32/Win32JoyStick.h"
00024 #include "Win32/Win32InputManager.h"
00025 #include "OISEvents.h"
00026 #include "OISException.h"
00027 
00028 using namespace OIS;
00029 
00030 //-------------------------------------------------------------------//
00031 Win32JoyStick::Win32JoyStick( IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info )
00032 {
00033         mBuffered = buffered;
00034         mDirectInput = pDI;
00035         coopSetting = coopSettings;
00036         mJoyStick = 0;
00037         mType = OISJoyStick;
00038 
00039         deviceGuid = info.deviceID;
00040         mVendor = info.vendor;
00041         mDevID = info.devId;
00042 
00043         listener = 0;
00044 }
00045 
00046 //-------------------------------------------------------------------//
00047 Win32JoyStick::~Win32JoyStick()
00048 {
00049         if(mJoyStick)
00050         {
00051                 mJoyStick->Unacquire();
00052                 mJoyStick->Release();
00053                 mJoyStick = 0;
00054         }
00055 }
00056 
00057 //-------------------------------------------------------------------//
00058 void Win32JoyStick::_initialize()
00059 {
00060         //Clear joy old state
00061         mState.clear();
00062 
00063         DIPROPDWORD dipdw;
00064 
00065         dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
00066         dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
00067         dipdw.diph.dwObj        = 0;
00068         dipdw.diph.dwHow        = DIPH_DEVICE;
00069         dipdw.dwData            = DX_BUFFERSIZE;
00070 
00071         if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))
00072                 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not init joy device!");
00073 
00074         if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
00075                 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> format error!");
00076 
00077         HWND hwin = ((Win32InputManager*)(InputManager::getSingletonPtr()))->getWindowHandle();
00078         
00079         if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
00080                 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> coop error!");
00081 
00082         if( mBuffered )
00083                 if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
00084                         OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set property" );
00085 
00086         //Enumerate all axes/buttons/sliders/etc before aquiring
00087     _enumerate();
00088 
00089         capture();
00090 }
00091 
00092 //-------------------------------------------------------------------//
00093 void Win32JoyStick::_enumerate()
00094 {
00095         //We can check force feedback here too
00096         DIDEVCAPS  DIJoyCaps; 
00097 
00098         DIJoyCaps.dwSize = sizeof(DIDEVCAPS);
00099 
00100         HRESULT hr = mJoyStick->GetCapabilities(&DIJoyCaps); 
00101         numAxes = (short)DIJoyCaps.dwAxes;
00102         numButtons = (short)DIJoyCaps.dwButtons;
00103 
00104         mJoyStick->EnumObjects(_DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
00105 }
00106 
00107 //-------------------------------------------------------------------//
00108 BOOL CALLBACK Win32JoyStick::_DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
00109 {
00110         DIPROPRANGE diprg;
00111         Win32JoyStick* _this = (Win32JoyStick*)pvRef;
00112 
00113         diprg.diph.dwSize       = sizeof(DIPROPRANGE);
00114         diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
00115         diprg.diph.dwHow        = DIPH_BYID;
00116         diprg.diph.dwObj        = lpddoi->dwType;
00117         diprg.lMin              = -32767;
00118         diprg.lMax              = 32768;
00119 
00120         if (FAILED(_this->mJoyStick->SetProperty(DIPROP_RANGE, &diprg.diph)))
00121                 OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set property" );
00122 
00123         return DIENUM_CONTINUE;
00124 }
00125 
00126 //-------------------------------------------------------------------//
00127 void Win32JoyStick::capture()
00128 {
00129         if( mBuffered )
00130                 _readBuffered();
00131         else
00132                 _read();
00133 }
00134 
00135 //-------------------------------------------------------------------//
00136 void Win32JoyStick::_read()
00137 {
00138     HRESULT     hr;
00139     DIJOYSTATE2 state;           // Direct Input joystick state 
00140 
00141     // Poll the device to read the current state
00142     hr = mJoyStick->Poll();
00143         if( SUCCEEDED(hr) || ((hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) &&
00144             SUCCEEDED(mJoyStick->Acquire()) && SUCCEEDED( mJoyStick->Poll() )))
00145     {
00146                 hr = mJoyStick->GetDeviceState(sizeof(DIJOYSTATE2), &state);
00147 
00148                 if (FAILED(hr))
00149                         OIS_EXCEPT(E_General, "Win32JoyStick::_read() >> Device Read Problem 1");
00150 
00151                 mState.buttons = 0;
00152                 for( int i = 0; i < numButtons; ++i )
00153                         mState.buttons |= ((state.rgbButtons[i] & 0x80) != 0) << i;
00154 
00155                 for( int i = 0; i < 4; ++i )
00156                         mState.mPOV[i] = state.rgdwPOV[i];
00157 
00158                 mState.mAxes[JoyStickState::Stick].setAbsValues(state.lX, state.lY, state.lZ);
00159                 mState.mAxes[JoyStickState::Rotational].setAbsValues(state.lRx, state.lRy, state.lRz);
00160                 mState.mAxes[JoyStickState::Velocity].setAbsValues(state.lVX, state.lVY, state.lVZ);
00161                 mState.mAxes[JoyStickState::AngularVelocity].setAbsValues(state.lVRx, state.lVRy, state.lVRz);
00162                 mState.mAxes[JoyStickState::Acceleration].setAbsValues(state.lAX, state.lAY, state.lAZ);
00163                 mState.mAxes[JoyStickState::AngularAcceleration].setAbsValues(state.lARx, state.lARy, state.lARz);
00164                 mState.mAxes[JoyStickState::Force].setAbsValues(state.lFX, state.lFY, state.lFZ);
00165                 mState.mAxes[JoyStickState::Torque].setAbsValues(state.lFRx, state.lFRy, state.lFRz);
00166         }
00167 }
00168 
00169 //-------------------------------------------------------------------//
00170 void Win32JoyStick::_readBuffered()
00171 {
00172         DIDEVICEOBJECTDATA diBuff[DX_BUFFERSIZE];
00173         DWORD entries = DX_BUFFERSIZE;
00174 
00175         // Poll the device to read the current state
00176     HRESULT hr = mJoyStick->Poll();
00177         if( hr == DI_OK )
00178                 hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
00179 
00180         if( hr != DI_OK )
00181         {
00182                 hr = mJoyStick->Acquire();
00183                 while( hr == DIERR_INPUTLOST ) 
00184                         hr = mJoyStick->Acquire();
00185 
00186                 // Poll the device to read the current state
00187             mJoyStick->Poll();
00188                 hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
00189                 if( FAILED(hr) )
00190                         OIS_EXCEPT(E_General, "Win32JoyStick::_readBuffered() >> Device Error");
00191         }
00192 
00193 #undef DIJOFS_BUTTON
00194 #undef DIJOFS_POV
00195 #define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n))
00196 #define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE2, rgdwPOV)+(n)*sizeof(DWORD))
00197 
00198         bool moved[8] = {false,false,false,false,false,false,false,false};
00199         for(unsigned int i = 0; i < entries; ++i)
00200         {
00201                 switch(diBuff->dwOfs)
00202                 {
00203                 case FIELD_OFFSET(DIJOYSTATE2, lX):
00204                         moved[JoyStickState::Stick] = true;
00205                         mState.mAxes[JoyStickState::Stick].abX = diBuff[i].dwData;
00206                         break;
00207                 case FIELD_OFFSET(DIJOYSTATE2, lY):
00208                         moved[JoyStickState::Stick] = true;
00209                         mState.mAxes[JoyStickState::Stick].abY = diBuff[i].dwData;
00210                         break;
00211                 case FIELD_OFFSET(DIJOYSTATE2, lZ):
00212                         moved[JoyStickState::Stick] = true;
00213                         mState.mAxes[JoyStickState::Stick].abZ = diBuff[i].dwData;
00214                         break;
00215                 case FIELD_OFFSET(DIJOYSTATE2, lRx):
00216                         moved[JoyStickState::Rotational] = true;
00217                         mState.mAxes[JoyStickState::Rotational].abX = diBuff[i].dwData;
00218                         break;
00219                 case FIELD_OFFSET(DIJOYSTATE2, lRy):
00220                         moved[JoyStickState::Rotational] = true;
00221                         mState.mAxes[JoyStickState::Rotational].abY = diBuff[i].dwData;
00222                         break;
00223                 case FIELD_OFFSET(DIJOYSTATE2, lRz):
00224                         moved[JoyStickState::Rotational] = true;
00225                         mState.mAxes[JoyStickState::Rotational].abZ = diBuff[i].dwData;
00226                         break;
00227                 //----- Max 4 POVs Next ---------------//
00228                 case DIJOFS_POV(0):
00229                         _changePOV(0,diBuff[i]);
00230                         break;
00231                 case DIJOFS_POV(1):
00232                         _changePOV(1,diBuff[i]);
00233                         break;
00234                 case DIJOFS_POV(2):
00235                         _changePOV(2,diBuff[i]);
00236                         break;
00237                 case DIJOFS_POV(3):
00238                         _changePOV(3,diBuff[i]);
00239                         break;
00240                 //------ The remaining Axes ------------//
00241                 case FIELD_OFFSET(DIJOYSTATE2, lVX):    
00242                         moved[JoyStickState::Velocity] = true;
00243                         mState.mAxes[JoyStickState::Velocity].abX = diBuff[i].dwData;
00244                         break;
00245                 case FIELD_OFFSET(DIJOYSTATE2, lVY):
00246                         moved[JoyStickState::Velocity] = true;
00247                         mState.mAxes[JoyStickState::Velocity].abY = diBuff[i].dwData;
00248                         break;
00249                 case FIELD_OFFSET(DIJOYSTATE2, lVZ):
00250                         moved[JoyStickState::Velocity] = true;
00251                         mState.mAxes[JoyStickState::Velocity].abZ = diBuff[i].dwData;
00252                         break;
00253                 case FIELD_OFFSET(DIJOYSTATE2, lVRx):
00254                         moved[JoyStickState::AngularVelocity] = true;
00255                         mState.mAxes[JoyStickState::AngularVelocity].abX = diBuff[i].dwData;
00256                         break;
00257                 case FIELD_OFFSET(DIJOYSTATE2, lVRy):
00258                         moved[JoyStickState::AngularVelocity] = true;
00259                         mState.mAxes[JoyStickState::AngularVelocity].abY = diBuff[i].dwData;
00260                         break;
00261                 case FIELD_OFFSET(DIJOYSTATE2, lVRz):
00262                         moved[JoyStickState::AngularVelocity] = true;
00263                         mState.mAxes[JoyStickState::AngularVelocity].abZ = diBuff[i].dwData;
00264                         break;
00265                 case FIELD_OFFSET(DIJOYSTATE2, lAX):
00266                         moved[JoyStickState::Acceleration] = true;
00267                         mState.mAxes[JoyStickState::Acceleration].abX = diBuff[i].dwData;
00268                         break;
00269                 case FIELD_OFFSET(DIJOYSTATE2, lAY):
00270                         moved[JoyStickState::Acceleration] = true;
00271                         mState.mAxes[JoyStickState::Acceleration].abY = diBuff[i].dwData;
00272                         break;
00273                 case FIELD_OFFSET(DIJOYSTATE2, lAZ):
00274                         moved[JoyStickState::Acceleration] = true;
00275                         mState.mAxes[JoyStickState::Acceleration].abZ = diBuff[i].dwData;
00276                         break;
00277                 case FIELD_OFFSET(DIJOYSTATE2, lARx):
00278                         moved[JoyStickState::AngularAcceleration] = true;
00279                         mState.mAxes[JoyStickState::AngularAcceleration].abX = diBuff[i].dwData;
00280                         break;
00281                 case FIELD_OFFSET(DIJOYSTATE2, lARy):
00282                         moved[JoyStickState::AngularAcceleration] = true;
00283                         mState.mAxes[JoyStickState::AngularAcceleration].abY = diBuff[i].dwData;
00284                         break;
00285                 case FIELD_OFFSET(DIJOYSTATE2, lARz):
00286                         moved[JoyStickState::AngularAcceleration] = true;
00287                         mState.mAxes[JoyStickState::AngularAcceleration].abZ = diBuff[i].dwData;
00288                         break;
00289                 case FIELD_OFFSET(DIJOYSTATE2, lFX):
00290                         moved[JoyStickState::Force] = true;
00291                         mState.mAxes[JoyStickState::Force].abX = diBuff[i].dwData;
00292                         break;
00293                 case FIELD_OFFSET(DIJOYSTATE2, lFY):
00294                         moved[JoyStickState::Force] = true;
00295                         mState.mAxes[JoyStickState::Force].abY = diBuff[i].dwData;
00296                         break;
00297                 case FIELD_OFFSET(DIJOYSTATE2, lFZ):
00298                         moved[JoyStickState::Force] = true;
00299                         mState.mAxes[JoyStickState::Force].abZ = diBuff[i].dwData;
00300                         break;
00301                 case FIELD_OFFSET(DIJOYSTATE2, lFRx):
00302                         moved[JoyStickState::Torque] = true;
00303                         mState.mAxes[JoyStickState::Torque].abX = diBuff[i].dwData;
00304                         break;
00305                 case FIELD_OFFSET(DIJOYSTATE2, lFRy):
00306                         moved[JoyStickState::Torque] = true;
00307                         mState.mAxes[JoyStickState::Torque].abY = diBuff[i].dwData;
00308                         break;
00309                 case FIELD_OFFSET(DIJOYSTATE2, lFRz):
00310                         moved[JoyStickState::Torque] = true;
00311                         mState.mAxes[JoyStickState::Torque].abZ = diBuff[i].dwData;
00312                         break;
00313                 default:
00314                         //Handle Button Events Easily using the DX Offset Macros
00315                         if( diBuff->dwOfs >= DIJOFS_BUTTON(0) && diBuff->dwOfs <= DIJOFS_BUTTON(30) )
00316                         {
00317                                 if(!_doButtonClick((diBuff->dwOfs - DIJOFS_BUTTON0), diBuff[i])) 
00318                                         return;
00319                         }
00320                         break;
00321                 } //end case
00322         } //end for
00323 
00324         //Check to see if any of the axes values have changed.. if so send events
00325         if( listener )
00326                 for( int i = 0; i < 8; ++i )
00327                         if( moved[i] )
00328                                 listener->axisMoved( JoyStickEvent(this, diBuff[i].dwTimeStamp, mState), i );
00329 }
00330 //-------------------------------------------------------------------//
00331 bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di )
00332 {
00333         bool ret = true;
00334         if( listener )
00335         {
00336                 if( di.dwData & 0x80 )
00337                 {
00338                         mState.buttons |= 1 << button; //turn the bit flag on
00339                         ret = listener->buttonPressed( JoyStickEvent( this, di.dwTimeStamp, mState ), button );
00340                 }
00341                 else
00342                 {
00343                         mState.buttons &= ~(1 << button); //turn the bit flag off
00344                         ret = listener->buttonReleased( JoyStickEvent( this, di.dwTimeStamp, mState ), button );
00345                 }
00346         }
00347         return ret;
00348 }
00349 
00350 //-------------------------------------------------------------------//
00351 bool Win32JoyStick::_changePOV( int pov, DIDEVICEOBJECTDATA& di )
00352 {
00353         mState.mPOV[pov] = di.dwData;
00354 
00355         if( listener )
00356                 return listener->povMoved( JoyStickEvent( this, di.dwTimeStamp, mState ), pov );
00357 
00358         return true;
00359 }
00360 
00361 //-------------------------------------------------------------------//
00362 void Win32JoyStick::setBuffered(bool buffered)
00363 {
00364         if( buffered != mBuffered )
00365         {
00366                 if(mJoyStick)
00367                 {
00368                         mJoyStick->Unacquire();
00369                         mJoyStick->Release();
00370                         mJoyStick = 0;
00371                 }
00372                 
00373                 mBuffered = buffered;
00374                 _initialize();
00375         }
00376 }
00377 
00378 //-------------------------------------------------------------------//
00379 JoyStickInfo Win32JoyStick::_getJoyInfo()
00380 {
00381         JoyStickInfo js;
00382         js.deviceID = deviceGuid;
00383         js.devId = mDevID;
00384         js.vendor = mVendor;
00385 
00386         return js;
00387 }

Generated on Sat Dec 1 20:13:52 2007 for OIS by  doxygen 1.5.4