// Strength ranges from 0 to 1 void setWheelRumbleStrength(double strength) { DIPERIODIC pf = { FFWRMAX * strength * 10000,0,0,0.06 * 1000000 }; g_sWheelRumbleConfig.cbTypeSpecificParams = sizeof(DIPERIODIC); g_sWheelRumbleConfig.lpvTypeSpecificParams = &pf; if (g_pWheelRumbleHandle) { g_pWheelRumbleHandle->SetParameters(&g_sWheelRumbleConfig, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); } }
// Magnitude ranges from -1 to 1 void setAutoCenterStrength(double magnitude) { DICONSTANTFORCE cf = { magnitude * 10000 }; g_sAutoCenterConfig.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); g_sAutoCenterConfig.lpvTypeSpecificParams = &cf; if (g_pAutoCenterHandle) { g_pAutoCenterHandle->SetParameters(&g_sAutoCenterConfig, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); } }
HRESULT SetDeviceForcesXY(float x,float y) { // Modifying an effect is basically the same as creating a new one, except // you need only specify the parameters you are modifying LONG rglDirection[2] = { 0, 0 }; DICONSTANTFORCE cf; if( g_dwNumForceFeedbackAxis == 1 ) { // If only one force feedback axis, then apply only one direction and // keep the direction at zero cf.lMagnitude = x; rglDirection[0] = 0; } else { // If two force feedback axis, then apply magnitude from both directions rglDirection[0] = x; rglDirection[1] = y; cf.lMagnitude = ( DWORD )sqrt( x * x + y * y ); } DIEFFECT eff; ZeroMemory( &eff, sizeof( eff ) ); eff.dwSize = sizeof( DIEFFECT ); eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; eff.cAxes = g_dwNumForceFeedbackAxis; eff.rglDirection = rglDirection; eff.lpEnvelope = 0; eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); eff.lpvTypeSpecificParams = &cf; eff.dwStartDelay = 0; // Now set the new parameters and start the effect immediately. HRESULT hr = S_OK; hr = g_pEffect->SetParameters( &eff, DIEP_DIRECTION |DIEP_TYPESPECIFICPARAMS |DIEP_START ); HRESULT a1 = DIERR_INVALIDPARAM; return hr; }
//--------------------------------------------------------------// void Win32ForceFeedback::_upload( GUID guid, DIEFFECT* diEffect, const Effect* effect) { LPDIRECTINPUTEFFECT dxEffect = 0; //Get the effect - if it exists EffectList::iterator i = mEffectList.find(effect->_handle); //It has been created already if( i != mEffectList.end() ) dxEffect = i->second; else //This effect has not yet been created - generate a handle effect->_handle = mHandles++; if( dxEffect == 0 ) { //This effect has not yet been created, so create it HRESULT hr = mJoyStick->CreateEffect(guid, diEffect, &dxEffect, NULL); if(SUCCEEDED(hr)) { mEffectList[effect->_handle] = dxEffect; dxEffect->Start(INFINITE,0); } else if( hr == DIERR_DEVICEFULL ) OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!"); else OIS_EXCEPT(E_General, "Unknown error creating effect->.."); } else { //ToDo -- Update the Effect HRESULT hr = dxEffect->SetParameters( diEffect, DIEP_DIRECTION | DIEP_DURATION | DIEP_ENVELOPE | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON | DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS | DIEP_START ); if(FAILED(hr)) OIS_EXCEPT(E_InvalidParam, "Error updating device!"); } }
//----------------------------------------------------------------------------- // Purpose: // Input : effectnum - // params - //----------------------------------------------------------------------------- void CInput::ForceFeedback_Start( int effectnum, const FFBaseParams_t& params ) { if ( !m_pFF || !m_pFF->m_bForceFeedbackAvailable ) return; // Unpause system... if ( m_pFF->m_bPaused ) { ForceFeedback_Resume(); } // look up the effect FORCEFEEDBACK_t effect = (FORCEFEEDBACK_t)effectnum; if ( effect < 0 || effect >= NUM_FORCE_FEEDBACK_PRESETS ) { Assert( !"ForceFeedback_Start with bogus effectnum" ); return; } EffectMap_t *map = &g_EffectMap[ effectnum ]; vecEffectPtr_t *effects = map->pVecEffectPtr; // Play the effects on the device int c = effects->Count(); for ( int i = 0; i < c; ++i ) { LPDIRECTINPUTEFFECT pEffect = (*effects)[ i ]; if ( !map->m_bDownloaded ) { pEffect->Download(); map->m_bDownloaded = true; } DWORD flags = DIEP_DIRECTION | DIEP_GAIN | DIEP_DURATION; LONG rglDirection[2] = { 0, 100 }; // Fill in parameters DIEFFECT effect; Q_memset( &effect, 0, sizeof( effect ) ); effect.dwSize = sizeof( effect ); effect.dwFlags = DIEFF_POLAR | DIEFF_OBJECTOFFSETS; effect.rglDirection = rglDirection; effect.cAxes = 2; HRESULT hr = pEffect->GetParameters( &effect, flags ); if ( !FAILED( hr ) ) { // If params.m_flDuration == 0.0f then that means use the duration in the file if ( params.m_flDuration <= -0.999f ) { effect.dwDuration = INFINITE; } else if( params.m_flDuration >= 0.001f ) { // Convert to microsseconds effect.dwDuration = (DWORD)( params.m_flDuration * 1000000.0f ); } effect.dwGain = params.m_flGain * 10000.0f; effect.rglDirection[ 0 ] = 100.0f * params.m_flDirection; effect.rglDirection[ 1 ] = 0; hr = pEffect->SetParameters( &effect, flags ); if ( !FAILED( hr ) ) { pEffect->Start( 1, params.m_bSolo ? DIES_SOLO : 0 ); } } } }