- Timestamp:
- Aug 22, 2009, 11:16:34 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/resource2/src/ois/win32/Win32ForceFeedback.cpp
r1505 r5668 25 25 #include <Math.h> 26 26 27 #if defined (_DEBUG) 27 // 0 = No trace; 1 = Important traces; 2 = Debug traces 28 #define OIS_WIN32_JOYFF_DEBUG 1 29 30 #if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG)) 31 #include <iostream> 28 32 #include <sstream> 33 using namespace std; 29 34 #endif 30 35 … … 32 37 33 38 //--------------------------------------------------------------// 34 Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* joy) : 35 mHandles(0), mJoyStick(joy) 36 { 39 Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps) : 40 mHandles(0), mJoyStick(pDIJoy), mFFAxes(0), mpDIJoyCaps(pDIJoyCaps) 41 { 42 #if (OIS_WIN32_JOYFF_DEBUG > 0) 43 cout << "FFSamplePeriod : " << mpDIJoyCaps->dwFFSamplePeriod << " mu-s, " 44 << "FFMinTimeResolution : " << mpDIJoyCaps->dwFFMinTimeResolution << " mu-s," 45 << "" << endl; 46 #endif 37 47 } 38 48 … … 45 55 LPDIRECTINPUTEFFECT dxEffect = i->second; 46 56 if( dxEffect ) 57 { 47 58 dxEffect->Unload(); 59 dxEffect->Release(); 60 } 48 61 } 49 62 50 63 mEffectList.clear(); 64 } 65 66 //--------------------------------------------------------------// 67 short Win32ForceFeedback::getFFAxesNumber() 68 { 69 return mFFAxes; 70 } 71 72 //--------------------------------------------------------------// 73 unsigned short Win32ForceFeedback::getFFMemoryLoad() 74 { 75 DIPROPDWORD dipdw; // DIPROPDWORD contains a DIPROPHEADER structure. 76 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 77 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 78 dipdw.diph.dwObj = 0; // device property 79 dipdw.diph.dwHow = DIPH_DEVICE; 80 dipdw.dwData = 0; // In case of any error. 81 82 const HRESULT hr = mJoyStick->GetProperty(DIPROP_FFLOAD, &dipdw.diph); 83 if(FAILED(hr)) 84 { 85 if (hr == DIERR_NOTEXCLUSIVEACQUIRED) 86 OIS_EXCEPT(E_General, "Can't query FF memory load as device was not acquired in exclusive mode"); 87 else 88 OIS_EXCEPT(E_General, "Unknown error querying FF memory load ->.."); 89 } 90 91 return (unsigned short)dipdw.dwData; 51 92 } 52 93 … … 86 127 //have been unlaoded 87 128 if( SUCCEEDED(dxEffect->Unload()) ) 129 { 130 dxEffect->Release(); 88 131 mEffectList.erase(i); 132 } 89 133 } 90 134 else … … 111 155 DIPropGain.dwData = gain_level; 112 156 113 mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph); 157 #if (OIS_WIN32_JOYFF_DEBUG > 0) 158 cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting master gain to " 159 << level << " => " << DIPropGain.dwData << endl; 160 #endif 161 162 const HRESULT hr = mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph); 163 164 #if defined (_DEBUG) 165 if(FAILED(hr)) 166 cout << "Failed to change master gain" << endl; 167 #endif 114 168 } 115 169 … … 117 171 void Win32ForceFeedback::setAutoCenterMode( bool auto_on ) 118 172 { 119 //DI Property DIPROPAUTOCENTER_OFF = 0, 1 is on120 173 DIPROPDWORD DIPropAutoCenter; 121 174 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); … … 123 176 DIPropAutoCenter.diph.dwObj = 0; 124 177 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; 125 DIPropAutoCenter.dwData = auto_on; 126 127 //hr = 128 mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); 178 DIPropAutoCenter.dwData = (auto_on ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF); 179 180 #if (OIS_WIN32_JOYFF_DEBUG > 0) 181 cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting auto-center mode to " 182 << auto_on << " => " << DIPropAutoCenter.dwData << endl; 183 #endif 184 185 const HRESULT hr = mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); 186 187 #if defined (_DEBUG) 188 if(FAILED(hr)) 189 cout << "Failed to change auto-center mode" << endl; 190 #endif 129 191 } 130 192 … … 132 194 void Win32ForceFeedback::_updateConstantEffect( const Effect* effect ) 133 195 { 196 ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect()); 197 134 198 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 135 199 LONG rglDirection[2] = { 0, 0 }; 200 DIENVELOPE diEnvelope; 136 201 DICONSTANTFORCE cf; 137 202 DIEFFECT diEffect; … … 139 204 //Currently only support 1 axis 140 205 //if( effect->getNumAxes() == 1 ) 141 cf.lMagnitude = static_cast<ConstantEffect*>(effect->getForceEffect())->level; 142 143 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONSTANTFORCE), &cf, effect); 206 cf.lMagnitude = eff->level; 207 208 #if (OIS_WIN32_JOYFF_DEBUG > 1) 209 cout << " Level : " << eff->level 210 << " => " << cf.lMagnitude << endl; 211 #endif 212 213 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONSTANTFORCE), &cf, effect, &eff->envelope); 144 214 _upload(GUID_ConstantForce, &diEffect, effect); 145 215 } … … 148 218 void Win32ForceFeedback::_updateRampEffect( const Effect* effect ) 149 219 { 220 RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect()); 221 150 222 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 151 223 LONG rglDirection[2] = { 0, 0 }; 224 DIENVELOPE diEnvelope; 152 225 DIRAMPFORCE rf; 153 226 DIEFFECT diEffect; 154 227 155 228 //Currently only support 1 axis 156 rf.lStart = static_cast<RampEffect*>(effect->getForceEffect())->startLevel;157 rf.lEnd = static_cast<RampEffect*>(effect->getForceEffect())->endLevel;158 159 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIRAMPFORCE), &rf, effect);229 rf.lStart = eff->startLevel; 230 rf.lEnd = eff->endLevel; 231 232 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope ); 160 233 _upload(GUID_RampForce, &diEffect, effect); 161 234 } … … 164 237 void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect ) 165 238 { 239 PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect()); 240 166 241 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 167 242 LONG rglDirection[2] = { 0, 0 }; 243 DIENVELOPE diEnvelope; 168 244 DIPERIODIC pf; 169 245 DIEFFECT diEffect; 170 246 171 247 //Currently only support 1 axis 172 pf.dwMagnitude = static_cast<PeriodicEffect*>(effect->getForceEffect())->magnitude;173 pf.lOffset = static_cast<PeriodicEffect*>(effect->getForceEffect())->offset;174 pf.dwPhase = static_cast<PeriodicEffect*>(effect->getForceEffect())->phase;175 pf.dwPeriod = static_cast<PeriodicEffect*>(effect->getForceEffect())->period;176 177 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIPERIODIC), &pf, effect);248 pf.dwMagnitude = eff->magnitude; 249 pf.lOffset = eff->offset; 250 pf.dwPhase = eff->phase; 251 pf.dwPeriod = eff->period; 252 253 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIPERIODIC), &pf, effect, &eff->envelope ); 178 254 179 255 switch( effect->type ) … … 191 267 void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect ) 192 268 { 269 ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect()); 270 193 271 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 194 272 LONG rglDirection[2] = { 0, 0 }; 273 DIENVELOPE diEnvelope; 195 274 DICONDITION cf; 196 275 DIEFFECT diEffect; 197 276 198 cf.lOffset = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;199 cf.lPositiveCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightCoeff;200 cf.lNegativeCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftCoeff;201 cf.dwPositiveSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightSaturation;202 cf.dwNegativeSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftSaturation;203 cf.lDeadBand = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;204 205 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONDITION), &cf, effect);277 cf.lOffset = eff->deadband; 278 cf.lPositiveCoefficient = eff->rightCoeff; 279 cf.lNegativeCoefficient = eff->leftCoeff; 280 cf.dwPositiveSaturation = eff->rightSaturation; 281 cf.dwNegativeSaturation = eff->leftSaturation; 282 cf.lDeadBand = eff->deadband; 283 284 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONDITION), &cf, effect, 0 ); 206 285 207 286 switch( effect->type ) … … 218 297 void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ ) 219 298 { 299 //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect()); 300 // 220 301 //DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 221 302 //LONG rglDirection[2] = { 0, 0 }; 303 //DIENVELOPE diEnvelope; 222 304 //DICUSTOMFORCE cf; 223 305 //DIEFFECT diEffect; … … 226 308 //cf.cSamples = 0; 227 309 //cf.rglForceData = 0; 228 //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICUSTOMFORCE), &cf, effect);310 //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope); 229 311 //_upload(GUID_CustomForce, &diEffect, effect); 230 312 } … … 233 315 void Win32ForceFeedback::_setCommonProperties( 234 316 DIEFFECT* diEffect, DWORD* rgdwAxes, 235 LONG* rglDirection, D WORD struct_size,236 LPVOID struct_type, const Effect* effect )317 LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 318 LPVOID struct_type, const Effect* effect, const Envelope* envelope ) 237 319 { 238 320 ZeroMemory(diEffect, sizeof(DIEFFECT)); … … 240 322 diEffect->dwSize = sizeof(DIEFFECT); 241 323 diEffect->dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; 324 diEffect->dwGain = DI_FFNOMINALMAX; 325 326 diEffect->dwTriggerButton = DIEB_NOTRIGGER; // effect->trigger_button; // TODO: Conversion 327 diEffect->dwTriggerRepeatInterval = effect->trigger_interval; 328 329 #if (OIS_WIN32_JOYFF_DEBUG > 1) 330 cout << " Trigger :" << endl 331 << " Button : " << effect->trigger_button 332 << " => " << diEffect->dwTriggerButton << endl 333 << " Interval : " << effect->trigger_interval 334 << " => " << diEffect->dwTriggerRepeatInterval << endl; 335 #endif 336 337 diEffect->cAxes = 1; // effect->getNumAxes(); 338 diEffect->rgdwAxes = rgdwAxes; 339 340 diEffect->rglDirection = rglDirection; // TODO: conversion from effect->direction 341 342 #if (OIS_WIN32_JOYFF_DEBUG > 1) 343 cout << " Direction : " << Effect::getDirectionName(effect->direction) 344 << " => {"; 345 for (int iDir=0; iDir < (int)diEffect->cAxes; iDir++) 346 cout << " " << diEffect->rglDirection[iDir]; 347 cout << "}" << endl; 348 #endif 349 350 if (diEnvelope && envelope && envelope->isUsed()) 351 { 352 diEnvelope->dwSize = sizeof(DIENVELOPE); 353 diEnvelope->dwAttackLevel = envelope->attackLevel; 354 diEnvelope->dwAttackTime = envelope->attackLength; 355 diEnvelope->dwFadeLevel = envelope->fadeLevel; 356 diEnvelope->dwFadeTime = envelope->fadeLength; 357 diEffect->lpEnvelope = diEnvelope; 358 } 359 else 360 diEffect->lpEnvelope = 0; 361 362 #if (OIS_WIN32_JOYFF_DEBUG > 1) 363 if (diEnvelope && envelope && envelope->isUsed()) 364 { 365 cout << " Enveloppe :" << endl 366 << " AttackLen : " << envelope->attackLength 367 << " => " << diEnvelope->dwAttackTime << endl 368 << " AttackLvl : " << envelope->attackLevel 369 << " => " << diEnvelope->dwAttackLevel << endl 370 << " FadeLen : " << envelope->fadeLength 371 << " => " << diEnvelope->dwFadeTime << endl 372 << " FadeLvl : " << envelope->fadeLevel 373 << " => " << diEnvelope->dwFadeLevel << endl; 374 } 375 #endif 376 377 diEffect->dwSamplePeriod = 0; 242 378 diEffect->dwDuration = effect->replay_length; 243 diEffect->dwSamplePeriod = 0; 244 diEffect->dwGain = DI_FFNOMINALMAX; 245 diEffect->dwTriggerButton = DIEB_NOTRIGGER; 246 diEffect->dwTriggerRepeatInterval = 0; 247 diEffect->cAxes = effect->getNumAxes(); 248 diEffect->rgdwAxes = rgdwAxes; 249 diEffect->rglDirection = rglDirection; 250 diEffect->lpEnvelope = 0; 379 diEffect->dwStartDelay = effect->replay_delay; 380 381 #if (OIS_WIN32_JOYFF_DEBUG > 1) 382 cout << " Replay :" << endl 383 << " Length : " << effect->replay_length 384 << " => " << diEffect->dwDuration << endl 385 << " Delay : " << effect->replay_delay 386 << " => " << diEffect->dwStartDelay << endl; 387 #endif 388 251 389 diEffect->cbTypeSpecificParams = struct_size; 252 390 diEffect->lpvTypeSpecificParams = struct_type; 253 diEffect->dwStartDelay = effect->replay_delay;254 391 } 255 392 … … 295 432 void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei ) 296 433 { 297 //Determine what the effect is and how it corresponds to our OIS's Enums 298 //We could save the GUIDs too, however, we will just use the predefined 299 //ones later 434 #if (OIS_WIN32_JOYFF_DEBUG > 0) 435 // Dump some usefull information about the effect type. 436 cout << "Adding support for '" << pdei->tszName << "' effect type" << endl; 437 cout << " Supported static params: "; 438 if (pdei->dwStaticParams & DIEP_AXES) cout << " Axes"; 439 if (pdei->dwStaticParams & DIEP_DIRECTION) cout << " Direction"; 440 if (pdei->dwStaticParams & DIEP_DURATION) cout << " Duration"; 441 if (pdei->dwStaticParams & DIEP_ENVELOPE) cout << " Envelope"; 442 if (pdei->dwStaticParams & DIEP_GAIN) cout << " Gain"; 443 if (pdei->dwStaticParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod"; 444 if (pdei->dwStaticParams & DIEP_STARTDELAY) cout << " StartDelay"; 445 if (pdei->dwStaticParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton"; 446 if (pdei->dwStaticParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval"; 447 if (pdei->dwStaticParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams"; 448 cout << endl; 449 cout << " Supported dynamic params: "; 450 if (pdei->dwDynamicParams & DIEP_AXES) cout << " Axes"; 451 if (pdei->dwDynamicParams & DIEP_DIRECTION) cout << " Direction"; 452 if (pdei->dwDynamicParams & DIEP_DURATION) cout << " Duration"; 453 if (pdei->dwDynamicParams & DIEP_ENVELOPE) cout << " Envelope"; 454 if (pdei->dwDynamicParams & DIEP_GAIN) cout << " Gain"; 455 if (pdei->dwDynamicParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod"; 456 if (pdei->dwDynamicParams & DIEP_STARTDELAY) cout << " StartDelay"; 457 if (pdei->dwDynamicParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton"; 458 if (pdei->dwDynamicParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval"; 459 if (pdei->dwDynamicParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams"; 460 cout << endl; 461 cout << " More details about supported parameters support: "; 462 if (pdei->dwEffType & DIEFT_STARTDELAY) cout << " StartDelay"; 463 if (pdei->dwEffType & DIEFT_FFATTACK) cout << " Attack"; 464 if (pdei->dwEffType & DIEFT_FFFADE) cout << " Fade"; 465 if (pdei->dwEffType & DIEFT_DEADBAND) cout << " DeadBand"; 466 if (pdei->dwEffType & DIEFT_SATURATION) cout << " Saturation"; 467 if (pdei->dwEffType & DIEFT_POSNEGSATURATION) cout << " PosNegaturation"; 468 if (pdei->dwEffType & DIEFT_POSNEGCOEFFICIENTS) cout << " PosNegCoefficients"; 469 if (pdei->dwEffType & DIEFT_HARDWARE) cout << " HardwareSpecific"; 470 cout << endl; 471 #endif 472 473 Effect::EForce eForce; 474 switch (DIEFT_GETTYPE(pdei->dwEffType)) 475 { 476 case DIEFT_CONSTANTFORCE: 477 eForce = Effect::ConstantForce; 478 break; 479 case DIEFT_RAMPFORCE: 480 eForce = Effect::RampForce; 481 break; 482 case DIEFT_PERIODIC: 483 eForce = Effect::PeriodicForce; 484 break; 485 case DIEFT_CONDITION: 486 eForce = Effect::ConditionalForce; 487 break; 488 case DIEFT_CUSTOMFORCE: 489 eForce = Effect::CustomForce; 490 break; 491 default: 492 eForce = Effect::UnknownForce; 493 #if defined (_DEBUG) 494 cout << "Win32ForceFeedback: DirectInput8 Effect type support not implemented: " 495 << "DIEFT_GETTYPE="<< (int)DIEFT_GETTYPE(pdei->dwEffType) << endl; 496 #endif 497 return; 498 } 499 500 //Determine what the effect type is and how it corresponds to our OIS's Enums 501 //We could save the GUIDs too, however, we will just use the predefined ones later 300 502 if( pdei->guid == GUID_ConstantForce ) 301 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Constant );503 _addEffectTypes(eForce, Effect::Constant ); 302 504 else if( pdei->guid == GUID_Triangle ) 303 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Triangle );505 _addEffectTypes(eForce, Effect::Triangle ); 304 506 else if( pdei->guid == GUID_Spring ) 305 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Spring );507 _addEffectTypes(eForce, Effect::Spring ); 306 508 else if( pdei->guid == GUID_Friction ) 307 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Friction );509 _addEffectTypes(eForce, Effect::Friction ); 308 510 else if( pdei->guid == GUID_Square ) 309 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Square );511 _addEffectTypes(eForce, Effect::Square ); 310 512 else if( pdei->guid == GUID_Sine ) 311 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Sine );513 _addEffectTypes(eForce, Effect::Sine ); 312 514 else if( pdei->guid == GUID_SawtoothUp ) 313 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothUp );515 _addEffectTypes(eForce, Effect::SawToothUp ); 314 516 else if( pdei->guid == GUID_SawtoothDown ) 315 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothDown );517 _addEffectTypes(eForce, Effect::SawToothDown ); 316 518 else if( pdei->guid == GUID_Damper ) 317 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Damper );519 _addEffectTypes(eForce, Effect::Damper ); 318 520 else if( pdei->guid == GUID_Inertia ) 319 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Inertia );521 _addEffectTypes(eForce, Effect::Inertia ); 320 522 else if( pdei->guid == GUID_CustomForce ) 321 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Custom );523 _addEffectTypes(eForce, Effect::Custom ); 322 524 else if( pdei->guid == GUID_RampForce ) 323 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Ramp ); 525 _addEffectTypes(eForce, Effect::Ramp ); 526 324 527 #if defined (_DEBUG) 325 528 //Only care about this for Debugging Purposes … … 333 536 #endif 334 537 } 538 539 //--------------------------------------------------------------// 540 void Win32ForceFeedback::_addFFAxis() 541 { 542 mFFAxes++; 543 }
Note: See TracChangeset
for help on using the changeset viewer.