//----------------------------------------------------------------------------- // File: ForceFeedback.h // Contains: Public interfaces for Force Feedback technology. // Copyright: © 2002-2003 by Apple Computer, Inc. All rights reserved. // //----------------------------------------------------------------------------- #ifndef _FORCEFEEDBACK_H_ #define _FORCEFEEDBACK_H_ #if PRAGMA_ONCE #pragma once #endif // 10.4 (8A414) Headers - using CodeWarrior 9.4 ForceFeedback.h gives errors #ifdef __MWERKS__ #warning You must turn on gcc extensions to use this header #endif #ifdef __cplusplus extern "C" { #endif /*! @header ForceFeedback.h @abstract Public Interfaces to the Force Feedback implementation in Mac OS X. @discussion The Force Feedback API allows developers to control Force Feedback devices attached to the system. It is a distilled version of the Force Feedback functionality found in Microsoft's DirectInput API. Developers familiar with that API should find this API to be similar. */ #include #if COREFOUNDATION_CFPLUGINCOM_SEPARATE #include #endif #include #include #include //----------------------------------------------------------------------------- // The Version of the FF API //----------------------------------------------------------------------------- /*! @enum Force Feedback API Version @discussion This refers the Force Feedback Framework API (and not the plugIn API). */ enum { kFFAPIMajorRev = 1, kFFAPIMinorAndBugRev = 0, kFFAPIStage = finalStage, kFFAPINonRelRev = 0 }; //----------------------------------------------------------------------------- // Effect definition structures //----------------------------------------------------------------------------- /*! @typedef FFCONSTANTFORCE @abstract Contains type-specific information for the CONSTANTFORCE effect. @discussion A pointer to a single FFCONSTANTFORCE structure for an effect is passed in the lpvTypeSpecificParams member of the FFEFFECT structure. @field lMagnitude The magnitude of the effect, in the range from -10,000 through 10,000. If an envelope is applied to this effect, the value represents the magnitude of the sustain. If no envelope is applied, the value represents the amplitude of the entire effect. */ struct FFCONSTANTFORCE { LONG lMagnitude; }; typedef struct FFCONSTANTFORCE FFCONSTANTFORCE; typedef FFCONSTANTFORCE * PFFCONSTANTFORCE; /*! @typedef FFRAMPFORCE @abstract Contains type-specific information for the RAMPFORCE effect. @discussion A pointer to a single FFRAMPFORCE structure for an effect is passed in the lpvTypeSpecificParams member of the FFEFFECT structure. The dwDuration for a ramp force effect cannot be FF_INFINITE. @field lMagnitude Magnitude at the start of the effect, in the range from -10,000 through 10,000. @field lEnd Magnitude at the end of the effect, in the range from -10,000 through 10,000. */ struct FFRAMPFORCE { LONG lStart; LONG lEnd; }; typedef struct FFRAMPFORCE FFRAMPFORCE; typedef FFRAMPFORCE * PFFRAMPFORCE; /*! @typedef FFPERIODIC @abstract Contains type-specific information for the following effects.
  • SINE
  • SQUARE
  • TRIANGLE
  • SAWTOOTHUP
  • SAWTOOTHDOWN
