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
#### Direction Direction can be a complicated concept when it comes to force feedback. Bear in mind that the force feedback API was designed to work not only with such devices as joysticks, but with other devices like steering wheels, throttle controls, and devices that can move in three dimensions. In a nutshell, direction determines the bearing of an effect along an axis (or axes) when its magnitude or coefficient values are positive. Negative values act in the opposite of the defined direction. Single axis directions are easily handled, as you can simply control the sign of the magnitude or coefficient in order to define the direction. In the case of multiple axes, however, there are three available coordinate systems: spherical, polar, and Cartesian. The Cartesian coordinate system may be useful if force feedback is being used in conjunction with Direct3D. The spherical coordinate system is necessary for defining the direction of an effect on three or more axes of movement. Since our discussion is focused on joystick programming, however, we’ll use the polar coordinate system. The polar coordinate system is perhaps the easiest to use, as it requires only the compass direction of the force, measured in hundredths of a degree. The DI_DEGREES constant is defined in the DInput unit, and can be used to easily specify a direction in terms of degrees. Bear in mind that the direction of a force is in terms of the direction from which the force originates. For example, a force from the north would push the stick toward the user, and would thus have a direction of zero. A force from the west, pushing the stick to the right, would have a direction of 90 * DI_DEGREES. The following illustration graphically explains the concept of direction as it applies to a joystick. Figure 8-2: Forcefeedback direction #### Envelope An envelope is a set of values that modify the magnitude of a force at the beginning and end of playback, and can be applied to all forces except conditions. This allows a developer to define the attack and fade of a force, like a musical note. We’ll examine envelopes in greater detail later in the chapter.
| envelope: A series of values that shape a force at the beginning and end of playback.
### Force Feedback Effects Force feedback effects are divided into six different categories: conditions, constant forces, periodic forces, ramp forces, device-specific effects, and custom forces. Each one of these is defined by an overall basic effect structure, which describes certain global attributes for the effect such as duration and direction, and a more type-specific structure, which describes very specific effect attributes depending on its category. Some of these categories even have subtypes. This makes for a rather complex system, but it should be more than adequate for just about any tactile feedback desired. #### Base Effect Structure All force feedback effects are defined by a primary structure called TDIEffect. This structure is used when creating the effect as well as modifying the effect after it has been created. This complex structure defines the overall parameters of the effect and includes members that hold other structures that further define the effect, and are dependent on the type of effect desired. The TDIEffect structure is defined as:
    TDIEffect = packed record

      dwSize : DWORD;                   // the size of the structure, in bytes

      dwFlags : DWORD;                  // indicates the directional coordinate

                                           system and axes/button identification

      dwDuration : DWORD;               // duration of the effect in microseconds

      dwSamplePeriod : DWORD;           // the sample period, in microseconds

      dwGain : DWORD;                   // the gain for the specific effect

      dwTriggerButton : DWORD;          // trigger button identifier

      dwTriggerRepeatInterval : DWORD;  // repetition interval, in microseconds

      cAxes : DWORD;                    // number of axes involved in the effect

      rgdwAxes : ^DWORD;                // array of axis identifiers

      rglDirection : ^longint;          // array of direction bearings

      lpEnvelope : PDIEnvelope;         // pointer to a TDIEnvelope structure

      cbTypeSpecificParams : DWORD;     // the size of the structure in the

                                           lpvTypeSpecificParams member

      lpvTypeSpecificParams : pointer;  // pointer to type-specific data structure

    end;
As usual with all DirectX data structures, the dwSize member should be set to SizeOf(TDIEffect). The dwFlags member indicates both the directional coordinate system as well as the method by which axes and buttons are to be identified. For our purposes, we’ll use the values DIEFF_POLAR to indicate a polar coordinate system and DIEFF_OBJECTOFFSETS to indicate button and axis data format offsets (using the OR operator to combine them). Most of the other members, such as duration, sample period, and gain, correspond directly to the concepts covered earlier, and should be set accordingly. The dwTriggerButton member indicates the button that will start the effect. This member can be set to a button offset (i.e., DIJOFS_BUTTON1) or DIEB_NOTRIGGER, indicating that the effect is not triggered. Assigning a value to dwTriggerRepeatInterval will cause the effect to be repeated as long as the button is held down (if supported). The cAxes member should be set to the number of axes involved in the effect, and the rgdwAxes member should point to an array of DWORDs, with each member holding a DIJOFS_* constant for each individual axis. The rglDirection member is a pointer to an array of longints that define the direction of the effect. There must be cAxes members in this array, but for the polar coordinate system, the bearing is stored in the first member, and the last member (remember, we’re only using two axes) is set to zero. The lpEnvelope member points to a TDIEnvelope structure, which we’ll discuss in more detail shortly. Finally, the cbTypeSpecificParams should be set to the size, in bytes, of the data structure pointed to by the lpvTypeSpecificParams member. This data structure is dependent on the type of desired effect; we’ll take a closer look at each effect type below, and examine their individual type-specific parameter data structures.
| Note: If two or more effects are assigned to a button, the last one downloaded to the device will be the one triggered.
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.