Difference between revisions of "User:Satijas"

From CDOT Wiki
Jump to: navigation, search
 
(9 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
Hi, my name is Sasha. I'm in GAM670
 
Hi, my name is Sasha. I'm in GAM670
  
[[Category:about]]
+
== Force Feedback ==
 +
 
 +
Add this to '''WindowSettings.h''':
 +
<big>
 +
 +
#define IDC_NOFF //number
 +
</big>
 +
 
 +
Add this in typedef enum Integer in '''Configuration.h''':
 +
<big>
 +
GF_CT_RMBL
 +
</big>
 +
 
 +
In '''iInput.h''':<br />
 +
add line 1 in the iJoystick class<br />
 +
In '''Input.h''':<br />
 +
add line 2 in the Joystick class<br />
 +
add line 3 in the Joystick class<br />
 +
<big>
 +
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);
 +
 +
</big>
 +
 
 +
In '''Input.cpp''', add the following to the Joystick constructor
 +
<big>
 +
  ffEffects = NULL;
 +
  centre = NULL;
 +
  feedBackOFF = 0;
 +
</big>
 +
 
 +
add this in Joystick::interrogate function:
 +
<big>
 +
  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);
 +
      }
 +
</big>
 +
 
 +
add this in Joystick::setup function:
 +
<big>
 +
  feedBackOFF = !!(flags & 8);
 +
</big>
 +
 
 +
change the SetCooperativeLevel in setup to check for device exclusivity
 +
<big>
 +
    else if (FAILED(joystick->SetCooperativeLevel((HWND)hwnd,
 +
  (feedBackOFF ? DISCL_NONEXCLUSIVE : DISCL_EXCLUSIVE) | DISCL_FOREGROUND)))
 +
</big>
 +
 
 +
add this line after (!zAxisOn)
 +
<big>
 +
if(feedBackOFF)
 +
    centre = NULL;
 +
</big>
 +
 
 +
add these in the restore function:
 +
<big>
 +
else{
 +
if(ffEffects){
 +
    ffEffects->Download();
 +
}
 +
if(centre){
 +
    centre->Download();
 +
    centre->Start(1,0);
 +
}
 +
</big>
 +
 
 +
 
 +
add this function in:
 +
<big>
 +
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 = &die;
 +
            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 = &die;
 +
            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();
 +
                }
 +
            }
 +
        }
 +
    }
 +
}
 +
</big>
 +
 
 +
Add this to release:
 +
<big>
 +
if(centre){
 +
    centre->Release();
 +
    centre = NULL;
 +
}
 +
if(ffEffects){
 +
    ffEffects->Release();
 +
    ffEffects = NULL;
 +
}
 +
</big>
 +
 
 +
In '''UserDialog.cpp''':
 +
In the saveUserChoices function, add another bool called ff:
 +
<big>
 +
bool y, z, '''ff''', none;
 +
</big>
 +
 
 +
Add this line after the y and z are retrieved
 +
<big>
 +
ff = SendDlgItemMessage(hwnd, IDC_NOFF, BM_GETCHECK, 0, 0) != BST_CHECKED;
 +
</big>
 +
 
 +
Add this in the else statement after y = z = false;
 +
<big>
 +
ff = true;
 +
</big>
 +
 
 +
Change the flags being set after:
 +
<big>
 +
        flags = ((y ? 1 : 0) << 2) | ((z ? 1 : 0) << 1) '''| ((ff ? 0 : 1) << 3)''' | (none ? 1 : 0);
 +
</big>
 +
 
 +
in '''iDesign.h''', add these to the iDesign class:
 +
<big>
 +
    virtual bool sendForce(bool) = 0;
 +
    virtual void setForceTime(double) = 0;
 +
    virtual double  getForceTime() = 0;
 +
    virtual void  setForceDir(int) = 0;
 +
    virtual int    getForceDir() = 0;
 +
    virtual void  setForceFactor(float) = 0;
 +
    virtual float    getForceFactor() = 0;
 +
</big>
 +
 
 +
in '''Design.h''', add these to the Design class:
 +
