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-1: Determining supported effect parameters
    var

      frmSupFxParams: TfrmSupFxParams;

      FDirectInput: IDirectInput;

      FDirectInputDevice: IDirectInputDevice2;

      {these are used to create our on-the-fly device data format}

      FDataFormat: TDIDataFormat;

      FDataFormatObjects: array[0..255] of TDIObjectDataFormat;

      FDataFormatGUIDs: array[0..255] of TGUID;

      {these just track present axes}

      FAxisList: array[0..255] of Integer;

      NumAxes: Integer;

    implementation

    uses DXTools, frmDevicesU;

    function EnumInputDevs(var lpddi: TDIDeviceInstance; pvRef: Pointer): Integer;

                                                                          stdcall;

    var

      TempGuid: PGuid;

    begin

      {we must save this guid in a separate list for use later when we

       create the device}

      New(TempGuid);

      TempGuid^ := lpddi.guidInstance;

      {display device information}

      TStringList(pvRef).AddObject(lpddi.tszInstanceName+’-’+lpddi.tszProductName,

                                   TObject(TempGuid));

      {continue enumeration}

      Result := 1;

    end;

    procedure SetDataFormat;

      function DIEnumDeviceObjectsProc(const peff: TDIDeviceObjectInstance;

        pvRef: Pointer): HRESULT; stdcall;

      begin

        {if the offset is not beyond the indicated data size... (useful if

         we were to use the TDIJoyState data structure instead) }

        if peff.dwOfs<FDataFormat.dwDataSize then

        begin

          {save the type GUID for this object}

          FDataFormatGUIDs[FDataFormat.dwNumObjs] := peff.guidType;

          {add the object information to our custom made

           data format}

          with FDataFormatObjects[FDataFormat.dwNumObjs] do

          begin

            pguid := @FDataFormatGUIDs[FDataFormat.dwNumObjs];

            dwOfs := peff.dwOfs;

            dwType := peff.dwType;

            dwFlags := 0;

          end;

          {if this object is an axis, store it in our axis list}

          if (peff.dwType and DIDFT_AXIS) > 0 then

          begin

            FAxisList[NumAxes] := peff.dwOfs;

            Inc(NumAxes);

          end;

          {increment the number of objects found}

          Inc(FDataFormat.dwNumObjs);

        end;

        {continue enumeration}

        Result := DIENUM_CONTINUE;

      end;

    begin

      {enumerate all objects on this input device. this will build our custom data

       structure programmatically with the correct information for each object}

      FDirectInputDevice.EnumObjects(@DIEnumDeviceObjectsProc, nil, DIDFT_ALL);

      {set the data format for the input device}

      DXCheck( FDirectInputDevice.SetDataFormat(FDataFormat) );

    end;

    procedure TfrmSupFxParams.FormActivate(Sender: TObject);

    var

      FJoyList: TStringList;

      iCount: Integer;

      TempDevice: IDirectInputDevice;

      RangeProp: TDIPropRange;

      DataProp: TDIPropDWord;

      EffectInfo: TDIEffectInfoA;

    begin

      {create the DirectInput object}

      DirectInputCreate(hInstance, DIRECTINPUT_VERSION, FDirectInput, nil);

      {create a list to hold information on each available game controller}

      FJoyList := TStringList.Create;

      {enumerate attached game controllers}

      //*** may want to cull out only those with force feedback here

      FDirectInput.EnumDevices(DIDEVTYPE_JOYSTICK, EnumInputDevs, FJoyList,

                               DIEDFL_ATTACHEDONLY);

      {we’ll add this information to a list box in a dialog box, and display this

       to the user so they can choose their desired input controller}

      frmDevices := TfrmDevices.Create(Self);

      for iCount := 0 to FJoyList.Count-1 do

        frmDevices.lbxJoyDevices.Items.Add(FJoyList[iCount]);

      frmDevices.ShowModal;

      {create the input device based on the input controller specified by the user}

      DXCheck( FDirectInput.CreateDevice(PGUID(FJoyList.Objects[0])^,

                                         TempDevice, nil) );

      {close this dialog box, and delete the list of GUIDs}

      frmDevices.Release;

      for iCount := 0 to FJoyList.Count-1 do

        Dispose(PGUID(FJoyList.Objects[0]));

      FJoyList.Free;

      {we need the new version of the input device interface, so retrieve it}

      try

        DXCheck(TempDevice.QueryInterface(IDirectInputDevice2,FDirectInputDevice));

      finally

        TempDevice := nil

      end;

      {now we need to begin creating the data format structure and setting the

       data format, so we must initialize the overall data format structure}

      with FDataFormat do

      begin

        dwFlags := DIDF_ABSAXIS;

        dwDataSize := SizeOf(TDIJoyState2);

        dwSize := SizeOf(FDataFormat);

        dwObjSize := SizeOf(TDIObjectDataFormat);

        dwNumObjs := 0;

        rgodf := @FDataFormatObjects;

      end;

      {create and set a data format specifically made for this device}

      SetDataFormat;

      {we must now set the range for each axis, so initialize a range

       property structure}

      RangeProp.diph.dwSize := SizeOf(TDIPropRange);

      RangeProp.diph.dwHeaderSize := SizeOf(TDIPropHeader);

      RangeProp.diph.dwHow := DIPH_BYOFFSET;

      RangeProp.lMin := -1000;

      RangeProp.lMax := 1000;

      {we must also set deadzones and saturations for each axis, so

       initialize a DWord property structure}

      DataProp.diph.dwSize := SizeOf(TDIPropDWord);

      DataProp.diph.dwHeaderSize := SizeOf(TDIPropHeader);

      DataProp.diph.dwHow := DIPH_BYOFFSET;

      {for each axis...}

      for iCount := 0 to NumAxes-1 do

      begin

        {set its range...}

        RangeProp.diph.dwObj := FAxisList[iCount];

        DXCheck( FDirectInputDevice.SetProperty(DIPROP_RANGE, RangeProp.diph) );

        {its deadzone... (this value is in 100ths of a percent)}

        DataProp.dwData := 1000;

        DataProp.diph.dwObj := FAxisList[iCount];

        DXCheck( FDirectInputDevice.SetProperty(DIPROP_DEADZONE, DataProp.diph) );

        {and its saturation (this value is also in 100ths of a percent)}

        DataProp.dwData := 9000;

        DXCheck( FDirectInputDevice.SetProperty(DIPROP_SATURATION,DataProp.diph));

      end;

      {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 effect information structure}

      FillChar(EffectInfo, SizeOf(TDIEffectInfoA), 0);

      EffectInfo.dwSize := SizeOf(TDIEffectInfoA);

      {retrieve effect information for constant forces}

      FDirectInputDevice.GetEffectInfo(EffectInfo, GUID_ConstantForce);

      {begin displaying supported TDIEffect parameters}

      lbxEffectInfo.Items.Add(Effect Name: +EffectInfo.tszName);

      lbxEffectInfo.Items.Add(’);

      lbxEffectInfo.Items.Add(Supported TDIEffect Members:’);

      if (EffectInfo.dwStaticParams and DIEP_DURATION) = DIEP_DURATION then

        lbxEffectInfo.Items.Add(     dwDuration’);

      if (EffectInfo.dwStaticParams and DIEP_SAMPLEPERIOD) =

          DIEP_SAMPLEPERIOD then

        lbxEffectInfo.Items.Add(     dwSamplePeriod’);

      if (EffectInfo.dwStaticParams and DIEP_GAIN) = DIEP_GAIN then

        lbxEffectInfo.Items.Add(     dwGain’);

      if (EffectInfo.dwStaticParams and DIEP_TRIGGERBUTTON) =

          DIEP_TRIGGERBUTTON then

        lbxEffectInfo.Items.Add(     dwTriggerButton’);

      if (EffectInfo.dwStaticParams and DIEP_TRIGGERREPEATINTERVAL) =

          DIEP_TRIGGERREPEATINTERVAL then

        lbxEffectInfo.Items.Add(     dwTriggerRepeatInterval’);

      if (EffectInfo.dwStaticParams and DIEP_AXES) = DIEP_AXES then

        lbxEffectInfo.Items.Add(     cAxes’);

      if (EffectInfo.dwStaticParams and DIEP_DIRECTION) = DIEP_DIRECTION then

        lbxEffectInfo.Items.Add(     rglDirection’);

      if (EffectInfo.dwStaticParams and DIEP_ENVELOPE) = DIEP_ENVELOPE then

        lbxEffectInfo.Items.Add(     lpEnvelope’);

    end;
Figure 8-3: Microsoft SideWinder Force Feedback Pro supported parameters
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.