00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00087 _enumerate();
00088
00089 capture();
00090 }
00091
00092
00093 void Win32JoyStick::_enumerate()
00094 {
00095
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;
00140
00141
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
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
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
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
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
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 }
00322 }
00323
00324
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;
00339 ret = listener->buttonPressed( JoyStickEvent( this, di.dwTimeStamp, mState ), button );
00340 }
00341 else
00342 {
00343 mState.buttons &= ~(1 << button);
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 }