<big>
 +
  private:
 +
    float fFactor;
 +
    double fTime;
 +
    int fDirection;
 +
 
 +
  public:
 +
    bool  sendForce(bool);
 +
    void  setForceTime(double);
 +
    double getForceTime();
 +
    void  setForceDir(int);
 +
    int    getForceDir();
 +
    void  setForceFactor(float);
 +
    float  getForceFactor();
 +
</big>
 +
 
 +
In '''Design.cpp''' constructor, add these default values:
 +
<big>
 +
    fTime = 0.1;
 +
    fFactor = 1.0f;
 +
    fDirection = 45;
 +
</big>
 +
 
 +
You can then use these in Design::update function
 +
<big>
 +
    setForceTime(double);
 +
    setForceDir(int);
 +
    setForceFactor(float);
 +
    sendForce(bool);
 +
    context->set(GF_CT_RMBL, int(0 or 1));
 +
</big>
 +
 
 +
Add these functions in '''Design.cpp'''
 +
<big>
 +
bool Design::sendForce(bool force)
 +
{
 +
    return force;
 +
}
  
== Force Feedback ==
+
void Design::setForceTime(double time)
 +
{
 +
    fTime = time;
 +
}
 +
 
 +
double Design::getForceTime()
 +
{
 +
    if(fTime != 0.0)
 +
        return fTime;
 +
}
 +
 
 +
void Design::setForceDir(int fctr)
 +
{
 +
    fDirection = fctr;
 +
}
 +
 
 +
int Design::getForceDir()
 +
{
 +
    return fDirection;
 +
}
  
 +
void Design::setForceFactor(float)
 +
{
 +
    fFactor = 1.0f;
 +
}
  
 +
float Design::getForceFactor()
 +
{
 +
    return fFactor;
 +
}
 +
</big>
  
[[Category:force feedback]]
+
In '''Engine.cpp''', add this to run method:
 +
<big>
 +
    joystick->updateForce(design->getForceFactor(), design->getForceTime(), design->getForceDir());
 +
</big>

Latest revision as of 13:46, 7 April 2011

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 in Configuration.h:

GF_CT_RMBL

In iInput.h:
add line 1 in the iJoystick class
In Input.h:
add line 2 in the Joystick class
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 = &die;
           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 = &die;
           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 called ff:

bool y, z, ff, none;

Add this line after the y and z are retrieved

ff = SendDlgItemMessage(hwnd, IDC_NOFF, BM_GETCHECK, 0, 0) != BST_CHECKED;

Add this in the else statement after y = z = false;

ff = true;

Change the flags being set after:

        flags = ((y ? 1 : 0) << 2) | ((z ? 1 : 0) << 1) | ((ff ? 0 : 1) << 3) | (none ? 1 : 0);

in iDesign.h, add these to the iDesign class:

   virtual bool sendForce(bool) = 0;
   virtual void setForceTime(double) = 0;
   virtual double  getForceTime() = 0;
   virtual void   setForceDir(int) = 0;
   virtual int    getForceDir() = 0;
   virtual void   setForceFactor(float) = 0;
   virtual float    getForceFactor() = 0;

in Design.h, add these to the Design class:

 private:
   float fFactor;
   double fTime;
   int fDirection;
 public:
   bool   sendForce(bool);
   void   setForceTime(double);
   double getForceTime();
   void   setForceDir(int);
   int    getForceDir();
   void   setForceFactor(float);
   float  getForceFactor();

In Design.cpp constructor, add these default values:

   fTime = 0.1;
   fFactor = 1.0f;
   fDirection = 45;

You can then use these in Design::update function

   setForceTime(double);
   setForceDir(int);
   setForceFactor(float);
   sendForce(bool);
   context->set(GF_CT_RMBL, int(0 or 1));

Add these functions in Design.cpp

bool Design::sendForce(bool force)
{
   return force;
}
void Design::setForceTime(double time)
{
   fTime = time;
}
double Design::getForceTime()
{
   if(fTime != 0.0)
       return fTime;
}
void Design::setForceDir(int fctr)
{
   fDirection = fctr;
}
int Design::getForceDir()
{
   return fDirection;
}
void Design::setForceFactor(float)
{
   fFactor = 1.0f;
}
float Design::getForceFactor()
{
   return fFactor;
}

In Engine.cpp, add this to run method:

   joystick->updateForce(design->getForceFactor(), design->getForceTime(), design->getForceDir());