Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
Listing 8-3: Creating force feedback effects
    var

       .

       .

       .

      {these hold all of the different effects}

      PeriodicEffect,

      RampEffect,

      ConstantEffect,

      ConditionEffect,

      DeviceEffect,

      CustomEffect: IDirectInputEffect;

       .

       .

       .

      {global effect info structures}

      AxisArray: array[0..1] of DWORD;

      DirArray: array[0..1] of longint;

      EffectInfo: TDIEffect;

    implementation

    uses DXTools, frmDevicesU;

       .

       .

       .

    function EnumEffects(var pdei: TDIEffectInfoA; pvRef: pointer) : Integer; stdcall;

    var

      TempGuid: PGuid;

    begin

      {filter out any effects that have adjustable type-specific parameters}

      if (pdei.dwStaticParams and DIEP_TYPESPECIFICPARAMS) =

          DIEP_TYPESPECIFICPARAMS then

      begin

        Result := 1;

        Exit;

      end;

      {create a new guid and save the guid info}

      New(TempGuid);

      TempGuid^ := pdei.guid;

      {add the name of the effect and its guid to the list box}

      frmEffectTest.lbxDevEffects.Items.AddObject(pdei.tszName, TObject(TempGuid));

      {continue enumeration}

      Result := 1;

    end;

       .

       .

       .

    procedure TfrmEffectTest.FormActivate(Sender: TObject);

    begin

       .

       .

       .

      {set the cooperative level.}

      DXCheck( FDirectInputDevice.SetCooperativeLevel(Handle, DISCL_EXCLUSIVE

                                                      or DISCL_FOREGROUND) );

      {finally, acquire the device so we can start retrieving information}

      DXCheck( FDirectInputDevice.Acquire );

      {initialize the global axis array. we’ll set it up to affect the

       X and Y axis of a joystick}

      AxisArray[0] := DIJOFS_X;

      AxisArray[1] := DIJOFS_Y;

      {indicate the direction of the effects. we’ll be using polar coordinates

       so we’ll indicate a 180 degree direction}

      DirArray[0] := 180*DI_DEGREES;

      DirArray[1] := 0;

      {enumerate all hardware-specific effects}

      FDirectInputDevice.EnumEffects(EnumEffects, nil, DIEFT_HARDWARE);

    end;

    procedure TfrmEffectTest.btnPeriodicClick(Sender: TObject);

    var

      PeriodicInfo: TDIPeriodic;

    begin

      {turn off the device effects list box and reset the force feedback device}

      lbxDevEffects.Visible := FALSE;

      FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

      {set up our periodic effect parameters}

      PeriodicInfo.dwMagnitude := DI_FFNOMINALMAX;

      PeriodicInfo.lOffset := 0;

      PeriodicInfo.dwPhase := 0;

      PeriodicInfo.dwPeriod := DI_SECONDS div 20;

      {set up general parameters for the periodic effect}

      EffectInfo.dwSize := SizeOf(TDIEffect);

      EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

      EffectInfo.dwDuration := INFINITE;                // repeat indefinitely

      EffectInfo.dwSamplePeriod := 0;

      EffectInfo.dwGain := DI_FFNOMINALMAX;

      EffectInfo.dwTriggerButton := DIJOFS_BUTTON0;     // tie it to button 0

      EffectInfo.dwTriggerRepeatInterval := INFINITE;

      EffectInfo.cAxes := 2;

      EffectInfo.rgdwAxes := @AxisArray;

      EffectInfo.rglDirection := @DirArray;

      EffectInfo.lpEnvelope := nil;

      EffectInfo.cbTypeSpecificParams := SizeOf(TDIPeriodic);

      EffectInfo.lpvTypeSpecificParams := @PeriodicInfo;

      {create the periodic effect}

      FDirectInputDevice.CreateEffect(GUID_sine, @EffectInfo, PeriodicEffect, nil);

    end;

    procedure TfrmEffectTest.btnRampClick(Sender: TObject);

    var

      RampInfo: TDIRampForce;

    begin

      {turn off the device effects list box and reset the force feedback device}

      lbxDevEffects.Visible := FALSE;

      FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

      {set up our ramp effect parameters}

      RampInfo.lStart := -DI_FFNOMINALMAX;

      RampInfo.lEnd := DI_FFNOMINALMAX;

      {set up general parameters for the ramp effect}

      EffectInfo.dwSize := SizeOf(TDIEffect);

      EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

      EffectInfo.dwDuration := DI_SECONDS div 2;        // half second duration

      EffectInfo.dwSamplePeriod := 0;

      EffectInfo.dwGain := DI_FFNOMINALMAX;

      EffectInfo.dwTriggerButton := DIJOFS_BUTTON0;     // tie it to button 0

      EffectInfo.dwTriggerRepeatInterval := 0;

      EffectInfo.cAxes := 2;

      EffectInfo.rgdwAxes := @AxisArray;

      EffectInfo.rglDirection := @DirArray;

      EffectInfo.lpEnvelope := nil;

      EffectInfo.cbTypeSpecificParams := SizeOf(TDIRampForce);

      EffectInfo.lpvTypeSpecificParams := @RampInfo;

      {create the ramp effect}

      FDirectInputDevice.CreateEffect(GUID_RampForce, @EffectInfo, RampEffect,nil);

    end;

    procedure TfrmEffectTest.btnConstantClick(Sender: TObject);

    var

      ConstantInfo: TDIConstantForce;

    begin

      {turn off the device effects list box and reset the force feedback device}

      lbxDevEffects.Visible := FALSE;

      FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

      {set up our constant effect parameters}

      ConstantInfo.lMagnitude := DI_FFNOMINALMAX;

      {set up general parameters for the constant effect}

      EffectInfo.dwSize := SizeOf(TDIEffect);

      EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

      EffectInfo.dwDuration := DI_SECONDS div 2;        // half second duration

      EffectInfo.dwSamplePeriod := 0;

      EffectInfo.dwGain := DI_FFNOMINALMAX;

      EffectInfo.dwTriggerButton := DIJOFS_BUTTON0;     // tie it to button 0

      EffectInfo.dwTriggerRepeatInterval := 0;

      EffectInfo.cAxes := 2;

      EffectInfo.rgdwAxes := @AxisArray;

      EffectInfo.rglDirection := @DirArray;

      EffectInfo.lpEnvelope := nil;

      EffectInfo.cbTypeSpecificParams := SizeOf(TDIConstantForce);

      EffectInfo.lpvTypeSpecificParams := @ConstantInfo;

      {create the constant effect}

      FDirectInputDevice.CreateEffect(GUID_ConstantForce, @EffectInfo,

                                      ConstantEffect, nil);

    end;

    procedure TfrmEffectTest.btnConditionClick(Sender: TObject);

    var

      ConditionInfo: array[0..1] of TDICondition;

      DirArray: array[0..1] of longint;

    begin

      {turn off the device effects list box and reset the force feedback device}

      lbxDevEffects.Visible := FALSE;

      FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

      {for a condition, we don’t really want a direction, so empty

       the direction array}

      DirArray[0] := 0;

      DirArray[1] := 0;

      {set up our condition effect parameters for the first axis}

      ConditionInfo[0].lOffset := 0;

      ConditionInfo[0].lPositiveCoefficient := DI_FFNOMINALMAX;

      ConditionInfo[0].lNegativeCoefficient := DI_FFNOMINALMAX;

      ConditionInfo[0].dwPositiveSaturation := 0;

      ConditionInfo[0].dwNegativeSaturation := 0;

      ConditionInfo[0].lDeadBand := 0;

      {set up our condition effect parameters for the second axis}

      ConditionInfo[1].lOffset := 0;

      ConditionInfo[1].lPositiveCoefficient := DI_FFNOMINALMAX;

      ConditionInfo[1].lNegativeCoefficient := DI_FFNOMINALMAX;

      ConditionInfo[1].dwPositiveSaturation := 0;

      ConditionInfo[1].dwNegativeSaturation := 0;

      ConditionInfo[1].lDeadBand := 0;

      {set up general parameters for the condition effect}

      EffectInfo.dwSize := SizeOf(TDIEffect);

      EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

      EffectInfo.dwDuration := INFINITE;                // infinite duration

      EffectInfo.dwSamplePeriod := 0;

      EffectInfo.dwGain := DI_FFNOMINALMAX;

      EffectInfo.dwTriggerButton := DIEB_NOTRIGGER;     // not tied to a button

      EffectInfo.dwTriggerRepeatInterval := 0;

      EffectInfo.cAxes := 2;

      EffectInfo.rgdwAxes := @AxisArray;

      EffectInfo.rglDirection := @DirArray;

      EffectInfo.lpEnvelope := nil;

      {notice that here we’ve got to indicate the size of the entire array}

      EffectInfo.cbTypeSpecificParams := 2*SizeOf(TDICondition);

      EffectInfo.lpvTypeSpecificParams := @ConditionInfo;

      {create the condition effect}

      FDirectInputDevice.CreateEffect(GUID_Friction, @EffectInfo, ConditionEffect,

                                      nil);

      {start the condition effect, killing all other effects currently playing}

      ConditionEffect.Start(1, DIES_SOLO);

    end;

    procedure TfrmEffectTest.btnDeviceClick(Sender: TObject);

    begin

      {simply make the device effects list box visible}

      lbxDevEffects.Visible := TRUE;

    end;

    procedure TfrmEffectTest.lbxDevEffectsClick(Sender: TObject);

    begin

      if lbxDevEffects.ItemIndex > -1 then

      begin

        {reset the force feedback device}

        FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

        {set up general parameters for the device-specific effect}

        EffectInfo.dwSize := SizeOf(TDIEffect);

        EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

        EffectInfo.dwDuration := DI_SECONDS*2;          // half second duration

        EffectInfo.dwSamplePeriod := 0;

        EffectInfo.dwGain := DI_FFNOMINALMAX;

        EffectInfo.dwTriggerButton := DIJOFS_BUTTON0;   // tied to button 0

        EffectInfo.dwTriggerRepeatInterval := 0;

        EffectInfo.cAxes := 2;

        EffectInfo.rgdwAxes := @AxisArray;

        EffectInfo.rglDirection := @DirArray;

        EffectInfo.lpEnvelope := nil;

        {we only play effects that do not have adjustable type-specific parameters,

         so we indicate such in the TDIEffect structure}

        EffectInfo.cbTypeSpecificParams := 0;

        EffectInfo.lpvTypeSpecificParams := nil;

        {create the device-specific effect}

        FDirectInputDevice.CreateEffect(PGuid(lbxDevEffects.Items.Objects

                       [lbxDevEffects.ItemIndex])^, @EffectInfo, DeviceEffect, nil);

      end;

    end;

    procedure TfrmEffectTest.btnCustomClick(Sender: TObject);

    var

      CustomInfo: TDICustomForce;

      MagnitudeArray: array[0..3] of longint;

    begin

      {turn off the device effects list box and reset the force feedback device}

      lbxDevEffects.Visible := FALSE;

      FDirectInputDevice.SendForceFeedbackCommand(DISFFC_RESET);

      {set up our array of magnitudes for the custom effect. this will create

       an increasing oscillation}

      MagnitudeArray[0] := -DI_FFNOMINALMAX div 4;

      MagnitudeArray[1] := DI_FFNOMINALMAX div 2;

      MagnitudeArray[2] := 0-(DI_FFNOMINALMAX div 4) * 3;

      MagnitudeArray[3] := DI_FFNOMINALMAX;

      {set up our custom effect parameters}

      CustomInfo.cChannels := 1;

      CustomInfo.dwSamplePeriod := 100000;

      CustomInfo.cSamples := 4;

      CustomInfo.rglForceData := @MagnitudeArray;

      {set up general parameters for the custom effect}

      EffectInfo.dwSize := SizeOf(TDIEffect);

      EffectInfo.dwFlags := DIEFF_OBJECTOFFSETS or DIEFF_POLAR;

      EffectInfo.dwDuration := INFINITE;                // infinite duration

      EffectInfo.dwSamplePeriod := 100000;              // sample periods the same

      EffectInfo.dwGain := DI_FFNOMINALMAX;

      EffectInfo.dwTriggerButton := DIJOFS_BUTTON0;     // tied to button 0

      EffectInfo.dwTriggerRepeatInterval := 0;

      EffectInfo.cAxes := 2;

      EffectInfo.rgdwAxes := @AxisArray;

      EffectInfo.rglDirection := @DirArray;

      EffectInfo.lpEnvelope := nil;

      EffectInfo.cbTypeSpecificParams := SizeOf(TDICustomForce);

      EffectInfo.lpvTypeSpecificParams := @CustomInfo;

      {create the custom effect}

      dxcheck(FDirectInputDevice.CreateEffect(GUID_CustomForce, @EffectInfo,

    CustomEffect, nil));

    end;
Previous | Table of Contents | Next

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.