Open main menu

CDOT Wiki β

Satijas

Joined 14 September 2009
Revision as of 13:27, 7 April 2011 by Satijas (talk | contribs)

About Me

Hi, my name is Sasha. I'm in GAM670

Force Feedback

Add this to WindowSettings.h:

#define IDC_NOFF //number

Add this in typedef enum Integer:

GF_CT_RMBL

In iInput.h, add line 1 in the iJoystick class In Input.h, add line 2 in the Joystick class In Input.h, add line 3 in the Joystick class

1.
public:
   virtual void updateForce(float, double, int) = 0;
2.
  int feedBackOFF;
  LPDIRECTINPUTEFFECT centre;
  LPDIRECTINPUTEFFECT ffEffects;
3.
  public:
     void updateForce(float factor, double time, int direction);

In Input.cpp, add the following to the Joystick constructor

 ffEffects = NULL;
 centre = NULL;
 feedBackOFF = 0;

add this in Joystick::interrogate function:

 DIDEVCAPS didcaps;
     didcaps.dwSize = sizeof didcaps;
     if(SUCCEEDED(didInter->GetCapabilities(&didcaps)) &&
       (didcaps.dwFlags && DIDC_FOREFEEDBACK){
        EnableWindow(GetDlgItem((HWND)hwnd, IDC_NOFF), TRUE);   
        }
     else{
        EnableWindow(GetDlgItem((HWND)hwnd, IDC_NOFF), FALSE);
     }

add this in Joystick::setup function:

 feedBackOFF = !!(flags & 8);

change the SetCooperativeLevel in setup to check for device exclusivity

   else if (FAILED(joystick->SetCooperativeLevel((HWND)hwnd,
 (feedBackOFF ? DISCL_NONEXCLUSIVE : DISCL_EXCLUSIVE) | DISCL_FOREGROUND)))

add this line after (!zAxisOn)

if(feedBackOFF)
   centre = NULL;

add these in the restore function:

else{
if(ffEffects){
    ffEffects->Download();
}
if(centre){
    centre->Download();
    centre->Start(1,0);
}


add this function in:

void Joystick::updateForce(float factor, double time, int direction){
   if(joystick)
   {
       if (feedBackOFF == 0)
       {
           if(context->get(GF_CT_RMBL) == 1)
           {
           if(ffEffects){
               ffEffects->Download();
           }
          
           DIEFFECT dif;
           DWORD axes[2] = {DIJOFS_X, DIJOFS_Y};
           LONG dir[2]   = {1, 0};
           ZeroMemory(&dif, sizeof dif);
          
           // set the size of the struct
           dif.dwSize  = sizeof dif;
           // set axes and directions
           dif.rgdwAxes = axes;
           dif.rglDirection = dir;
          
           DIPERIODIC dip;
           DIENVELOPE die;
           // if both x & y have FF, make shake come at 45 degree angle
           // otherwise just shake the x axis.
           //
           if (axisIsActive[0] && axisIsActive[1]) {
               dif.dwFlags = DIEFF_POLAR | DIEFF_OBJECTOFFSETS;
               dif.cAxes = 2;
               dir[0] = direction * DI_DEGREES;
           }
           else { // assume only x axis has FF
               dif.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
               dif.cAxes = 1;
           }
           dif.dwGain = DI_FFNOMINALMAX;
           dif.dwDuration = time * DI_SECONDS / 2; // Timing in seconds of the force feedback, time is passed in here;
           dif.dwSamplePeriod = direction;
           dif.dwTriggerButton = DIEB_NOTRIGGER;
           dif.dwTriggerRepeatInterval = 0;
           dif.lpEnvelope = ¨
           dif.cbTypeSpecificParams = sizeof dip;
           dif.lpvTypeSpecificParams = &dip;
           dif.dwStartDelay = 3 * DI_SECONDS; // 3 secs
           dip.dwMagnitude = 3 * DI_FFNOMINALMAX / 10;
           dip.lOffset  = 0;
           dip.dwPhase  = 0;
           dip.dwPeriod = DI_SECONDS / 10; // 1/10th second
           die.dwSize = sizeof die;
           die.dwAttackLevel = factor;
           die.dwAttackTime  = factor * DI_SECONDS / 2;
           die.dwFadeLevel   = factor;
           die.dwFadeTime    = DI_SECONDS / 2;
           HRESULT hr = joystick->CreateEffect(GUID_Square, &dif, &ffEffects, NULL);
           // create a ramp force
           DIRAMPFORCE dirf;
           // if both x & y have FF, use the direction to change the angle of the shake
           // otherwise just shake the x axis.
           //
           if (axisIsActive[0] && axisIsActive[1]) {
               dif.dwFlags = DIEFF_POLAR | DIEFF_OBJECTOFFSETS;
               dif.cAxes = 2;
               dir[0] = direction * DI_DEGREES;
           }
           else { // assume only x axis has FF
               dif.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
               dif.cAxes = 1;
           }
           dif.dwGain = DI_FFNOMINALMAX;
           dif.dwDuration = time * DI_SECONDS / 2; // Timing in seconds for the force feedback, time is passed in here;
           dif.dwSamplePeriod = direction;
           dif.dwTriggerButton = DIEB_NOTRIGGER;
           dif.dwTriggerRepeatInterval = 0;
           dif.lpEnvelope = ¨
           dif.cbTypeSpecificParams = sizeof dirf;
           dif.lpvTypeSpecificParams = &dirf;
           dif.dwStartDelay = 0.01 * DI_SECONDS;
           dirf.lStart = DI_FFNOMINALMAX / 2;
           dirf.lEnd   = - DI_FFNOMINALMAX / 2;
           die.dwSize = sizeof die;
           die.dwAttackLevel = DI_FFNOMINALMAX / 50;
           die.dwAttackTime  = time * DI_SECONDS / 2;
           die.dwFadeLevel   = DI_FFNOMINALMAX / 10;
           die.dwFadeTime    = time * DI_SECONDS / 2;
           if (SUCCEEDED(joystick->CreateEffect(GUID_RampForce, &dif,
            &ffEffects, NULL))){
              ffEffects->Download();// download to driver
               ffEffects->Start(INFINITE,0); // infinite so it can be played as many times
               }
           }
           else if(context->get(GF_CT_RMBL) == 0)
           {
               if(ffEffects){
               DWORD DIGFFS_STOPPED1 = 2;
               if(!joystick->GetForceFeedbackState(&DIGFFS_STOPPED1))
                   ffEffects->Stop();
               }
           }
       }
   }
}

Add this to release:

if(centre){
    centre->Release();
    centre = NULL;
}
if(ffEffects){
    ffEffects->Release();
    ffEffects = NULL;
}

In UserDialog.cpp: In the saveUserChoices function, add another bool:

bool y, z, ff, none;