@discussion A pointer to a single FFPERIODIC structure for an effect is passed in the lpvTypeSpecificParams member of the FFEFFECT structure. A Force Feedback plugIn cannot provide support for all values in the dwPhase member. In this case, the value is rounded off to the nearest supported value. @field dwMagnitude Magnitude of the effect, in the range from 0 through 10,000. If an envelope is applied to this effect, the value represents the magnitude of the sustain. If no envelope is applied, the value represents the amplitude of the entire effect. @field lOffset Offset of the effect. The range of forces generated by the effect is lOffset minus dwMagnitude to lOffset plus dwMagnitude. The value of the lOffset member is also the baseline for any envelope that is applied to the effect. @field dwPhase Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999. @field dwPeriod Period of the effect, in microseconds. */ struct FFPERIODIC { DWORD dwMagnitude; LONG lOffset; DWORD dwPhase; DWORD dwPeriod; }; typedef struct FFPERIODIC FFPERIODIC; typedef FFPERIODIC * PFFPERIODIC; /*! @typedef FFCONDITION @abstract Contains type-specific information for the following effects.
  • SPRING
  • DAMPER
  • INERTIA
  • FRICTION
@discussion A pointer to an array of FFCONDITION structures for an effect is passed in the lpvTypeSpecificParams member of the FFEFFECT structure. The number of elements in the array must be either one, or equal to the number of axes associated with the effect.

Different types of conditions interpret the parameters differently, but the basic idea is that force resulting from a condition is equal to A(q - q0) where A is a scaling coefficient, q is some metric, and q0 is the neutral value for that metric.

The preceding simplified formula must be adjusted if a nonzero deadband is provided. If the metric is less than lOffset - lDeadBand, the resulting force is given by the following formula:

force = lNegativeCoefficient * (q - (lOffset - lDeadBand))

Similarly, if the metric is greater than lOffset + lDeadBand, the resulting force is given by the following formula:

force = lPositiveCoefficient * (q - (lOffset + lDeadBand))

A spring condition uses axis position as the metric.

A damper condition uses axis velocity as the metric.

An inertia condition uses axis acceleration as the metric.

If the number of FFCONDITION structures in the array is equal to the number of axes for the effect, the first structure applies to the first axis, the second applies to the second axis, and so on. For example, a two-axis spring condition with lOffset set to 0 in both FFCONDITION structures would have the same effect as the joystick self-centering spring. When a condition is defined for each axis in this way, the effect must not be rotated.

If there is a single FFCONDITION structure for an effect with more than one axis, the direction along which the parameters of the FFCONDITION structure are in effect is determined by the direction parameters passed in the rglDirection field of the FFEFFECT structure. For example, a friction condition rotated 45 degrees (in polar coordinates) would resist joystick motion in the northeast-southwest direction but would have no effect on joystick motion in the northwest-southeast direction. @field lOffset Offset for the condition, in the range from -10,000 through 10,000. @field lPositiveCoefficient Coefficient constant on the positive side of the offset, in the range from -10,000 through 10,000. @field lNegativeCoefficient Coefficient constant on the negative side of the offset, in the range from -10,000 through 10,000.

If the device does not support separate positive and negative coefficients, the value of lNegativeCoefficient is ignored, and the value of lPositiveCoefficient is used as both the positive and negative coefficients. @field dwPositiveSaturation Maximum force output on the positive side of the offset, in the range from 0 through 10,000.

If the device does not support force saturations, the value of this member is ignored. @field dwNegativeSaturation Maximum force output on the negative side of the offset, in the range from 0 through 10,000.

If the device does not support force saturation, the value of this member is ignored.

If the device does not support separate positive and negative saturation, the value of dwNegativeSaturation is ignored, and the value of dwPositiveSaturation is used as both the positive and negative saturation. @field lDeadBand Region around lOffset in which the condition is not active, in the range from 0 through 10,000. In other words, the condition is not active between lOffset minus lDeadBand and lOffset plus lDeadBand. */ struct FFCONDITION { LONG lOffset; LONG lPositiveCoefficient; LONG lNegativeCoefficient; DWORD dwPositiveSaturation; DWORD dwNegativeSaturation; LONG lDeadBand; }; typedef struct FFCONDITION FFCONDITION; typedef FFCONDITION * PFFCONDITION; /*! @typedef FFCUSTOMFORCE @abstract Contains type-specific information for the CUSTOMFORCE effect. @discussion A pointer to a single FFCUSTOMFORCE structure for an effect is passed in the lpvTypeSpecificParams member of the FFEFFECT structure. The structure describes a custom or user-defined force. @field cChannels Number of channels (axes) affected by this force.

The first channel is applied to the first axis associated with the effect, the second to the second, and so on. If there are fewer channels than axes, nothing is associated with the extra axes.

If there is only a single channel, the effect is rotated in the direction specified by the rglDirection member of the FFEFFECT structure. If there is more than one channel, rotation is not allowed.

Not all devices support rotation of custom effects. @field dwSamplePeriod Sample period, in microseconds. @field cSamples Total number of samples in the rglForceData. It must be an integral multiple of the cChannels. @field rglForceData Pointer to an array of force values representing the custom force. If multiple channels are provided, the values are interleaved. For example, if cChannels is 3, the first element of the array belongs to the first channel, the second to the second, and the third to the third. */ struct FFCUSTOMFORCE { DWORD cChannels; DWORD dwSamplePeriod; DWORD cSamples; LPLONG rglForceData; }; typedef struct FFCUSTOMFORCE FFCUSTOMFORCE; typedef FFCUSTOMFORCE * PFFCUSTOMFORCE; /*! @typedef FFENVELOPE @abstract Used by the FFEFFECT structure to specify the optional envelope parameters for an effect. @discussion The sustain level for the envelope is represented by the dwMagnitude member of the FFPERIODIC structure and the lMagnitude member of the FFCONSTANTFORCE structure. The sustain time is represented by dwDuration member of the FFEFFECT structure @field dwSize Size, in bytes, of this structure. This member must be initialized before the structure is used. @field dwAttackLevel Amplitude for the start of the envelope, relative to the baseline, in the range from 0 through 10,000. If the effect's type-specific data does not specify a baseline, the amplitude is relative to 0. @field dwAttackTime The time, in microseconds, to reach the sustain level. @field dwFadeLevel Amplitude for the end of the envelope, relative to the baseline, in the range from 0 through 10,000. If the effect's type-specific data does not specify a baseline, the amplitude is relative to 0. @field dwFadeTime The time, in microseconds, to reach the fade level. */ struct FFENVELOPE { DWORD dwSize; DWORD dwAttackLevel; DWORD dwAttackTime; DWORD dwFadeLevel; DWORD dwFadeTime; }; typedef struct FFENVELOPE FFENVELOPE; typedef FFENVELOPE * PFFENVELOPE; /*! @typedef FFEFFECT @abstract UsUsed by the FFDeviceCreateEffect method to initialize a new effect object. It is also used by the FFEffectSetParameters and FFEffectGetParameters functions. @discussion OBJECT IDS cannot be used to identify trigger buttons in dwTriggerButton, and output axes in rgdwAxes[n]. Please use object offsets (FFJOFS_* constants), the only supported method. @field dwSize Size, in bytes, of this structure. This member must be initialized before the structure is used. @field dwFlags Flags associated with the effect. This value can be a combination of one or more of the following values:
  • FFEFF_CARTESIAN
The values of rglDirection are to be interpreted as Cartesian coordinates.
  • FFEFF_OBJECTOFFSETS
The values of dwTriggerButton and rgdwAxes are data format offsets, FFJOFS_* constants. This flag is not necessary, as the format is assumed. The OBJECTIDS method of specifying dwTriggerButton and rgdwAxes is not supported -- FFJOFS_* constants MUST be used.
  • FFEFF_POLAR
The values of rglDirection are to be interpreted as polar coordinates.
  • FFEFF_SPHERICAL
The values of rglDirection are to be interpreted as spherical coordinates. @field dwDuration The total duration of the effect, in microseconds. If this value is FF_INFINITE, the effect has infinite duration. If an envelope has been applied to the effect, the attack is applied, followed by an infinite sustain. @field dwSamplePeriod The period at which the device should play back the effect, in microseconds. A value of 0 indicates that the default playback sample rate should be used.

If the device is not capable of playing back the effect at the specified rate, it chooses the supported rate that is closest to the requested value.

Setting a custom dwSamplePeriod can be used for special effects. For example, playing a sine wave at an artificially large sample period results in a rougher texture. @field dwGain The gain to be applied to the effect, in the range from 0 through 10,000. The gain is a scaling factor applied to all magnitudes of the effect and its envelope. @field dwTriggerButton The identifier or offset of the button to be used to trigger playback of the effect. The FFJOFS_* flags must be used to specify the value. If this member is set to FFEB_NOTRIGGER, no trigger button is associated with the effect. @field dwTriggerRepeatInterval The interval, in microseconds, between the end of one playback and the start of the next when the effect is triggered by a button press and the button is held down. Setting this value to FF_INFINITE suppresses repetition. @field cAxes Number of axes involved in the effect. This member must be filled in by the caller if changing or setting the axis list or the direction list.

The number of axes for an effect cannot be changed once it has been set. @field rgdwAxes Pointer to a DWORD array (of cAxes elements) containing identifiers or offsets identifying the axes to which the effect is to be applied. The FFJOFS_* flags must be used to specify the values in the array.

The list of axes associated with an effect cannot be changed once it has been set.

No more than 32 axes can be associated with a single effect. @field rglDirection Pointer to a LONG array (of cAxes elements) containing either Cartesian coordinates, polar coordinates, or spherical coordinates. The flags FFEFF_CARTESIAN, FFEFF_POLAR, and FFEFF_SPHERICAL determine the semantics of the values in the array.

If Cartesian, each value in rglDirection is associated with the corresponding axis in rgdwAxes.

If polar, the angle is measured in hundredths of degrees from the (0, -1) direction, rotated in the direction of (1, 0). This usually means that north is away from the user, and east is to the user's right. The last element is not used.

If spherical, the first angle is measured in hundredths of a degree from the (1, 0) direction, rotated in the direction of (0, 1). The second angle (if the number of axes is three or more) is measured in hundredths of a degree toward (0, 0, 1). The third angle (if the number of axes is four or more) is measured in hundredths of a degree toward (0, 0, 0, 1), and so on. The last element is not used.

Note: The rglDirection array must contain cAxes entries, even if polar or spherical coordinates are given. In these cases, the last element in the rglDirection array is reserved for future use and must be 0. @field lpEnvelope Optional pointer to a FFENVELOPE structure that describes the envelope to be used by this effect. Not all effect types use envelopes. If no envelope is to be applied, the member should be set to NULL. @field cbTypeSpecificParams Number of bytes of additional type-specific parameters for the corresponding effect type. @field lpvTypeSpecificParams TPointer to type-specific parameters, or NULL if there are no type-specific parameters.

If the effect is of type FFEFT_CONDITION, this member contains a pointer to an array of FFCONDITION structures that define the parameters for the condition. A single structure may be used, in which case the condition is applied in the direction specified in the rglDirection array. Otherwise, there must be one structure for each axis, in the same order as the axes in rgdwAxes array. If a structure is supplied for each axis, the effect should not be rotated; you should use the following values in the rglDirection array:
  • FFEFF_SPHERICAL: 0, 0, ...
  • FFEFF_POLAR: 9000, 0, ...
  • FFEFF_CARTESIAN: 1, 0, ...
If the effect is of type FFEFT_CUSTOMFORCE, this member contains a pointer to a FFCUSTOMFORCE structure that defines the parameters for the custom force.

If the effect is of type FFEFT_PERIODIC, this member contains a pointer to a FFPERIODIC structure that defines the parameters for the effect.

If the effect is of type FFEFT_CONSTANTFORCE, this member contains a pointer to a FFCONSTANTFORCE structure that defines the parameters for the constant force.

If the effect is of type FFEFT_RAMPFORCE, this member contains a pointer to a FFRAMPFORCE structure that defines the parameters for the ramp force. @field dwStartDelay Time (in microseconds) that the device should wait after a FFEffectStart call before playing the effect. If this value is 0, effect playback begins immediately. */ struct FFEFFECT { DWORD dwSize; DWORD dwFlags; DWORD dwDuration; DWORD dwSamplePeriod; DWORD dwGain; DWORD dwTriggerButton; DWORD dwTriggerRepeatInterval; DWORD cAxes; LPDWORD rgdwAxes; LPLONG rglDirection; PFFENVELOPE lpEnvelope; DWORD cbTypeSpecificParams; void * lpvTypeSpecificParams; DWORD dwStartDelay; }; typedef struct FFEFFECT FFEFFECT; typedef FFEFFECT * PFFEFFECT; /*! @typedef FFEFFESCAPE @abstract The FFEFFESCAPE structure passes hardware-specific data directly to the Force Feedback plugIn. @discussion @field dwSize Size, in bytes, of this structure. This member must be initialized before the structure is used. @field dwCommand Specifies a plugIn specific command number. Contact the hardware vendor for a list of valid commands and their parameters. @field lpvInBuffer Buffer containing the data required to perform the operation. @field cbInBuffer Specifies the size, in bytes, of the lpvInBuffer buffer. @field lpvOutBuffer Buffer in which the operation's output data is returned. @field cbOutBuffer On entry, specifies the size, in bytes, of the lpvOutBuffer buffer. On exit, specifies the number of bytes actually produced by the command. */ struct FFEFFESCAPE { DWORD dwSize; DWORD dwCommand; void * lpvInBuffer; DWORD cbInBuffer; void * lpvOutBuffer; DWORD cbOutBuffer; }; typedef struct FFEFFESCAPE FFEFFESCAPE; typedef FFEFFESCAPE * PFFEFFESCAPE; /*! @typedef FFCAPABILITIES @abstract Used by the FFDeviceGetForceFeedbackCapabilities method to retrieve device force-feedback capabilities. @discussion This structure has no DirectInput equivalent. @field ffSpecVer Specifies the version number of the FF API specification supported by this plugIn. It should be specified using the fields of the NumVersion structure. The first version of the FF API specification is 1.0.0f0. @field supportedEffects FFCapabilitiesEffectType flags that identify all effect types supported by the plugIn/device (including driver-emulated effects). This value can be a combination of one or more of the following values:

FFCAP_ET_CONSTANTFORCE
The Constant Force effect type is supported by this device.
...

FFCAP_ET_*

See the header file ForceFeedbackConstants.h for a complete list of FFCapabilitiesEffectType flags.
@field emulatedEffects FFCapabilitiesEffectType flags that identify all effect types not directly supported by the device, but emulated by the plugIn. The emulated effects flags must also appear in the supportedEffects member. This value can be a combination of one or more of the following values:

FFCAP_ET_*

See the header file ForceFeedbackConstants.h for a complete list of FFCapabilitiesEffectType flags. @field subType The force-feedback sub-category which best identifies the device's FF capabilities. This value can be one of the following:

FFCAP_ST_KINESTHETIC
A kinesthetic force feedback device is one that can produce "grounded" forces based on the controller's position. It supports temporal force-feedback effects (periodic vibrations), as well as directional (constant force) and position-based (spring, damper) forces. Most higher-end force-feedback joysticks and steering wheels fall into this category.

FFCAP_ST_VIBRATION
A vibration force feedback device is one that can only produce non-grounded temporal force-feedback effects (periodic vibrations). Most console gamepads and some lower-end joysticks fall into this category.

The force-feedback subtype must be provided, and can only be one of the aforementioned values. @field numFfAxes The number of controller axes that provide force feedback. Indicates the number of valid elements in ffAxes. @field ffAxes An array of values that decribe the axes on which force-feedback is present. The number of valid elements in the array is specified in numFfAxes. Each element of the array can contain one of the following values:

FFJOFS_X
The X-axis is force-feedback-actuated.

FFJOFS_Y
The Y-axis is force-feedback-actuated.

FFJOFS_Z
The Z-axis is force-feedback-actuated.

For devices of subType FFCAP_ST_VIBRATION, it is recommended that the numFfAxes = 1, and that ffAxes[0] = FFJOFS_X. @field storageCapacity The maximum number of effects that can be created via calls to FFDeviceCreateEffect and coexist at any one time. This may or may not be different from the playbackCapacity, depending on device driver complexity. @field playbackCapacity The maximum number of created effects that can be simultaneously played via calls to FFEffectStart. This number will always be equal to or less than the storageCapacity. A device driver may allow more effects to be created than the physical device can actually handle. Therefore, this number is an important parameter for FF designers. @field driverVer Specifies the version number of the force-feedback device driver, using a NumVersion structure. @field firmwareVer Specifies the firmware revision of the device, using a NumVersion structure. @field hardwareVer Specifies the hardware revision of the device, using a NumVersion structure. */ struct FFCAPABILITIES { NumVersion ffSpecVer; UInt32 supportedEffects; UInt32 emulatedEffects; UInt32 subType; UInt32 numFfAxes; UInt8 ffAxes[32]; UInt32 storageCapacity; UInt32 playbackCapacity; NumVersion firmwareVer; NumVersion hardwareVer; NumVersion driverVer; }; typedef struct FFCAPABILITIES FFCAPABILITIES; typedef FFCAPABILITIES * PFFCAPABILITIES; //----------------------------------------------------------------------------- // Object reference pointers //----------------------------------------------------------------------------- // FFDeviceObjectReference and FFEffectObjectReference are opaque handles // to objects created and maintained by the FF API. // A FFDeviceObjectReference is obtained through a call to FFCreateDevice and // refers to a specific attached device supporting force feedback. This // reference may be passed to any of the "FFDevice" functions (below). When // you are through with it, call FFReleaseDevice to release the memory. // Similarly, a FFEffectObjectReference is obtained through a call to // FFDeviceCreateEffect and refers to a created force feedback effect on a // particular device. This reference may be passed to any of the "FFEffect" // functions. Call FFDeviceReleaseEffect to unload the effect and clean up // its memory. - Jeff Mallett 9/25/02 // typedef struct {} __FFDHIDDEN, * FFDeviceObjectReference; typedef struct {} __FFEHIDDEN, * FFEffectObjectReference; //----------------------------------------------------------------------------- // FF (general) function prototypes //----------------------------------------------------------------------------- /*! @function FFCreateDevice @abstract Creates a new API device object from an OS object in preparation to use the device for force feedback. @param hidDevice Pointer to a HID device object. @param pdeviceReference Address of a variable to receive an opaque reference handle to a new device object. This reference can be used in subsequent calls to FFDevice* functions @result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOINTERFACE
FFERR_OUTOFMEMORY
FFERR_INTERNAL
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object. */ extern HRESULT FFCreateDevice( io_service_t hidDevice, FFDeviceObjectReference * pDeviceReference ); /*! @function FFReleaseDevice @abstract Disposes of an API device object created with FFCreateDevice. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOINTERFACE
FFERR_OUTOFMEMORY
@discussion */ extern HRESULT FFReleaseDevice( FFDeviceObjectReference deviceReference ); /*! @function FFIsForceFeedback @abstract Used to determine if a particular device provided by HID Manager is a force feedback device. @param hidDevice Pointer to a HID device object to be tested for force feedback support. @result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method succeeds, and the device does not support FF, the return value is FFERR_NOINTERFACE. If the method fails, the return value is FFERR_INVALIDPARAM @discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object. */ extern HRESULT FFIsForceFeedback( io_service_t hidDevice ); //----------------------------------------------------------------------------- // FFDevice (device related) function prototypes //----------------------------------------------------------------------------- /*! @function FFDeviceCreateEffect @abstract Creates and initializes an instance of an effect identified by the effect UUID on the device. @param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice. @param uuidRef Reference to the UUID identifying the effect to be created. Only predefined effect UUIDs are accepted. The following standard effect UUIDs are defined:

