Difference between revisions of "User:Satijas"

From CDOT Wiki
Jump to: navigation, search
 
(7 intermediate revisions by the same user not shown)
Line 3: Line 3:
  
 
Hi, my name is Sasha. I'm in GAM670
 
Hi, my name is Sasha. I'm in GAM670
 
[[Category:about]]
 
  
 
== Force Feedback ==
 
== Force Feedback ==
  
Add this to WindowSettings.h:
+
Add this to '''WindowSettings.h''':
 
<big>
 
<big>
 
   
 
   
Line 14: Line 12:
 
</big>
 
</big>
  
Add this in typedef enum Integer:
+
Add this in typedef enum Integer in '''Configuration.h''':
 
<big>
 
<big>
 
  GF_CT_RMBL
 
  GF_CT_RMBL
 
</big>
 
</big>
  
In iInput.h, add line 1 in the iJoystick class
+
In '''iInput.h''':<br />
In Input.h, add line 2 in the Joystick class
+
add line 1 in the iJoystick class<br />
In Input.h, add line 3 in the Joystick class
+
In '''Input.h''':<br />
 +
add line 2 in the Joystick class<br />
 +
add line 3 in the Joystick class<br />
 
<big>
 
<big>
 
  1.
 
  1.
Line 37: Line 37:
 
</big>
 
</big>
  
In Input.cpp, add the following to the Joystick constructor
+
In '''Input.cpp''', add the following to the Joystick constructor
 
<big>
 
<big>
 
   ffEffects = NULL;
 
   ffEffects = NULL;
Line 113: Line 113:
 
             DIPERIODIC dip;
 
             DIPERIODIC dip;
 
             DIENVELOPE die;
 
             DIENVELOPE die;
 
+
 
             // if both x & y have FF, make shake come at 45 degree angle
 
             // if both x & y have FF, make shake come at 45 degree angle
 
             // otherwise just shake the x axis.
 
             // otherwise just shake the x axis.
Line 135: Line 135:
 
             dif.lpvTypeSpecificParams = &dip;
 
             dif.lpvTypeSpecificParams = &dip;
 
             dif.dwStartDelay = 3 * DI_SECONDS; // 3 secs
 
             dif.dwStartDelay = 3 * DI_SECONDS; // 3 secs
 
+
 
             dip.dwMagnitude = 3 * DI_FFNOMINALMAX / 10;
 
             dip.dwMagnitude = 3 * DI_FFNOMINALMAX / 10;
 
             dip.lOffset  = 0;
 
             dip.lOffset  = 0;
 
             dip.dwPhase  = 0;
 
             dip.dwPhase  = 0;
 
             dip.dwPeriod = DI_SECONDS / 10; // 1/10th second
 
             dip.dwPeriod = DI_SECONDS / 10; // 1/10th second
 
+
 
             die.dwSize = sizeof die;
 
             die.dwSize = sizeof die;
 
             die.dwAttackLevel = factor;
 
             die.dwAttackLevel = factor;
Line 147: Line 147:
 
             die.dwFadeTime    = DI_SECONDS / 2;
 
             die.dwFadeTime    = DI_SECONDS / 2;
 
             HRESULT hr = joystick->CreateEffect(GUID_Square, &dif, &ffEffects, NULL);
 
             HRESULT hr = joystick->CreateEffect(GUID_Square, &dif, &ffEffects, NULL);
 
+
 
             // create a ramp force
 
             // create a ramp force
 
             DIRAMPFORCE dirf;
 
             DIRAMPFORCE dirf;
Line 171: Line 171:
 
             dif.lpvTypeSpecificParams = &dirf;
 
             dif.lpvTypeSpecificParams = &dirf;
 
             dif.dwStartDelay = 0.01 * DI_SECONDS;
 
             dif.dwStartDelay = 0.01 * DI_SECONDS;
 
+
 
             dirf.lStart = DI_FFNOMINALMAX / 2;
 
             dirf.lStart = DI_FFNOMINALMAX / 2;
 
             dirf.lEnd  = - DI_FFNOMINALMAX / 2;
 
             dirf.lEnd  = - DI_FFNOMINALMAX / 2;
 
+
 
             die.dwSize = sizeof die;
 
             die.dwSize = sizeof die;
 
             die.dwAttackLevel = DI_FFNOMINALMAX / 50;
 
             die.dwAttackLevel = DI_FFNOMINALMAX / 50;
Line 180: Line 180:
 
             die.dwFadeLevel  = DI_FFNOMINALMAX / 10;
 
             die.dwFadeLevel  = DI_FFNOMINALMAX / 10;
 
             die.dwFadeTime    = time * DI_SECONDS / 2;
 
             die.dwFadeTime    = time * DI_SECONDS / 2;
 
+
 
             if (SUCCEEDED(joystick->CreateEffect(GUID_RampForce, &dif,
 
             if (SUCCEEDED(joystick->CreateEffect(GUID_RampForce, &dif,
 
             &ffEffects, NULL))){
 
             &ffEffects, NULL))){
Line 212: Line 212:
 
</big>
 
</big>
  
In UserDialog.cpp:
+
In '''UserDialog.cpp''':
In the saveUserChoices function, add another bool:
+
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>
 
<big>
  bool y, z, <b>ff</b>, none;
+
    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>
 
</big>
  
 +
in '''Design.h''', add these to the Design class:
 
<big>
 
<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>
 
</big>
  
 +
In '''Design.cpp''' constructor, add these default values:
 
<big>
 
<big>
 +
    fTime = 0.1;
 +
    fFactor = 1.0f;
 +
    fDirection = 45;
 
</big>
 
</big>
  
 +
You can then use these in Design::update function
 
<big>
 
<big>
 +
    setForceTime(double);
 +
    setForceDir(int);
 +
    setForceFactor(float);
 +
    sendForce(bool);
 +
    context->set(GF_CT_RMBL, int(0 or 1));
 
</big>
 
</big>
  
[[Category:force feedback]]
+
Add these functions in '''Design.cpp'''
 +
<big>
 +
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;
 +
}
 +
</big>
 +
 
 +
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());