kFFEffectType_ConstantForce_ID
kFFEffectType_RampForce_ID
kFFEffectType_Square_ID
kFFEffectType_Sine_ID
kFFEffectType_Triangle_ID
kFFEffectType_SawtoothUp_ID
kFFEffectType_SawtoothDown_ID
kFFEffectType_Spring_ID
kFFEffectType_Damper_ID
kFFEffectType_Inertia_ID
kFFEffectType_Friction_ID
kFFEffectType_CustomForce_ID

@param pEffectDefinition Pointer to FFEFFECT structure that provides parameters for the created effect. This parameter is optional. If it is NULL, the effect object is created without parameters. The application must then call the FFEffectSetParameters function to set the parameters of the effect before it can download the effect. @param pEffectReference Address of a variable to receive an opaque reference handle to a new effect object. This reference can be used in subsequent calls to FFEffect* functions. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_UNSUPPORTEDAXIS
FFERR_OUTOFMEMORY
FFERR_DEVICEPAUSED
FFERR_DEVICEFULL
FFERR_INVALIDDOWNLOADID
FFERR_INTERNAL
FFERR_EFFECTTYPEMISMATCH
@discussion When you are finished with the effect, FFReleaseEffect must be called on the reference received in this function to dispose of the API effect object. */ extern HRESULT FFDeviceCreateEffect( FFDeviceObjectReference deviceReference, CFUUIDRef uuidRef, FFEFFECT * pEffectDefinition, FFEffectObjectReference * pEffectReference ); /*! @function FFDeviceReleaseEffect @abstract Disposes of an API effect object created with FFDeviceCreateEffect. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
FFERR_GENERIC
FFERR_INTERNAL
FFERR_INVALIDDOWNLOADID
@discussion */ extern HRESULT FFDeviceReleaseEffect( FFDeviceObjectReference deviceReference, FFEffectObjectReference effectReference ); /*! @function FFDeviceEscape @abstract Sends a hardware-specific command to the device. @param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice. @param pFFEffectEscape Pointer to FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_UNSUPPORTED
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver. */ extern HRESULT FFDeviceEscape( FFDeviceObjectReference deviceReference, FFEFFESCAPE * pFFEffectEscape ); /*! @function FFDeviceGetForceFeedbackState @abstract Retrieves the state of the device's force feedback system. @param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice. @param pFFState Location for flags that describe the current state of the device's force feedback system. The value is a combination of the following constants:

FFGFFS_ACTUATORSOFF
The device's force feedback actuators are disabled.

FFGFFS_ACTUATORSON
The device's force feedback actuators are enabled.

FFGFFS_DEVICELOST
The device suffered an unexpected failure and is in an indeterminate state. It must be reset either by unacquiring and reacquiring the device, or by sending a FFSFFC_RESET command.

FFGFFS_EMPTY
The device has no downloaded effects.

FFGFFS_PAUSED
Playback of all active effects has been paused.

FFGFFS_POWEROFF
The force feedback system is not currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.

FFGFFS_POWERON
Power to the force feedback system is currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.

FFGFFS_SAFETYSWITCHOFF
The safety switch is currently off; that is, the device cannot operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.

FFGFFS_SAFETYSWITCHON
The safety switch is currently on; that is, the device can operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.

FFGFFS_STOPPED
No effects are playing, and the device is not paused.

FFGFFS_USERFFSWITCHOFF
The user force feedback switch is currently off; that is, the device cannot operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.

FFGFFS_USERFFSWITCHON
The user force feedback switch is currently on; that is, the device can operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.

Future versions can define additional flags. Applications should ignore any flags that are not currently defined.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
@discussion */ extern HRESULT FFDeviceGetForceFeedbackState( FFDeviceObjectReference deviceReference, FFState * pFFState ); /*! @function FFDeviceSendForceFeedbackCommand @abstract Sends a command to the device's force feedback system. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @param flags Single value indicating the desired change in state. The value can be one of the following:

FFSFFC_CONTINUE
Paused playback of all active effects is to be continued. It is an error to send this command when the device is not in a paused state.

FFSFFC_PAUSE
Playback of all active effects is to be paused. This command also stops the clock-on effects so that they continue playing to their full duration when restarted.

While the device is paused, new effects cannot be started, and existing ones cannot be modified. Doing so can cause the subsequent FFSFFC_CONTINUE command to fail to perform properly.

To abandon a pause and stop all effects, use the FFSFFC_STOPALL or FFSFCC_RESET commands.

FFSFFC_RESET
The device's force feedback system is to be put in its startup state. All effects are removed from the device, are no longer valid, and must be recreated if they are to be used again. The device's actuators are disabled.

FFSFFC_SETACTUATORSOFF
The device's force feedback actuators are to be disabled. While the actuators are off, effects continue to play but are ignored by the device. Using the analogy of a sound playback device, they are muted, rather than paused.

FFSFFC_SETACTUATORSON
The device's force feedback actuators are to be enabled.

FFSFFC_STOPALL
Playback of any active effects is to be stopped. All active effects are reset, but are still being maintained by the device and are still valid. If the device is in a paused state, that state is lost.

This command is equivalent to calling the FFEffect_Stop method for each effect playing. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_INTERNAL
@discussion */ extern HRESULT FFDeviceSendForceFeedbackCommand( FFDeviceObjectReference deviceReference, FFCommandFlag flags ); /*! @function FFDeviceSetForceFeedbackProperty @abstract Retrieves the device's force feedback capabilities. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @param property The following property values are defined for a FF device:

FFPROP_AUTOCENTER
Specifies whether the actuated FF axes are self-centering. This property controls the device's "default centering spring".
The pValue member points to a UInt32 can be one of the following values.
0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
1 - ON: The device should automatically center when the user releases the device.
Not all devices support the autocenter property.

FFPROP_FFGAIN
Sets the gain for the device.
The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
Setting a gain value is useful when an application wants to scale down the strength of all force feedback effects uniformly, based on user preferences. @param pValue Address of the location where the property value is to be read. SetForceFeedbackProperty will assume that the data is valid, and of the correct type. @result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
@discussion */ extern HRESULT FFDeviceSetForceFeedbackProperty( FFDeviceObjectReference deviceReference, FFProperty property, void * pValue ); /*! @function FFDeviceGetForceFeedbackProperty @abstract Gets properties that define the device behavior. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @param property The following property values are defined for a FF device (see FFDeviceSetForceFeedbackProperty for details):

FFPROP_AUTOCENTER
FFPROP_FFGAIN
@param pValue Address of the location where the value associated with the property is to be stored. GetForceFeedbackProperty assumes that the pointer is valid, although it will perform a size check before writing the data to pValue @param valueSize Size, in bytes, of data area pointed to by pValue. Size is compared to expected property size, and the function fails if a mismatch occurs. @result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
@discussion */ extern HRESULT FFDeviceGetForceFeedbackProperty( FFDeviceObjectReference deviceReference, FFProperty property, void * pValue, IOByteCount valueSize ); /*! @function FFDeviceSetCooperativeLevel @abstract Function is unimplemented in version 1.0 of this API @discussion */ extern HRESULT FFDeviceSetCooperativeLevel( FFDeviceObjectReference deviceReference, void * taskIdentifier, FFCooperativeLevelFlag flags ); /*! @function FFDeviceGetForceFeedbackCapabilities @abstract Retrieves the device's force feedback capabilities. @param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice. @param pFFCapabilities Pointer to a FFCAPABILITIES structure that is to be filled in by the this call. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
@discussion */ extern HRESULT FFDeviceGetForceFeedbackCapabilities( FFDeviceObjectReference deviceReference, FFCAPABILITIES * pFFCapabilities ); //----------------------------------------------------------------------------- // FFEffect (effect related) function prototypes //----------------------------------------------------------------------------- /*! @function FFEffectDownload @abstract Places the effect on the device. If the effect is already on the device, the existing effect is updated to match the values set by the FFEffectSetParameters method. @param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @result If the method succeeds, the return value is FF_OK or S_FALSE. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_DEVICEPAUSED
FFERR_DEVICEFULL
FFERR_INVALIDDOWNLOADID
FFERR_INTERNAL
FFERR_EFFECTTYPEMISMATCH

If the method returns S_FALSE, the effect has already been downloaded to the device.
@discussion It is valid to update an effect while it is playing. The semantics of such an operation are explained in the reference for FFEffectSetParameters. */ extern HRESULT FFEffectDownload( FFEffectObjectReference effectReference ); /*! @function FFEffectEscape @abstract Sends a hardware-specific command to the driver. @param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @param pFFEffectEscape FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
FFERR_UNSUPPORTED

Other device-specific error codes are also possible. Ask the hardware manufacturer for details
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver. */ extern HRESULT FFEffectEscape( FFEffectObjectReference effectReference, FFEFFESCAPE * pFFEffectEscape ); /*! @function FFEffectGetEffectStatus @abstract Sends a hardware-specific command to the driver. @param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @param pFlags Pointer to status flags for the effect. The value can be 0 or one or more of the following constants:

FFEGES_PLAYING
The effect is playing.

FFEGES_EMULATED
The effect is emulated.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
@discussion */ extern HRESULT FFEffectGetEffectStatus( FFEffectObjectReference effectReference, FFEffectStatusFlag * pFlags ); /*! @function FFEffectGetParameters @abstract Retrieves information about an effect. @param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @param pFFEffect Address of a FFEFFECT structure that receives effect information. The dwSize member must be filled in by the application before calling this method. @param flags Flags that specify which parts of the effect information are to be retrieved. The value can be 0 or one or more of the following constants:

FFEP_ALLPARAMS
The union of all other FFEP_* flags, indicating that all members of the FFEFFECT structure are being requested.

FFEP_AXES
The cAxes and rgdwAxes members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rgdwAxes member. If the buffer is too small, the method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.

FFEP_DIRECTION
The cAxes and rglDirection members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rglDirection member. If the buffer is too small, the GetParameters method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
The dwFlags member must include at least one of the coordinate system flags (FFEFF_CARTESIAN, FFEFF_POLAR, or FFEFF_SPHERICAL). The API returns the direction of the effect in one of the coordinate systems you specified, converting between coordinate systems as necessary. On exit, exactly one of the coordinate system flags is set in the dwFlags member, indicating which coordinate system the FF API used. In particular, passing all three coordinate system flags retrieves the coordinates in exactly the same format in which they were set.

FFEP_DURATION
The dwDuration member should receive data.

FFEP_ENVELOPE
The lpEnvelope member points to a FFENVELOPE structure that should receive data. If the effect does not have an envelope associated with it, the lpEnvelope member is set to NULL.

FFEP_GAIN
The dwGain member should receive data.

FFEP_SAMPLEPERIOD
The dwSamplePeriod member should receive data.

FFEP_STARTDELAY
The dwStartDelay member should receive data.

FFEP_TRIGGERBUTTON
The dwTriggerButton member should receive data.

FFEP_TRIGGERREPEATINTERVAL
The dwTriggerRepeatInterval member should receive data.

FFEP_TYPESPECIFICPARAMS
The lpvTypeSpecificParams member points to a buffer whose size is specified by the cbTypeSpecificParams member. On return, the buffer is filled in with the type-specific data associated with the effect, and the cbTypeSpecificParams member contains the number of bytes copied. If the buffer supplied by the application is too small to contain all the type-specific data, the method returns FFERR_MOREDATA, and the cbTypeSpecificParams member contains the required size of the buffer in bytes.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
FFERR_MOREDATA
@discussion Common errors resulting in a FFERR_INVALIDPARAM error include not setting the dwSize member of the FFEFFECT structure, passing invalid flags, or not setting up the members in the FFEFFECT structure properly in preparation for receiving the effect information. */ extern HRESULT FFEffectGetParameters( FFEffectObjectReference effectReference, FFEFFECT * pFFEffect, FFEffectParameterFlag flags ); /*! @function FFEffectSetParameters @abstract Sets the characteristics of an effect. @param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @param pFFEffect Address of a FFEFFECT structure that contains effect information. The dwSize member must be filled in by the application before calling this method, as well as any members specified by corresponding bits in the flags parameter. @param flags Flags that specify which portions of the effect information are to be set and how the downloading of the parameters should be handled. The value can be 0 or one or more of the following constants:

FFEP_AXES
The cAxes and rgdwAxes members contain data.

FFEP_DIRECTION
The cAxes and rglDirection members contain data. The dwFlags member specifies (with FFEFF_CARTESIAN or FFEFF_POLAR) the coordinate system in which the values should be interpreted.

FFEP_DURATION
The dwDuration member contains data.

FFEP_ENVELOPE
The lpEnvelope member points to a FFENVELOPE structure that contains data. To detach any existing envelope from the effect, pass this flag and set the lpEnvelope member to NULL.

FFEP_GAIN
The dwGain member contains data.

FFEP_NODOWNLOAD
Suppress the automatic FFEffect_Download that is normally performed after the parameters are updated.

FFEP_NORESTART
Suppress the stopping and restarting of the effect to change parameters. See Remarks.

FFEP_SAMPLEPERIOD
The dwSamplePeriod member contains data.

FFEP_START
The effect is to be started (or restarted if it is currently playing) after the parameters are updated. By default, the play state of the effect is not altered.

FFEP_STARTDELAY
The dwStartDelay member contains data.

FFEP_TRIGGERBUTTON
The dwTriggerButton member contains data.


The dwTriggerRepeatInterval member contains data.

FFEP_TYPESPECIFICPARAMS
The lpvTypeSpecificParams and cbTypeSpecificParams members of the FFEFFECT structure contain the address and size of type-specific data for the effect. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_UNSUPPORTEDAXIS
FFERR_OUTOFMEMORY
FFERR_DEVICEPAUSED
FFERR_DEVICEFULL
FFERR_INVALIDDOWNLOADID
FFERR_INTERNAL
FFERR_EFFECTTYPEMISMATCH
@discussion The FFEffectSetParameters method automatically downloads the effect, but this behavior can be suppressed by setting the FFEP_NODOWNLOAD flag. If automatic download has been suppressed, you can manually download the effect by invoking the FFEffectDownload method.

If the effect is playing while the parameters are changed, the new parameters take effect as if they were the parameters when the effect started.

For example, suppose a periodic effect with a duration of three seconds is started. After two seconds, the direction of the effect is changed. The effect then continues for one additional second in the new direction. The envelope, phase, amplitude, and other parameters of the effect continue smoothly, as if the direction had not changed.

In the same situation, if after two seconds the duration of the effect were changed to 1.5 seconds, the effect would stop.

Normally, if the driver cannot update the parameters of a playing effect, the driver is permitted to stop the effect, update the parameters, and then restart the effect. Passing the FFEP_NORESTART flag suppresses this behavior. If the driver cannot update the parameters of an effect while it is playing, the error code FFERR_EFFECTPLAYING is returned, and the parameters are not updated.

No more than one of the FFEP_NODOWNLOAD, FFEP_START, and FFEP_NORESTART flags should be set. (It is also valid to pass none of them.)

These three flags control download and playback behavior as follows:

If FFEP_NODOWNLOAD is set, the effect parameters are updated but not downloaded to the device.

If the FFEP_START flag is set, the effect parameters are updated and downloaded to the device, and the effect is started just as if the FFEffect_Start method had been called with the dwIterations parameter set to 1 and with no flags. (Combining the update with FFEP_START is slightly faster than calling Start separately, because it requires less information to be transmitted to the device.)

If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is not playing, the parameters are updated and downloaded to the device.

If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is playing, the parameters are updated if the device supports on-the-fly updating. Otherwise the behavior depends on the state of the FFEP_NORESTART flag. If it is set, the error code FFERR_EFFECTPLAYING is returned. If it is clear, the effect is stopped, the parameters are updated, and the effect is restarted. */ extern HRESULT FFEffectSetParameters( FFEffectObjectReference effectReference, FFEFFECT * pFFEffect, FFEffectParameterFlag flags ); /*! @function FFEffectStart @abstract Begins playing an effect. If the effect is already playing, it is restarted from the beginning. If the effect has not been downloaded or has been modified since its last download, it is downloaded before being started. This default behavior can be suppressed by passing the FFES_NODOWNLOAD flag. @param efffectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @param iterations Number of times to play the effect in sequence. The envelope is re-articulated with each iteration.

To play the effect exactly once, pass 1. To play the effect repeatedly until explicitly stopped, pass INFINITE. To play the effect until explicitly stopped without re-articulating the envelope, modify the effect parameters with the FFEffect_SetParameters method, and change the dwDuration member to INFINITE. @param flags Flags that describe how the effect should be played by the device. The value can be 0 or one or more of the following values:

FFES_SOLO
All other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects already started on the device.

FFES_NODOWNLOAD
Do not automatically download the effect. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_DEVICEPAUSED
FFERR_DEVICEFULL
FFERR_INVALIDDOWNLOADID
FFERR_INTERNAL
FFERR_EFFECTTYPEMISMATCH
FFERR_GENERIC
@discussion Not all devices support multiple iterations. */ extern HRESULT FFEffectStart( FFEffectObjectReference effectReference, UInt32 iterations, FFEffectStartFlag flags ); /*! @function FFEffectStop @abstract Stops playing an effect. @param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
FFERR_GENERIC
FFERR_INTERNAL
FFERR_INVALIDDOWNLOADID
@discussion */ extern HRESULT FFEffectStop( FFEffectObjectReference effectReference ); /*! @function FFEffectUnload @abstract Removes the effect from the device. If the effect is playing, it is automatically stopped before it is unloaded. @param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect. @result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:

FFERR_INVALIDPARAM
FFERR_NOTDOWNLOADED
FFERR_GENERIC
FFERR_INTERNAL
FFERR_INVALIDDOWNLOADID
@discussion */ extern HRESULT FFEffectUnload( FFEffectObjectReference effectReference ); #ifdef __cplusplus } #endif #endif // _FORCEFEEDBACK_H_