Initial commit.

This commit is contained in:
Jim Gray
2013-04-04 14:32:05 -07:00
parent ba5c81da32
commit d71d53e8ec
2180 changed files with 1393544 additions and 1 deletions

1228
code/ff/IFC/FeelitAPI.h Normal file

File diff suppressed because it is too large Load Diff

79
code/ff/IFC/IFC.h Normal file
View File

@@ -0,0 +1,79 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: IFC.h
PURPOSE: Class Types for the Force Foundation Classes
STARTED: 10/29/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
**********************************************************************/
#if !defined(AFX_IFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "ImmBox.h"
#include "ImmCondition.h"
#include "ImmConstant.h"
#include "ImmDamper.h"
#include "ImmDevice.h"
#include "ImmDevices.h"
#include "ImmDXDevice.h"
#include "ImmEffect.h"
#include "ImmEllipse.h"
#include "ImmEnclosure.h"
#include "ImmMouse.h"
#include "ImmFriction.h"
#include "ImmGrid.h"
#include "ImmInertia.h"
#include "ImmPeriodic.h"
#include "ImmProjects.h"
#include "ImmRamp.h"
#include "ImmSpring.h"
#include "ImmTexture.h"
#include "IFCErrors.h"
#endif // !defined(AFX_IFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

BIN
code/ff/IFC/IFC22.dll Normal file

Binary file not shown.

BIN
code/ff/IFC/IFC22.lib Normal file

Binary file not shown.

181
code/ff/IFC/IFCErrors.h Normal file
View File

@@ -0,0 +1,181 @@
/**********************************************************************
Copyright (c) 1999 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: IFCErrors.h
PURPOSE: Error codes returned in IFC; Error handling in IFC
STARTED: 2/28/99 by Jeff Mallett
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/6/99 jrm: Added user error handling control
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#if !defined(IFCERRORS_H__INCLUDED_)
#define IFCERRORS_H__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <winerror.h>
#include "ImmBaseTypes.h"
/****************************************************************************
*
* Error Codes
*
****************************************************************************/
typedef enum {
IFC_ERR_OK = 0,
IFC_ERR_UNKNOWN_ERROR = 1,
IFC_ERR_ALLOCATION_FAILED = 2,
IFC_ERR_INVALID_PARAMETER = 3,
IFC_ERR_NULL_PARAMETER = 4,
IFC_ERR_WRONG_FORM = 5,
IFC_ERR_DEVICE_IS_NULL = 6,
IFC_ERR_INVALID_GUID = 7,
IFC_ERR_EFFECT_NOT_INITIALIZED = 8,
IFC_ERR_CANT_INITIALIZE_DEVICE = 9,
IFC_ERR_CANT_CREATE_EFFECT = 10,
IFC_ERR_CANT_CREATE_EFFECT_FROM_IFR = 11,
IFC_ERR_NO_EFFECTS_FOUND = 12,
IFC_ERR_EFFECT_IS_COMPOUND = 13,
IFC_ERR_PROJECT_ALREADY_OPEN = 14,
IFC_ERR_PROJECT_NOT_OPEN = 15,
IFC_ERR_NO_DX7_DEVICE = 16,
IFC_ERR_CANT_WRITE_IFR = 17,
IFC_ERR_DINPUT_NOT_FOUND = 18,
IFC_ERR_IMMAPI_NOT_FOUND = 19,
IFC_ERR_FILE_NOT_FOUND = 20,
IFC_ERR_NO_VERSION_INFO = 21
} IFC_ERROR_CODE;
typedef enum {
IFC_OUTPUT_ERR_TO_DEBUG = 0x0001,
IFC_OUTPUT_ERR_TO_DIALOG = 0x0002
} IFC_ERROR_HANDLING_FLAGS;
/****************************************************************************
*
* Macros
*
****************************************************************************/
//
// ------ PUBLIC MACROS ------
//
#define IFC_GET_LAST_ERROR CIFCErrors::GetLastErrorCode()
#define IFC_SET_ERROR_HANDLING CIFCErrors::SetErrorHandling
//
// ------ PRIVATE MACROS ------
//
#if (IFC_VERSION >= 0x0110)
#define IFC_SET_ERROR(err) CIFCErrors::SetErrorCode(err, __FILE__, __LINE__)
#else
#define IFC_SET_ERROR(err) CIFCErrors::SetErrorCode(err)
#endif
#define IFC_CLEAR_ERROR IFC_SET_ERROR(IFC_ERR_OK)
/****************************************************************************
*
* CIFCErrors
*
****************************************************************************/
// All members are static. Don't bother instantiating an object of this class.
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CIFCErrors
{
//
// ATTRIBUTES
//
public:
static HRESULT
GetLastErrorCode()
{ return m_Err; }
static void
SetErrorHandling(unsigned long dwFlags)
{ m_dwErrHandlingFlags = dwFlags; }
//
// ------ PRIVATE INTERFACE ------
//
// Internally used by IFC classes
static void
SetErrorCode(
HRESULT err
#if (IFC_VERSION >= 0x0110)
, const char *sFile, int nLine
#endif
);
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
private:
static HRESULT m_Err;
static unsigned long m_dwErrHandlingFlags;
};
#endif // IFCERRORS_H__INCLUDED_

359
code/ff/IFC/ImmBaseTypes.h Normal file
View File

@@ -0,0 +1,359 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmBaseTypes.h
PURPOSE: Base Types for Feelit API Foundation Classes
STARTED: 10/29/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
**********************************************************************/
#if !defined(AFX_IMMBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
//#include <windows.h>
#include "FeelitApi.h"
// Version 0x0100 -- IFC10
// Version 0x0101 -- IFC10p Special release: contains CImmProject::DestroyEffect
// Version 0x0110 -- IFC21 (and IFC20?)
#ifndef IFC_VERSION
#define IFC_VERSION 0x0110
#endif
//#if (IFC_VERSION >= 0x0101)
// This means that a user can call delete on a CImmCompoundEffect
// object that was allocated through a CImmProject::CreateEffect()
// and all will be well.
// #define PROTECT_AGAINST_DELETION
//#endif
#if (IFC_VERSION >= 0x0110)
#define IFC_START_DELAY
#define IFC_EFFECT_CACHING
#endif
// Add define for DirectInput Device emulating FEELit Device
#define FEELIT_DEVICETYPE_DIRECTINPUT 3
//================================================================
// TYPE WRAPPERS
//================================================================
//
// IMM --> FEELIT Wrappers
//
#define IMM_VERSION FEELIT_VERSION
#define IMM_DEVICETYPE_DEVICE FEELIT_DEVICETYPE_DEVICE
#define IMM_DEVICETYPE_MOUSE FEELIT_DEVICETYPE_MOUSE
#define IMM_DEVICETYPE_HID FEELIT_DEVICETYPE_HID
#define IMM_DEVICETYPE_DIRECTINPUT FEELIT_DEVICETYPE_DIRECTINPUT
#define IMM_EFFECT FEELIT_EFFECT
#define LPIMM_EFFECT LPFEELIT_EFFECT
#define LPCIMM_EFFECT LPCFEELIT_EFFECT
#define IMM_CONDITION FEELIT_CONDITION
#define LPIMM_CONDITION LPFEELIT_CONDITION
#define LPCIMM_CONDITION LPCFEELIT_CONDITION
#define IMM_CONSTANTFORCE FEELIT_CONSTANTFORCE
#define LPIMM_CONSTANTFORCE LPFEELIT_CONSTANTFORCE
#define LPCIMM_CONSTANTFORCE LPCFEELIT_CONSTANTFORCE
#define IMM_ELLIPSE FEELIT_ELLIPSE
#define LPIMM_ELLIPSE LPFEELIT_ELLIPSE
#define LPCIMM_ELLIPSE LPCFEELIT_ELLIPSE
#define IMM_ENCLOSURE FEELIT_ENCLOSURE
#define LPIMM_ENCLOSURE LPFEELIT_ENCLOSURE
#define LPCIMM_ENCLOSURE LPCFEELIT_ENCLOSURE
#define IMM_PERIODIC FEELIT_PERIODIC
#define LPIMM_PERIODIC LPFEELIT_PERIODIC
#define LPCIMM_PERIODIC LPCFEELIT_PERIODIC
#define IMM_RAMPFORCE FEELIT_RAMPFORCE
#define LPIMM_RAMPFORCE LPFEELIT_RAMPFORCE
#define LPCIMM_RAMPFORCE LPCFEELIT_RAMPFORCE
#define IMM_TEXTURE FEELIT_TEXTURE
#define LPIMM_TEXTURE LPFEELIT_TEXTURE
#define LPCIMM_TEXTURE LPCFEELIT_TEXTURE
#define IMM_ENVELOPE FEELIT_ENVELOPE
#define LPIMM_ENVELOPE LPFEELIT_ENVELOPE
#define LPCIMM_ENVELOPE LPCFEELIT_ENVELOPE
#define LPIIMM_API LPIFEELIT
#define LPIIMM_EFFECT LPIFEELIT_EFFECT
#define LPIIMM_DEVICE LPIFEELIT_DEVICE
#define IMM_CUSTOMFORCE FEELIT_CUSTOMFORCE
#define LPIMM_CUSTOMFORCE LPFEELIT_CUSTOMFORCE
#define LPCIMM_CUSTOMFORCE LPCFEELIT_CUSTOMFORCE
#define LPIMM_ENUMDEVICESCALLBACK LPFEELIT_ENUMDEVICESCALLBACK
/* Effect Types */
#define IMM_EFFECTTYPE_ALL FEELIT_FEFFECTTYPE_ALL
#define IMM_EFFECTTYPE_CONSTANTFORCE FEELIT_FEFFECTTYPE_CONSTANTFORCE
#define IMM_EFFECTTYPE_RAMPFORCE FEELIT_FEFFECTTYPE_RAMPFORCE
#define IMM_EFFECTTYPE_PERIODIC FEELIT_FEFFECTTYPE_PERIODIC
#define IMM_EFFECTTYPE_CONDITION FEELIT_FEFFECTTYPE_CONDITION
#define IMM_EFFECTTYPE_ENCLOSURE FEELIT_FEFFECTTYPE_ENCLOSURE
#define IMM_EFFECTTYPE_ELLIPSE FEELIT_FEFFECTTYPE_ELLIPSE
#define IMM_EFFECTTYPE_TEXTURE FEELIT_FEFFECTTYPE_TEXTURE
#define IMM_EFFECTTYPE_COMPOUND 0x00000008
#define IMM_EFFECTTYPE_CUSTOMFORCE FEELIT_FEFFECTTYPE_CUSTOMFORCE
#define IMM_EFFECTTYPE_HARDWARE FEELIT_FEFFECTTYPE_HARDWARE
#define IMM_EFFECTTYPE_FFATTACK FEELIT_FEFFECTTYPE_FFATTACK
#define IMM_EFFECTTYPE_FFFADE FEELIT_FEFFECTTYPE_FFFADE
#define IMM_EFFECTTYPE_SATURATION FEELIT_FEFFECTTYPE_SATURATION
#define IMM_EFFECTTYPE_POSNEGCOEFFICIENTS FEELIT_FEFFECTTYPE_POSNEGCOEFFICIENTS
#define IMM_EFFECTTYPE_POSNEGSATURATION FEELIT_FEFFECTTYPE_POSNEGSATURATION
#define IMM_EFFECTTYPE_DEADBAND FEELIT_FEFFECTTYPE_DEADBAND
/* Units */
#define IMM_DEGREES FEELIT_DEGREES
#define IMM_FFNOMINALMAX FEELIT_FFNOMINALMAX
#define IMM_SECONDS FEELIT_SECONDS
/* Start Flags */
#define IMM_START_SOLO FEELIT_FSTART_SOLO
#define IMM_START_NODOWNLOAD FEELIT_FSTART_NODOWNLOAD
/* Status Flags */
#define IMM_STATUS_PLAYING FEELIT_FSTATUS_PLAYING
#define IMM_STATUS_EMULATED FEELIT_FSTATUS_EMULATED
/* Stiffness Mask Flags */
#define IMM_STIFF_NONE FEELIT_FSTIFF_NONE
#define IMM_STIFF_OUTERLEFTWALL FEELIT_FSTIFF_OUTERLEFTWALL
#define IMM_STIFF_INNERLEFTWALL FEELIT_FSTIFF_INNERLEFTWALL
#define IMM_STIFF_INNERRIGHTWALL FEELIT_FSTIFF_INNERRIGHTWALL
#define IMM_STIFF_OUTERRIGHTWALL FEELIT_FSTIFF_OUTERRIGHTWALL
#define IMM_STIFF_OUTERTOPWALL FEELIT_FSTIFF_OUTERTOPWALL
#define IMM_STIFF_INNERTOPWALL FEELIT_FSTIFF_INNERTOPWALL
#define IMM_STIFF_INNERBOTTOMWALL FEELIT_FSTIFF_INNERBOTTOMWALL
#define IMM_STIFF_OUTERBOTTOMWALL FEELIT_FSTIFF_OUTERBOTTOMWALL
#define IMM_STIFF_OUTERANYWALL FEELIT_FSTIFF_OUTERANYWALL
#define IMM_STIFF_INBOUNDANYWALL FEELIT_FSTIFF_INBOUNDANYWALL
#define IMM_STIFF_INNERANYWALL FEELIT_FSTIFF_INNERANYWALL
#define IMM_STIFF_OUTBOUNDANYWALL FEELIT_FSTIFF_OUTBOUNDANYWALL
#define IMM_STIFF_ANYWALL FEELIT_FSTIFF_ANYWALL
/* Clipping Mask Flags */
#define IMM_CLIP_NONE FEELIT_FCLIP_NONE
#define IMM_CLIP_OUTERLEFTWALL FEELIT_FCLIP_OUTERLEFTWALL
#define IMM_CLIP_INNERLEFTWALL FEELIT_FCLIP_INNERLEFTWALL
#define IMM_CLIP_INNERRIGHTWALL FEELIT_FCLIP_INNERRIGHTWALL
#define IMM_CLIP_OUTERRIGHTWALL FEELIT_FCLIP_OUTERRIGHTWALL
#define IMM_CLIP_OUTERTOPWALL FEELIT_FCLIP_OUTERTOPWALL
#define IMM_CLIP_INNERTOPWALL FEELIT_FCLIP_INNERTOPWALL
#define IMM_CLIP_INNERBOTTOMWALL FEELIT_FCLIP_INNERBOTTOMWALL
#define IMM_CLIP_OUTERBOTTOMWALL FEELIT_FCLIP_OUTERBOTTOMWALL
#define IMM_CLIP_OUTERANYWALL FEELIT_FCLIP_OUTERANYWALL
#define IMM_CLIP_INNERANYWALL FEELIT_FCLIP_INNERANYWALL
#define IMM_CLIP_ANYWALL FEELIT_FCLIP_ANYWALL
/* Device capabilities Stuct */
#define IMM_DEVCAPS FEELIT_DEVCAPS
#define LPIMM_DEVCAPS LPFEELIT_DEVCAPS
#define LPCIMM_DEVCAPS LPCFEELIT_DEVCAPS
/* Device capabilities flags */
#define IMM_DEVCAPS_ATTACHED FEELIT_FDEVCAPS_ATTACHED
#define IMM_DEVCAPS_POLLEDDEVICE FEELIT_FDEVCAPS_POLLEDDEVICE
#define IMM_DEVCAPS_EMULATED FEELIT_FDEVCAPS_EMULATED
#define IMM_DEVCAPS_POLLEDDATAFORMAT FEELIT_FDEVCAPS_POLLEDDATAFORMAT
#define IMM_DEVCAPS_FORCEFEEDBACK FEELIT_FDEVCAPS_FORCEFEEDBACK
#define IMM_DEVCAPS_FFATTACK FEELIT_FDEVCAPS_FFATTACK
#define IMM_DEVCAPS_FFFADE FEELIT_FDEVCAPS_FFFADE
#define IMM_DEVCAPS_SATURATION FEELIT_FDEVCAPS_SATURATION
#define IMM_DEVCAPS_POSNEGCOEFFICIENTS FEELIT_FDEVCAPS_POSNEGCOEFFICIENTS
#define IMM_DEVCAPS_POSNEGSATURATION FEELIT_FDEVCAPS_POSNEGSATURATION
#define IMM_DEVCAPS_DEADBAND FEELIT_FDEVCAPS_DEADBAND
#define LPIMM_DEVICEINSTANCE LPFEELIT_DEVICEINSTANCE
#define LPCIMM_DEVICEOBJECTINSTANCE LPCFEELIT_DEVICEOBJECTINSTANCE
#define LPCIMM_EFFECTINFO LPCFEELIT_EFFECTINFO
#define IMM_PARAM_DURATION FEELIT_FPARAM_DURATION
#define IMM_PARAM_SAMPLEPERIOD FEELIT_FPARAM_SAMPLEPERIOD
#define IMM_PARAM_GAIN FEELIT_FPARAM_GAIN
#define IMM_PARAM_TRIGGERBUTTON FEELIT_FPARAM_TRIGGERBUTTON
#define IMM_PARAM_TRIGGERREPEATINTERVAL FEELIT_FPARAM_TRIGGERREPEATINTERVAL
#define IMM_PARAM_AXES FEELIT_FPARAM_AXES
#define IMM_PARAM_DIRECTION FEELIT_FPARAM_DIRECTION
#define IMM_PARAM_ENVELOPE FEELIT_FPARAM_ENVELOPE
#define IMM_PARAM_TYPESPECIFICPARAMS FEELIT_FPARAM_TYPESPECIFICPARAMS
#define IMM_PARAM_STARTDELAY FEELIT_FPARAM_STARTDELAY
#define IMM_PARAM_ALLPARAMS FEELIT_FPARAM_ALLPARAMS
#define IMM_PARAM_START FEELIT_FPARAM_START
#define IMM_PARAM_NORESTART FEELIT_FPARAM_NORESTART
#define IMM_PARAM_NODOWNLOAD FEELIT_FPARAM_NODOWNLOAD
#define IMM_EFFECT_OBJECTIDS FEELIT_FEFFECT_OBJECTIDS
#define IMM_EFFECT_OBJECTOFFSETS FEELIT_FEFFECT_OBJECTOFFSETS
#define IMM_EFFECT_CARTESIAN FEELIT_FEFFECT_CARTESIAN
#define IMM_EFFECT_POLAR FEELIT_FEFFECT_POLAR
#define IMM_EFFECT_SPHERICAL FEELIT_FEFFECT_SPHERICAL
#define IMM_PARAM_NOTRIGGER FEELIT_PARAM_NOTRIGGER
/* Offsets */
#define IMM_MOUSEOFFSET_XAXIS FEELIT_MOUSEOFFSET_XAXIS
#define IMM_MOUSEOFFSET_YAXIS FEELIT_MOUSEOFFSET_YAXIS
#define IMM_MOUSEOFFSET_ZAXIS FEELIT_MOUSEOFFSET_ZAXIS
#define IMM_MOUSEOFFSET_XFORCE FEELIT_MOUSEOFFSET_XFORCE
#define IMM_MOUSEOFFSET_YFORCE FEELIT_MOUSEOFFSET_YFORCE
#define IMM_MOUSEOFFSET_ZFORCE FEELIT_MOUSEOFFSET_ZFORCE
#define IMM_MOUSEOFFSET_BUTTON0 FEELIT_MOUSEOFFSET_BUTTON0
#define IMM_MOUSEOFFSET_BUTTON1 FEELIT_MOUSEOFFSET_BUTTON1
#define IMM_MOUSEOFFSET_BUTTON2 FEELIT_MOUSEOFFSET_BUTTON2
#define IMM_MOUSEOFFSET_BUTTON3 FEELIT_MOUSEOFFSET_BUTTON3
/* Cooperative Level Flags */
#define IMM_COOPLEVEL_FOREGROUND FEELIT_FCOOPLEVEL_FOREGROUND
#define IMM_COOPLEVEL_BACKGROUND FEELIT_FCOOPLEVEL_BACKGROUND
/* Enumeration codes */
#define IMM_ENUM_STOP FEELIT_ENUM_STOP
#define IMM_ENUM_CONTINUE FEELIT_ENUM_CONTINUE
#define IMM_ENUMDEV_ALLDEVICES FEELIT_FENUMDEV_ALLDEVICES
#define IMM_ENUMDEV_ATTACHEDONLY FEELIT_FENUMDEV_ATTACHEDONLY
#define IMM_ENUMDEV_FORCEFEEDBACK FEELIT_FENUMDEV_FORCEFEEDBACK
/* Return values */
#define IMM_RESULT_OK FEELIT_RESULT_OK
#define IMM_RESULT_NOTATTACHED FEELIT_RESULT_NOTATTACHED
#define IMM_RESULT_BUFFEROVERFLOW FEELIT_RESULT_BUFFEROVERFLOW
#define IMM_RESULT_PROPNOEFFECT FEELIT_RESULT_PROPNOEFFECT
#define IMM_RESULT_NOEFFECT FEELIT_RESULT_NOEFFECT
#define IMM_RESULT_POLLEDDEVICE FEELIT_RESULT_POLLEDDEVICE
#define IMM_RESULT_DOWNLOADSKIPPED FEELIT_RESULT_DOWNLOADSKIPPED
#define IMM_RESULT_EFFECTRESTARTED FEELIT_RESULT_EFFECTRESTARTED
#define IMM_RESULT_TRUNCATED FEELIT_RESULT_TRUNCATED
#define IMM_RESULT_TRUNCATEDANDRESTARTED FEELIT_RESULT_TRUNCATEDANDRESTARTED
#define IMM_ERROR_OLDFEELITVERSION FEELIT_ERROR_OLDFEELITVERSION
#define IMM_ERROR_BETAFEELITVERSION FEELIT_ERROR_BETAFEELITVERSION
#define IMM_ERROR_BADDRIVERVER FEELIT_ERROR_BADDRIVERVER
#define IMM_ERROR_DEVICENOTREG FEELIT_ERROR_DEVICENOTREG
#define IMM_ERROR_NOTFOUND FEELIT_ERROR_NOTFOUND
#define IMM_ERROR_OBJECTNOTFOUND FEELIT_ERROR_OBJECTNOTFOUND
#define IMM_ERROR_INVALIDPARAM FEELIT_ERROR_INVALIDPARAM
#define IMM_ERROR_NOINTERFACE FEELIT_ERROR_NOINTERFACE
#define IMM_ERROR_GENERIC FEELIT_ERROR_GENERIC
#define IMM_ERROR_OUTOFMEMORY FEELIT_ERROR_OUTOFMEMORY
#define IMM_ERROR_UNSUPPORTED FEELIT_ERROR_UNSUPPORTED
#define IMM_ERROR_NOTINITIALIZED FEELIT_ERROR_NOTINITIALIZED
#define IMM_ERROR_ALREADYINITIALIZED FEELIT_ERROR_ALREADYINITIALIZED
#define IMM_ERROR_NOAGGREGATION FEELIT_ERROR_NOAGGREGATION
#define IMM_ERROR_OTHERAPPHASPRIO FEELIT_ERROR_OTHERAPPHASPRIO
#define IMM_ERROR_INPUTLOST FEELIT_ERROR_INPUTLOST
#define IMM_ERROR_ACQUIRED FEELIT_ERROR_ACQUIRED
#define IMM_ERROR_NOTACQUIRED FEELIT_ERROR_NOTACQUIRED
#define IMM_ERROR_READONLY FEELIT_ERROR_READONLY
#define IMM_ERROR_HANDLEEXISTS FEELIT_ERROR_HANDLEEXISTS
#define IMM_ERROR_INSUFFICIENTPRIVS FEELIT_ERROR_INSUFFICIENTPRIVS
#define IMM_ERROR_DEVICEFULL FEELIT_ERROR_DEVICEFULL
#define IMM_ERROR_MOREDATA FEELIT_ERROR_MOREDATA
#define IMM_ERROR_NOTDOWNLOADED FEELIT_ERROR_NOTDOWNLOADED
#define IMM_ERROR_HASEFFECTS FEELIT_ERROR_HASEFFECTS
#define IMM_ERROR_NOTEXCLUSIVEACQUIRED FEELIT_ERROR_NOTEXCLUSIVEACQUIRED
#define IMM_ERROR_INCOMPLETEEFFECT FEELIT_ERROR_INCOMPLETEEFFECT
#define IMM_ERROR_NOTBUFFERED FEELIT_ERROR_NOTBUFFERED
#define IMM_ERROR_EFFECTPLAYING FEELIT_ERROR_EFFECTPLAYING
#define IMM_ERROR_INTERNAL FEELIT_ERROR_INTERNAL
#define IMM_ERROR_INACTIVE FEELIT_ERROR_INACTIVE
//================================================================
// GUID WRAPPERS
//================================================================
//
// Immersion --> Feelit Wrappers
//
#define GUID_Imm_ConstantForce GUID_Feelit_ConstantForce
#define GUID_Imm_RampForce GUID_Feelit_RampForce
#define GUID_Imm_Square GUID_Feelit_Square
#define GUID_Imm_Sine GUID_Feelit_Sine
#define GUID_Imm_Triangle GUID_Feelit_Triangle
#define GUID_Imm_SawtoothUp GUID_Feelit_SawtoothUp
#define GUID_Imm_SawtoothDown GUID_Feelit_SawtoothDown
#define GUID_Imm_Spring GUID_Feelit_Spring
#define GUID_Imm_DeviceSpring GUID_Feelit_DeviceSpring
#define GUID_Imm_Damper GUID_Feelit_Damper
#define GUID_Imm_Inertia GUID_Feelit_Inertia
#define GUID_Imm_Friction GUID_Feelit_Friction
#define GUID_Imm_Texture GUID_Feelit_Texture
#define GUID_Imm_Grid GUID_Feelit_Grid
#define GUID_Imm_Enclosure GUID_Feelit_Enclosure
#define GUID_Imm_Ellipse GUID_Feelit_Ellipse
#define GUID_Imm_CustomForce GUID_Feelit_CustomForce
#define CLSID_Imm CLSID_Feelit
#define CLSID_ImmDevice CLSID_FeelitDevice
#define GUID_Imm_XAxis GUID_Feelit_XAxis
#define GUID_Imm_YAxis GUID_Feelit_YAxis
#define GUID_Imm_ZAxis GUID_Feelit_ZAxis
#define GUID_Imm_RxAxis GUID_Feelit_RxAxis
#define GUID_Imm_RyAxis GUID_Feelit_RyAxis
#define GUID_Imm_RzAxis GUID_Feelit_RzAxis
#define GUID_Imm_Slider GUID_Feelit_Slider
#define GUID_Imm_Button GUID_Feelit_Button
#define GUID_Imm_Key GUID_Feelit_Key
#define GUID_Imm_POV GUID_Feelit_POV
#define GUID_Imm_Unknown GUID_Feelit_Unknown
#define GUID_Imm_Mouse GUID_Feelit_Mouse
#endif // !defined(AFX_IMMBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

170
code/ff/IFC/ImmBox.h Normal file
View File

@@ -0,0 +1,170 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmBox.h
PURPOSE: Box Class for Immersion Foundation Classes
STARTED: 11/04/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
#include "ImmEnclosure.h"
//================================================================
// Constants
//================================================================
const POINT IMM_BOX_MOUSE_POS_AT_START = { MAXLONG, MAXLONG };
#define IMM_BOX_DEFAULT_STIFFNESS 5000
#define IMM_BOX_DEFAULT_WIDTH 10
#define IMM_BOX_DEFAULT_HEIGHT IMM_ENCLOSURE_HEIGHT_AUTO
#define IMM_BOX_DEFAULT_WALL_WIDTH IMM_ENCLOSURE_WALL_WIDTH_AUTO
#define IMM_BOX_DEFAULT_CENTER_POINT IMM_BOX_MOUSE_POS_AT_START
//================================================================
// CImmBox
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmBox : public CImmEnclosure
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmBox();
// Destructor
virtual
~CImmBox();
//
// ATTRIBUTES
//
public:
BOOL
ChangeParameters(
POINT pntCenter,
LONG lStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwHeight = IMM_EFFECT_DONT_CHANGE,
DWORD dwWallWidth = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParameters(
LPCRECT pRectOutside,
LONG lStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwWallWidth = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE
);
//
// OPERATIONS
//
public:
BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwWidth = IMM_ENCLOSURE_DEFAULT_WIDTH,
DWORD dwHeight = IMM_ENCLOSURE_DEFAULT_HEIGHT,
LONG lStiffness = IMM_BOX_DEFAULT_STIFFNESS,
DWORD dwWallWidth = IMM_BOX_DEFAULT_WALL_WIDTH,
POINT pntCenter = IMM_BOX_DEFAULT_CENTER_POINT,
CImmEffect* pInsideEffect = NULL,
DWORD dwNoDownload = 0
);
BOOL
Initialize(
CImmDevice* pDevice,
LPCRECT pRectOutside,
LONG lStiffness = IMM_BOX_DEFAULT_STIFFNESS,
DWORD dwWallWidth = IMM_BOX_DEFAULT_WALL_WIDTH,
CImmEffect* pInsideEffect = NULL,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
#endif // !defined(AFX_IMMBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

View File

@@ -0,0 +1,228 @@
/**********************************************************************
Copyright (c) 1999 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmCompoundEffect.h
PURPOSE: Manages Compound Effects for Force Foundation Classes
STARTED: 2/24/99 by Jeff Mallett
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
#include "ImmIFR.h"
#if !defined(__FEELCOMPOUNDEFFECT_H)
#define __FEELCOMPOUNDEFFECT_H
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
/*
** IMM_FFE_FILEEFFECT - struct used by DX7 to read and write to FFE
** files. This struct is different from DIFILEEFFECT due to the use
** of the non const LPDIEFFECT. An LPDIEFFECT is needed to be able to
** collect information from IFC class objects. This should be defined
** elsewhere, but no more appropriate header currently exists.
*/
typedef struct IMM_FFE_FILEEFFECT{
DWORD dwSize;
GUID GuidEffect;
LPDIEFFECT lpDiEffect;
CHAR szFriendlyName[MAX_PATH];
}IMM_FFE_FILEEFFECT, *LPIMM_FFE_FILEEFFECT;
//================================================================
// CImmCompoundEffect
//================================================================
// Represents a compound effect, such as might be created in
// Immersion Studio. Contains an array of effect objects.
// Methods iterate over component effects, passing the message
// to each one.
// Also, has stuff for being used by CImmProject:
// * next pointer so can be put on a linked list
// * force name
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmCompoundEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public://### protected:
// Constructs a CImmCompoundEffect
// Don't try to construct a CImmCompoundEffect yourself.
// Instead let CImmProject construct it for you.
CImmCompoundEffect(
IFREffect **hEffects,
long nEffects,
LPCSTR pEffectName
);
public:
~CImmCompoundEffect();
//
// ATTRIBUTES
//
public:
long
GetNumberOfContainedEffects() const
{ return m_nEffects; }
const char *
GetName() const
{ return m_lpszName; }
GENERIC_EFFECT_PTR
GetContainedEffect(
long index
);
GENERIC_EFFECT_PTR
GetContainedEffect(
LPCSTR lpszEffectName
);
DWORD
GetEffectType();
//
// OPERATIONS
//
public:
// Start all the contained effects
BOOL Start(
DWORD dwIterations = IMM_EFFECT_DONT_CHANGE,
DWORD dwFlags = 0
);
// Stop all the contained effects
BOOL Stop();
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL initialize(
CImmDevice* pDevice,
IFREffect **hEffects,
DWORD dwNoDownload
);
BOOL
set_contained_effect(
GENERIC_EFFECT_PTR pObject,
int index = 0
);
BOOL
set_name(
const char *lpszName
);
void
set_next(
CImmCompoundEffect *pNext
)
{ m_pNext = pNext; }
CImmCompoundEffect *
get_next() const
{ return m_pNext; }
void
set_objID(
GUID* pobjID
)
{ m_objID = *pobjID; }
BOOL
set_contained_obj_IDs(
GUID *guidList
);
int
buffer_ifr_object(TCHAR* pData);
BOOL
get_ffe_object(LPIMM_FFE_FILEEFFECT pffeObject);
//
// FRIENDS
//
public:
friend class CImmProject;
//
// INTERNAL DATA
//
protected:
GENERIC_EFFECT_PTR *m_paEffects; // Array of force class object pointers
long m_nEffects; // Number of effects in m_paEffects
private:
char *m_lpszName; // Name of the compound effect
GUID m_objID;
GUID *m_pContainedObjIDs;
CImmCompoundEffect *m_pNext; // Next compound effect in the project
#ifdef PROTECT_AGAINST_DELETION
CImmProject *m_pOwningProject;
#endif
};
#endif

451
code/ff/IFC/ImmCondition.h Normal file
View File

@@ -0,0 +1,451 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmCondition.h
PURPOSE: Immersion Foundation Classes Base Condition Effect
STARTED: Oct.10.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMCondition_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMCondition_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
const POINT IMM_CONDITION_PT_NULL = { 0, 0 };
#define IMM_CONDITION_DEFAULT_COEFFICIENT 2500
#define IMM_CONDITION_DEFAULT_SATURATION 10000
#define IMM_CONDITION_DEFAULT_DEADBAND 100
#define IMM_CONDITION_DEFAULT_CENTER_POINT IMM_EFFECT_MOUSE_POS_AT_START
#define IMM_CONDITION_DEFAULT_DURATION INFINITE
typedef enum {
IC_NULL = 0,
IC_POSITIVE_COEFFICIENT,
IC_NEGATIVE_COEFFICIENT,
IC_POSITIVE_SATURATION,
IC_NEGATIVE_SATURATION,
IC_DEAD_BAND,
IC_AXIS,
IC_CENTER,
IC_DIRECTION_X,
IC_DIRECTION_Y,
IC_ANGLE,
IC_CONDITION_X,
IC_CONDITION_Y
} IC_ArgumentType;
#define IC_CONDITION IC_CONDITION_X
//================================================================
// CImmCondition
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmCondition : public CImmEffect
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmCondition(
const GUID& rguidEffect
);
// Destructor
virtual
~CImmCondition();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_CONDITION; }
// Use this form for single-axis and dual-axis effects
BOOL
ChangeConditionParams(
LPCIMM_CONDITION pConditionX,
LPCIMM_CONDITION pConditionY
);
// Use this form for directional effects
BOOL
ChangeConditionParams(
LPCIMM_CONDITION pCondition,
LONG lDirectionX,
LONG lDirectionY
);
// Use this form for directional effects
BOOL
ChangeConditionParamsPolar(
LPCIMM_CONDITION pCondition,
LONG lAngle
);
// Use this form for single-axis, dual-axis, or directional effects
BOOL
ChangeConditionParamsX(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient = IMM_EFFECT_DONT_CHANGE,
DWORD dwPositiveSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegativeSaturation = IMM_EFFECT_DONT_CHANGE,
LONG lDeadBand = IMM_EFFECT_DONT_CHANGE,
POINT pntCenter = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeConditionParamsPolarX(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient,
DWORD dwPositiveSaturation,
DWORD dwNegativeSaturation,
LONG lDeadBand,
POINT pntCenter,
LONG lAngle
);
BOOL
ChangeConditionParamsY(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient = IMM_EFFECT_DONT_CHANGE,
DWORD dwPositiveSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegativeSaturation = IMM_EFFECT_DONT_CHANGE,
LONG lDeadBand = IMM_EFFECT_DONT_CHANGE,
POINT pntCenter = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeConditionParamsPolarY(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient,
DWORD dwPositiveSaturation,
DWORD dwNegativeSaturation,
LONG lDeadBand,
POINT pntCenter,
LONG lAngle
);
// Use this form for single-axis, dual-axis symetrical, or directional effects
BOOL
ChangeConditionParams(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient = IMM_EFFECT_DONT_CHANGE,
DWORD dwPositiveSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegativeSaturation = IMM_EFFECT_DONT_CHANGE,
LONG lDeadBand = IMM_EFFECT_DONT_CHANGE,
POINT pntCenter = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeConditionParamsPolar(
LONG lPositiveCoefficient,
LONG lNegativeCoefficient,
DWORD dwPositiveSaturation,
DWORD dwNegativeSaturation,
LONG lDeadBand,
POINT pntCenter,
LONG lAngle
);
BOOL ChangePositiveCoefficientX( LONG lPositiveCoefficient );
BOOL ChangeNegativeCoefficientX( LONG lNegativeCoefficient );
BOOL ChangePositiveSaturationX( DWORD dwPositiveSaturation );
BOOL ChangeNegativeSaturationX( DWORD dwNegativeSaturation );
BOOL ChangeDeadBandX( LONG lDeadBand );
BOOL ChangePositiveCoefficientY( LONG lPositiveCoefficient );
BOOL ChangeNegativeCoefficientY( LONG lNegativeCoefficient );
BOOL ChangePositiveSaturationY( DWORD dwPositiveSaturation );
BOOL ChangeNegativeSaturationY( DWORD dwNegativeSaturation );
BOOL ChangeDeadBandY( LONG lDeadBand );
BOOL ChangePositiveCoefficient( LONG lPositiveCoefficient );
BOOL ChangeNegativeCoefficient( LONG lNegativeCoefficient );
BOOL ChangePositiveSaturation( DWORD dwPositiveSaturation );
BOOL ChangeNegativeSaturation( DWORD dwNegativeSaturation );
BOOL ChangeDeadBand( LONG lDeadBand );
BOOL
SetCenter(
POINT pntCenter
);
BOOL
ChangeConditionParams2(
IC_ArgumentType type,
...
);
BOOL GetPositiveCoefficientX( LONG &lPositiveCoefficient );
BOOL GetNegativeCoefficientX( LONG &lNegativeCoefficient );
BOOL GetPositiveSaturationX( DWORD &dwPositiveSaturation );
BOOL GetNegativeSaturationX( DWORD &dwNegativeSaturation );
BOOL GetDeadBandX( LONG &lDeadBand );
BOOL GetPositiveCoefficientY( LONG &lPositiveCoefficient );
BOOL GetNegativeCoefficientY( LONG &lNegativeCoefficient );
BOOL GetPositiveSaturationY( DWORD &dwPositiveSaturation );
BOOL GetNegativeSaturationY( DWORD &dwNegativeSaturation );
BOOL GetDeadBandY( LONG &lDeadBand );
BOOL GetAxis( DWORD &dwfAxis );
BOOL GetCenter( POINT &pntCenter );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
// Use this form for single-axis and dual-axis effects
BOOL
InitCondition(
CImmDevice* pDevice,
LPCIMM_CONDITION pConditionX,
LPCIMM_CONDITION pConditionY,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitCondition(
CImmDevice* pDevice,
LPCIMM_CONDITION pCondition,
LONG lDirectionX,
LONG lDirectionY,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitConditionPolar(
CImmDevice* pDevice,
LPCIMM_CONDITION pCondition,
LONG lAngle,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
// Use this form for single-axis, dual-axis symetrical, or directional effects
BOOL
InitCondition(
CImmDevice* pDevice,
LONG lPositiveCoefficient = IMM_CONDITION_DEFAULT_COEFFICIENT,
LONG lNegativeCoefficient = IMM_CONDITION_DEFAULT_COEFFICIENT,
DWORD dwPositiveSaturation = IMM_CONDITION_DEFAULT_SATURATION,
DWORD dwNegativeSaturation = IMM_CONDITION_DEFAULT_SATURATION,
LONG lDeadBand = IMM_CONDITION_DEFAULT_DEADBAND,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
POINT pntCenter = IMM_CONDITION_DEFAULT_CENTER_POINT,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitConditionPolar(
CImmDevice* pDevice,
LONG lPositiveCoefficient = IMM_CONDITION_DEFAULT_COEFFICIENT,
LONG lNegativeCoefficient = IMM_CONDITION_DEFAULT_COEFFICIENT,
DWORD dwPositiveSaturation = IMM_CONDITION_DEFAULT_SATURATION,
DWORD dwNegativeSaturation = IMM_CONDITION_DEFAULT_SATURATION,
LONG lDeadBand = IMM_CONDITION_DEFAULT_DEADBAND,
POINT pntCenter = IMM_CONDITION_DEFAULT_CENTER_POINT,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
virtual BOOL
Start(
DWORD dwIterations = 1,
DWORD dwFlags = 0,
BOOL bAllowStartDelayEmulation = true
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
void
convert_line_point_to_offset(
POINT pntOnLine
);
BOOL
set_parameters(
DWORD dwfAxis,
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
LPCIMM_CONDITION pConditionX,
LPCIMM_CONDITION pConditionY
);
BOOL
set_parameters(
DWORD dwfAxis,
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
LONG lPositiveCoefficient,
LONG lNegativeCoefficient,
DWORD dwPositiveSaturation,
DWORD dwNegativeSaturation,
LONG lDeadBand,
POINT pntCenter
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
LONG lPositiveCoefficient,
LONG lNegativeCoefficient,
DWORD dwPositiveSaturation,
DWORD dwNegativeSaturation,
LONG lDeadBand,
POINT pntCenter,
int fAxis
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
LPCIMM_CONDITION pConditionX,
LPCIMM_CONDITION pConditionY
);
int
buffer_ifr_data(
TCHAR* pData
);
BOOL
get_ffe_data(
LPDIEFFECT pdiEffect
);
//
// INTERNAL DATA
//
IMM_CONDITION m_aCondition[2];
DWORD m_dwfAxis;
BOOL m_bUseMousePosAtStart;
protected:
BOOL m_bUseDeviceCoordinates;
};
//
// INLINES
//
inline BOOL
CImmCondition::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Spring) ||
IsEqualGUID(guid, GUID_Imm_DeviceSpring) ||
IsEqualGUID(guid, GUID_Imm_Damper) ||
IsEqualGUID(guid, GUID_Imm_Inertia) ||
IsEqualGUID(guid, GUID_Imm_Friction) ||
IsEqualGUID(guid, GUID_Imm_Texture) ||
IsEqualGUID(guid, GUID_Imm_Grid);
}
#endif // !defined(AFX_IMMCondition_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

219
code/ff/IFC/ImmConstant.h Normal file
View File

@@ -0,0 +1,219 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmConstant.h
PURPOSE: Base Constant Class for Immersion Foundation Classes
STARTED: 11/03/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
const POINT IMM_CONSTANT_DEFAULT_DIRECTION = { 1, 0 };
#define IMM_CONSTANT_DEFAULT_DURATION 1000 // Milliseconds
#define IMM_CONSTANT_DEFAULT_MAGNITUDE 5000
//================================================================
// CImmConstant
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmConstant : public CImmEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmConstant();
// Destructor
virtual
~CImmConstant();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_CONSTANTFORCE; }
BOOL
ChangeParameters(
LONG lDirectionX,
LONG lDirectionY,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lMagnitude = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL
ChangeParametersPolar(
LONG lAngle,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lMagnitude = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL ChangeMagnitude( LONG lMagnitude );
BOOL GetMagnitude( LONG &lMagnitude );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
virtual
BOOL
Initialize(
CImmDevice* pDevice,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwDuration = IMM_CONSTANT_DEFAULT_DURATION,
LONG lMagnitude = IMM_CONSTANT_DEFAULT_MAGNITUDE,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwNoDownload = 0
);
virtual
BOOL
InitializePolar(
CImmDevice* pDevice,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwDuration = IMM_CONSTANT_DEFAULT_DURATION,
LONG lMagnitude = IMM_CONSTANT_DEFAULT_MAGNITUDE,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
LONG lMagnitude,
LPIMM_ENVELOPE pEnvelope
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
LONG lMagnitude,
LPIMM_ENVELOPE pEnvelope
);
int
buffer_ifr_data(
TCHAR* pData
);
BOOL
get_ffe_data(
LPDIEFFECT pdiEffect
);
//
// INTERNAL DATA
//
IMM_CONSTANTFORCE m_ConstantForce;
protected:
};
//
// INLINES
//
inline BOOL
CImmConstant::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_ConstantForce);
}
#endif // !defined(AFX_IMMCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

148
code/ff/IFC/ImmDXDevice.h Normal file
View File

@@ -0,0 +1,148 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmDXDevice.h
PURPOSE: Abstraction of DirectX Force Feedback device
STARTED: 10/10/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#ifndef ImmDXDevice_h
#define ImmDXDevice_h
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmDevice.h"
//================================================================
// CImmDXDevice
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmDXDevice : public CImmDevice
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmDXDevice();
// Destructor
virtual
~CImmDXDevice();
//
// ATTRIBUTES
//
public:
virtual LPIIMM_API
GetAPI()
{ return (LPIIMM_API) m_piApi; } // actually LPDIRECTINPUT
virtual LPIIMM_DEVICE
GetDevice()
{ return (LPIIMM_DEVICE) m_piDevice; } // actually LPDIRECTINPUTDEVICE2
virtual DWORD GetProductType();
virtual BOOL GetDriverVersion(
DWORD &dwFFDriverVersion,
DWORD &dwFirmwareRevision,
DWORD &dwHardwareRevision);
virtual int GetProductName(LPTSTR lpszProductName, int nMaxCount);
virtual int GetProductGUIDString(LPTSTR lpszGUID, int nMaxCount);
virtual GUID GetProductGUID();
//
// OPERATIONS
//
public:
BOOL
Initialize(
HANDLE hinstApp,
HANDLE hwndApp,
LPDIRECTINPUT pDI = NULL,
LPDIRECTINPUTDEVICE2 piDevice = NULL,
BOOL bEnumerate = TRUE
);
virtual BOOL
GetCurrentPosition( long &lXPos, long &lYPos );
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
virtual void
reset();
friend class CImmDevices;
static BOOL CALLBACK
devices_enum_proc(
LPDIDEVICEINSTANCE pImmDevInst,
LPVOID pv
);
//
// INTERNAL DATA
//
protected:
// TODO: these are unused... delete them in future rev
BOOL m_bpDIPreExist;
BOOL m_bpDIDevicePreExist;
// end of useless variables
LPDIRECTINPUT m_piApi;
LPDIRECTINPUTDEVICE2 m_piDevice;
};
#endif // ForceDXDevice_h

185
code/ff/IFC/ImmDamper.h Normal file
View File

@@ -0,0 +1,185 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmDamper.h
PURPOSE: Immersion Foundation Classes Damper Effect
STARTED: Oct.14.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmCondition.h"
//================================================================
// Constants
//================================================================
#define IMM_DAMPER_DEFAULT_VISCOSITY 2500
#define IMM_DAMPER_DEFAULT_SATURATION 10000
#define IMM_DAMPER_DEFAULT_MIN_VELOCITY 0
//================================================================
// CImmDamper
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmDamper : public CImmCondition
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmDamper();
// Destructor
virtual ~CImmDamper();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
BOOL
ChangeParameters(
LONG lViscosity,
DWORD dwSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwMinVelocity = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParametersPolar(
LONG lViscosity,
DWORD dwSaturation,
DWORD dwMinVelocity,
LONG lAngle
);
BOOL ChangeViscosity( LONG lViscosity );
BOOL ChangeMinVelocityX( DWORD dwMinVelocity );
BOOL ChangeMinVelocityY( DWORD dwMinVelocity );
//For setting both axes to the same value
BOOL ChangeMinVelocity( DWORD dwMinVelocity );
BOOL GetViscosity( LONG &lViscosity );
BOOL GetMinVelocityX( DWORD &dwMinVelocity );
BOOL GetMinVelocityY( DWORD &dwMinVelocity );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwViscosity = IMM_DAMPER_DEFAULT_VISCOSITY,
DWORD dwSaturation = IMM_DAMPER_DEFAULT_SATURATION,
DWORD dwMinVelocity = IMM_DAMPER_DEFAULT_MIN_VELOCITY,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
DWORD dwViscosity,
DWORD dwSaturation,
DWORD dwMinVelocity,
LONG lAngle,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
//
// INLINES
//
inline BOOL
CImmDamper::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Damper);
}
#endif // !defined(AFX_IMMDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

281
code/ff/IFC/ImmDevice.h Normal file
View File

@@ -0,0 +1,281 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmDevice.h
PURPOSE: Abstract Base Device Class for Force Foundation Classes
STARTED: 10/10/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
3/16/99 jrm: Made abstract. Moved functionality to CImmMouse/CImmDXDevice
**********************************************************************/
#if !defined(AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#define DIRECTINPUT_VERSION 0x0800 //[ 0x0300 | 0x0500 | 0x0700 | 0x0800 ]
#include <dinput.h>
#include "ImmBaseTypes.h"
#ifdef IFC_EFFECT_CACHING
#include "ImmEffectSuite.h"
#endif
//================================================================
// Device and Technology types
//================================================================
//Company IDs
const DWORD IMM_OTHERPARTNER =0x01000000;
const DWORD IMM_IMMERSION =0x02000000;
const DWORD IMM_ACTLABS =0x03000000;
const DWORD IMM_ANKO =0x04000000;
const DWORD IMM_AVB =0x05000000;
const DWORD IMM_BOEDER =0x06000000;
const DWORD IMM_CHPRODUCTS =0x07000000;
const DWORD IMM_CHIC =0x08000000;
const DWORD IMM_GUILLEMOT =0x09000000;
const DWORD IMM_GENIUS =0x0a000000;
const DWORD IMM_HAPP =0x0b000000;
const DWORD IMM_INTERACT =0x0c000000;
const DWORD IMM_INTERACTIVEIO =0x0d000000;
const DWORD IMM_KYE =0x0e000000;
const DWORD IMM_LMP =0x0f000000;
const DWORD IMM_LOGITECH =0x10000000;
const DWORD IMM_MADCATZ =0x11000000;
const DWORD IMM_MICROSOFT =0x12000000;
const DWORD IMM_PADIX =0x13000000;
const DWORD IMM_PRIMAX =0x14000000;
const DWORD IMM_QUANTUM3D =0x15000000;
const DWORD IMM_ROCKFIRE =0x16000000;
const DWORD IMM_SCT =0x17000000;
const DWORD IMM_SMELECTRONIC =0x18000000;
const DWORD IMM_SYSGRATION =0x19000000;
const DWORD IMM_THRUSTMASTER =0x1a000000;
const DWORD IMM_TRUST =0x1b000000;
const DWORD IMM_VIKINGS =0x1c000000;
// Device IDs
const DWORD IMM_OTHERDEVICE =0x00000001;
const DWORD IMM_JOYSTICK =0x00000002;
const DWORD IMM_WHEEL =0x00000003;
const DWORD IMM_GAMEPAD =0x00000004;
const DWORD IMM_ABSMOUSE =0x00000005;
const DWORD IMM_RELMOUSE =0x00000006;
//Technology IDs
//Note that these are bit masks
const DWORD IMM_OTHERTECH =0x00000001;
const DWORD IMM_FULLFF =0x00000002;
const DWORD IMM_IHDFF =0x00000004;
const DWORD IMM_VIBROFF =0x00000008;
//Product Types (not to be confused with product GUIDs)
const DWORD IMM_JOYSTICK_FULLFF = MAKELONG(IMM_FULLFF, IMM_JOYSTICK);
const DWORD IMM_WHEEL_FULLFF = MAKELONG(IMM_FULLFF, IMM_WHEEL);
const DWORD IMM_GAMEPAD_FULLFF = MAKELONG(IMM_FULLFF, IMM_GAMEPAD);
const DWORD IMM_ABSMOUSE_FULLFF = MAKELONG(IMM_FULLFF, IMM_ABSMOUSE);
const DWORD IMM_JOYSTICK_IHDFF = MAKELONG(IMM_IHDFF, IMM_JOYSTICK);
const DWORD IMM_WHEEL_IHDFF = MAKELONG(IMM_IHDFF, IMM_WHEEL);
const DWORD IMM_GAMEPAD_IHDFF = MAKELONG(IMM_IHDFF, IMM_GAMEPAD);
const DWORD IMM_RELMOUSE_IHDFF = MAKELONG(IMM_IHDFF, IMM_RELMOUSE);
const DWORD IMM_JOYSTICK_VIBROFF= MAKELONG(IMM_VIBROFF, IMM_JOYSTICK);
const DWORD IMM_WHEEL_VIBROFF = MAKELONG(IMM_VIBROFF, IMM_WHEEL);
const DWORD IMM_GAMEPAD_VIBROFF = MAKELONG(IMM_VIBROFF, IMM_GAMEPAD);
const DWORD IMM_RELMOUSE_VIBROFF= MAKELONG(IMM_VIBROFF, IMM_RELMOUSE);
//================================================================
// CImmDevice
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmDevice
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmDevice();
// Destructor
virtual
~CImmDevice();
//
// ATTRIBUTES
//
public:
virtual LPIIMM_API
GetAPI()
= 0; // pure virtual function
virtual LPIIMM_DEVICE // Will actually return LPDIRECTINPUTDEVICE2 for DX supported device
GetDevice()
= 0; // pure virtual function
DWORD
GetDeviceType() const
{ return m_dwDeviceType; }
virtual DWORD GetProductType() = 0;
virtual BOOL GetDriverVersion(
DWORD &dwFFDriverVersion,
DWORD &dwFirmwareRevision,
DWORD &dwHardwareRevision)
= 0;
virtual int GetProductName(LPTSTR lpszProductName, int nMaxCount) = 0;
virtual int GetProductGUIDString(LPTSTR lpszGUID, int nMaxCount) = 0;
virtual GUID GetProductGUID() = 0;
static BOOL GetIFCVersion(DWORD &dwMajor, DWORD &dwMinor, DWORD &dwBuild, DWORD &dwBuildMinor);
static BOOL GetImmAPIVersion(DWORD &dwMajor, DWORD &dwMinor, DWORD &dwBuild, DWORD &dwBuildMinor);
static BOOL GetDXVersion(DWORD &dwMajor, DWORD &dwMinor, DWORD &dwBuild, DWORD &dwBuildMinor);
//
// OPERATIONS
//
public:
static CImmDevice *
CreateDevice(HINSTANCE hinstApp, HWND hwndApp);
virtual BOOL
GetCurrentPosition( long &lXPos, long &lYPos )
= 0; // pure virtual function
virtual BOOL
ChangeScreenResolution(
BOOL bAutoSet,
DWORD dwXScreenSize = 0,
DWORD dwYScreenSize = 0
);
// The default state is using standard Win32 Mouse messages (e.g., WM_MOUSEMOVE)
// and functions (e.g, GetCursorPos). Call only to switch to relative mode
// if not using standard Win32 Mouse services (e.g., DirectInput) for mouse
// input.
BOOL
UsesWin32MouseServices(
BOOL bWin32MouseServ
);
// Another syntax for SwitchToAbsoluteMode.
// The default is Absolute mode. Call only to switch to Relative mode or
// to switch back to Absolute mode.
virtual BOOL
SwitchToAbsoluteMode(
BOOL bAbsMode
);
//
// ------ PRIVATE INTERFACE ------
//
//
// CACHING
//
#ifdef IFC_EFFECT_CACHING
public:
void Cache_AddEffect(CImmEffect *pImmEffect);
void Cache_RemoveEffect(const CImmEffect *pImmEffect);
void Cache_SwapOutEffect();
protected:
void Cache_LoadEffectSuite(CImmEffectSuite *pSuite, BOOL bCreateOnDevice);
void Cache_UnloadEffectSuite(CImmEffectSuite *pSuite, BOOL bUnloadFromDevice);
CEffectList m_Cache; // List of all effects created on device
#endif
//
// HELPERS
//
protected:
// Performs device preparation by setting the device's parameters
virtual BOOL
prepare_device();
virtual void
reset()
= 0; // pure virtual function
static BOOL CALLBACK
enum_didevices_proc(
LPDIDEVICEINSTANCE pImmDevInst,
LPVOID pv
);
static BOOL CALLBACK
enum_devices_proc(
LPIMM_DEVICEINSTANCE pImmDevInst,
LPVOID pv
);
void
detach_effects();
//
// INTERNAL DATA
//
protected:
BOOL m_bInitialized;
DWORD m_dwDeviceType;
GUID m_guidDevice;
BOOL m_bGuidValid;
DWORD m_dwProductType;
};
#endif // !defined(AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

156
code/ff/IFC/ImmDevices.h Normal file
View File

@@ -0,0 +1,156 @@
/**********************************************************************
Copyright (c) 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmDevices.h
PURPOSE: Abstract Base Device Class for Immersion Foundation Classes
STARTED: 3/29/00
NOTES/REVISIONS:
3/29/00 jrm (Jeff Mallett): Started
**********************************************************************/
#if !defined(AFX_FORCEDEVICES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_FORCEDEVICES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
typedef enum {
IMM_ENUMERATE_IMM_DEVICES = 0x00000001,
IMM_ENUMERATE_DX_DEVICES = 0x00000002,
IMM_ENUMERATE_ALL = 0xFFFFFFFF
} IMM_ENUMERATE;
typedef enum {
IMM_NO_PREFERENCE = 0x00000000,
IMM_PREFER_IMM_DEVICES = 0x00000001,
IMM_PREFER_DX_DEVICES = 0x00000002
} IMM_ENUMERATE_PREFERENCE;
class CImmDevices;
class CInitializeEnum {
public:
HANDLE m_hinstApp;
HANDLE m_hwndApp;
DWORD m_dwCooperativeFlag;
CImmDevices *m_pDevices;
long m_lMaximumDevices;
};
//================================================================
// CImmDevices
//================================================================
typedef class CImmDevice * IMM_DEVICE_PTR;
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmDevices {
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
CImmDevices();
~CImmDevices();
//
// ATTRIBUTES
//
public:
long
GetNumDevices()
{ return m_lNumDevices; }
IMM_DEVICE_PTR
GetDevice(long lIndex);
//
// OPERATIONS
//
public:
void
AddDevice(IMM_DEVICE_PTR pDevice);
long
CreateDevices(
HINSTANCE hinstApp,
HWND hwndApp,
long lMaximumDevices = -1, // means "all"
IMM_ENUMERATE type = IMM_ENUMERATE_ALL,
IMM_ENUMERATE_PREFERENCE preference = IMM_NO_PREFERENCE
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
enumerate_dx_devices(CInitializeEnum *pIE);
BOOL
enumerate_imm_devices(CInitializeEnum *pIE);
void
clean_up();
//
// INTERNAL DATA
//
protected:
long m_lNumDevices;
IMM_DEVICE_PTR *m_DeviceArray;
};
#endif // !defined(AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

440
code/ff/IFC/ImmEffect.h Normal file
View File

@@ -0,0 +1,440 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmEffect.h
PURPOSE: Immersion Foundation Classes Base Effect
STARTED: Oct.10.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID and feel_to_DI_GUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMEffect_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMEffect_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmDevice.h"
class CImmProject;
//================================================================
// Constants
//================================================================
#define IMM_EFFECT_AXIS_X 1
#define IMM_EFFECT_AXIS_Y 2
#define IMM_EFFECT_AXIS_BOTH 3
#define IMM_EFFECT_AXIS_DIRECTIONAL 4
#define IMM_EFFECT_DONT_CHANGE MINLONG
#define IMM_EFFECT_DONT_CHANGE_PTR MAXDWORD
const POINT IMM_EFFECT_DONT_CHANGE_POINT = { 0xFFFFFFFF, 0xFFFFFFFF };
const POINT IMM_EFFECT_MOUSE_POS_AT_START = { MAXLONG, MAXLONG };
#define IMM_EFFECT_DEFAULT_ENVELOPE NULL
#define IMM_EFFECT_DEFAULT_DIRECTION_X 1
#define IMM_EFFECT_DEFAULT_DIRECTION_Y 1
#define IMM_EFFECT_DEFAULT_ANGLE 0
// GENERIC_EFFECT_PTR
// This is really a pointer to a child of CImmEffect.
typedef class CImmEffect * GENERIC_EFFECT_PTR;
//================================================================
// CImmEffect
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmEffect(
const GUID& rguidEffect
);
// Destructor
virtual
~CImmEffect();
//
// ATTRIBUTES
//
public:
LPIIMM_EFFECT
GetEffect()
{ return m_piImmEffect; }
CImmDevice*
GetDevice()
{ return m_pImmDevice; }
BOOL
GetStatus(
DWORD* pdwStatus
);
void
GetParameters(IMM_EFFECT &Effect);
BOOL GetEnvelope( LPIMM_ENVELOPE pEnvelope );
BOOL GetDuration( DWORD &dwDuration );
BOOL GetGain( DWORD &dwGain );
BOOL GetStartDelay( DWORD &dwStartDelay );
BOOL GetTriggerButton( DWORD &dwTriggerButton );
BOOL GetTriggerRepeatInterval( DWORD &dwTriggerRepeatInterval );
BOOL GetDirection( LONG &lDirectionX, LONG &lDirectionY );
BOOL GetDirection( LONG &lAngle );
BOOL GetIterations( DWORD &dwIterations );
GUID
GetGUID()
{ return m_guidEffect; }
virtual BOOL
GetIsCompatibleGUID(
GUID & /* guid */
)
{ return true; }
virtual DWORD GetEffectType()
{ return 0; }
LPCSTR
GetName()
{ return m_lpszName; }
// Allocates an object of the correct IFC class from the given GUID
static GENERIC_EFFECT_PTR
NewObjectFromGUID(
GUID &guid
);
BOOL
ChangeBaseParams(
LONG lDirectionX,
LONG lDirectionY,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR,
DWORD dwSamplePeriod = IMM_EFFECT_DONT_CHANGE,
DWORD dwGain = IMM_EFFECT_DONT_CHANGE,
DWORD dwTriggerButton = IMM_EFFECT_DONT_CHANGE,
DWORD dwTriggerRepeatInterval = IMM_EFFECT_DONT_CHANGE
#ifdef IFC_START_DELAY
,DWORD dwStartDelay = IMM_EFFECT_DONT_CHANGE // milliseconds
#endif
);
BOOL
ChangeBaseParamsPolar(
LONG lAngle,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE, // milliseconds
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR,
DWORD dwSamplePeriod = IMM_EFFECT_DONT_CHANGE,
DWORD dwGain = IMM_EFFECT_DONT_CHANGE,
DWORD dwTriggerButton = IMM_EFFECT_DONT_CHANGE,
DWORD dwTriggerRepeatInterval = IMM_EFFECT_DONT_CHANGE
#ifdef IFC_START_DELAY
,DWORD dwStartDelay = IMM_EFFECT_DONT_CHANGE // milliseconds
#endif
);
BOOL
ChangeDirection(
LONG lDirectionX,
LONG lDirectionY
);
BOOL
ChangeDirection(
LONG lAngle
);
BOOL
ChangeDuration(
DWORD dwDuration
);
BOOL
ChangeGain(
DWORD dwGain
);
BOOL
ChangeStartDelay(
DWORD dwStartDelay
);
BOOL
ChangeTriggerButton(
DWORD dwTriggerButton
);
BOOL
ChangeTriggerRepeatInterval(
DWORD dwTriggerRepeatInterval
);
BOOL
ChangeIterations(
DWORD dwIterations
);
BOOL
ChangeEnvelope(
DWORD dwAttackLevel,
DWORD dwAttackTime, // microseconds
DWORD dwFadeLevel,
DWORD dwFadeTime // microseconds
);
BOOL
ChangeEnvelope(
LPIMM_ENVELOPE pEnvelope
);
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializeFromProject(
CImmProject &project,
LPCSTR lpszEffectName,
CImmDevice* pDevice = NULL,
DWORD dwNoDownload = 0
);
virtual BOOL
Start(
DWORD dwIterations = IMM_EFFECT_DONT_CHANGE,
DWORD dwFlags = 0
#ifdef IFC_START_DELAY
, BOOL bAllowStartDelayEmulation = true
#endif
);
virtual BOOL
Stop();
//
// ------ PRIVATE INTERFACE ------
//
//
// CACHING
//
#ifdef IFC_EFFECT_CACHING
public:
friend class CEffectList;
friend class CImmCompoundEffect;
BOOL GetIsPlaying();
BOOL GetIsTriggered() const;
short GetPriority() const { return m_Priority; }
void SetPriority(short priority) { m_Priority = priority; }
virtual HRESULT Unload();
virtual void Reload();
//Althought public, this should only be used internally.
BOOL
set_outside_effect(
CImmEffect* pImmOutsideEffect
);
BOOL
get_is_inside_effect()
{ return m_bIsInsideEffect; }
public:
ECacheState m_CacheState; // effect's status in the cache
BOOL m_bInCurrentSuite; // is the effect in the currently loaded suite?
short m_Priority; // Priority within suite: higher number is higher priority
DWORD m_dwLastStarted; // when last started (0 = never) or when param change made on device
DWORD m_dwLastStopped; // when last stopped (0 = not since last start)
DWORD m_dwLastLoaded; // when last loaded with CImmEffectSuite::Load or Create
protected:
CImmDevice *m_pImmDevice; // ### Use instead of m_piImmDevice
#endif
//
// HELPERS
//
protected:
#ifdef IFC_START_DELAY
void EmulateStartDelay(
DWORD dwIterations,
DWORD dwNoDownload
);
#endif
#ifdef IFC_EFFECT_CACHING
public: // initalize needs to be called by CImmDevice
#endif
BOOL
initialize(
CImmDevice* pDevice,
DWORD dwNoDownload
);
#ifdef IFC_EFFECT_CACHING
protected:
#endif
HRESULT
set_parameters_on_device(
DWORD dwFlags
);
BOOL
set_name(
const char *lpszName
);
void
imm_to_DI_GUID(
GUID &guid
);
void
DI_to_imm_GUID(
GUID &guid
);
void
reset();
void
reset_effect_struct();
void
reset_device();
void
buffer_direction(
TCHAR** pData
);
void
buffer_long_param(
TCHAR** pData,
LPCSTR lpszKey,
long lDefault,
long lValue
);
void
buffer_dword_param(
TCHAR** pData,
LPCSTR lpszKey,
DWORD dwDefault,
DWORD dwValue
);
virtual int
buffer_ifr_data(
TCHAR* pData
);
virtual BOOL
get_ffe_data(
LPDIEFFECT pdiEffect
);
//
// INTERNAL DATA
//
protected:
IMM_EFFECT m_Effect;
DWORD m_dwaAxes[2];
LONG m_laDirections[2];
IMM_ENVELOPE m_Envelope;
GUID m_guidEffect;
BOOL m_bIsPlaying;
DWORD m_dwDeviceType;
LPIIMM_DEVICE m_piImmDevice; // Might also be holding LPDIRECTINPUTDEVICE2
LPIIMM_EFFECT m_piImmEffect;
DWORD m_cAxes; // Number of axes
DWORD m_dwNoDownload;
DWORD m_dwIterations;
char *m_lpszName; // Name of this effect primative
// Needed for co-ordinating events for Enclosures/Ellipes and the inside effects.
BOOL m_bIsInsideEffect;
CImmEffect* m_pOutsideEffect;
#ifdef IFC_START_DELAY
public:
// Prevents access to dangling pointer when this is deleted
// All relevent code may be removed when all hardware and drivers support start delay
CImmEffect **m_ppTimerRef; // pointer to pointer to this.
#endif
};
#endif // !defined(AFX_ImmEffect_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

View File

@@ -0,0 +1,103 @@
/**********************************************************************
Copyright (c) 1999 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmEffectSuite.h
PURPOSE: Caching of effects
STARTED: 6/16/99 Jeff Mallett
NOTES/REVISIONS:
**********************************************************************/
#if !defined(AFX_FEELEFFECTSUITE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_FEELEFFECTSUITE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#ifdef IFC_EFFECT_CACHING
class CImmDevice; //#include "ImmDevice.h"
class CImmEffect; //#include "ImmEffect.h"
typedef enum {
IMMCACHE_NOT_ON_DEVICE,
IMMCACHE_ON_DEVICE,
IMMCACHE_SWAPPED_OUT
} ECacheState;
//================================================================
// CEffectList, CEffectListElement
//================================================================
class DLLIFC CEffectListElement
{
public:
CEffectListElement() : m_pImmEffect(NULL), m_pNext(NULL) { }
CImmEffect *m_pImmEffect;
CEffectListElement *m_pNext;
};
class DLLIFC CEffectList
{
public:
CEffectList() : m_pFirstEffect(NULL) { }
~CEffectList();
BOOL AddEffect(CImmEffect *pImmEffect);
BOOL RemoveEffect(const CImmEffect *pImmEffect);
void ClearDevice(CImmDevice *pImmDevice);
CEffectListElement *m_pFirstEffect;
};
//================================================================
// CImmEffectSuite
//================================================================
class CImmEffectSuite
{
public:
CImmEffectSuite() : m_bCurrentSuite(false) { }
CEffectListElement *GetFirstEffect();
void AddEffect(CImmEffect *pImmEffect);
void RemoveEffect(CImmEffect *pImmEffect);
void SetPriorities(short priority);
BOOL m_bCurrentSuite; // Is the suite the "current suite"?
private:
CEffectList m_EffectList; // List of effects in suite
};
#endif // IFC_EFFECT_CACHING
#endif // !defined(AFX_FEELEFFECTSUITE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

295
code/ff/IFC/ImmEllipse.h Normal file
View File

@@ -0,0 +1,295 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmEllipse.h
PURPOSE: Base Ellipse Class for Immersion Foundation Classes
STARTED: 10/29/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
#define IMM_ELLIPSE_DEFAULT_STIFFNESS 5000
#define IMM_ELLIPSE_DEFAULT_SATURATION 10000
#define IMM_ELLIPSE_DEFAULT_WIDTH 10
#define IMM_ELLIPSE_HEIGHT_AUTO MAXDWORD
#define IMM_ELLIPSE_DEFAULT_HEIGHT IMM_ELLIPSE_HEIGHT_AUTO
#define IMM_ELLIPSE_WALL_WIDTH_AUTO MAXDWORD
#define IMM_ELLIPSE_DEFAULT_WALL_WIDTH IMM_ELLIPSE_WALL_WIDTH_AUTO
#define IMM_ELLIPSE_DEFAULT_STIFFNESS_MASK IMM_STIFF_ANYWALL
#define IMM_ELLIPSE_DEFAULT_CLIPPING_MASK IMM_CLIP_NONE
#define IMM_ELLIPSE_DEFAULT_CENTER_POINT IMM_EFFECT_MOUSE_POS_AT_START
//================================================================
// CImmEllipse
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmEllipse : public CImmEffect
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmEllipse();
// Destructor
virtual
~CImmEllipse();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_ELLIPSE; }
BOOL
ChangeParameters(
POINT pntCenter,
DWORD dwWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwHeight = IMM_EFFECT_DONT_CHANGE,
LONG lStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwWallThickness = IMM_EFFECT_DONT_CHANGE,
DWORD dwSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwStiffnessMask = IMM_EFFECT_DONT_CHANGE,
DWORD dwClippingMask = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParameters(
LPCRECT pRectOutside,
LONG lStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwWallThickness = IMM_EFFECT_DONT_CHANGE,
DWORD dwSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwStiffnessMask = IMM_EFFECT_DONT_CHANGE,
DWORD dwClippingMask = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
BOOL ChangeStiffness ( LONG lStiffness );
BOOL ChangeWallThickness( DWORD dwThickness );
BOOL ChangeSaturation ( DWORD dwSaturation );
BOOL ChangeStiffnessMask( DWORD dwStiffnessMask );
BOOL ChangeClippingMask ( DWORD dwClippingMask );
BOOL ChangeInsideEffect ( CImmEffect* pInsideEffect );
BOOL
ChangeRect(
LPCRECT pRect
);
BOOL
ChangeCenter(
POINT pntCenter
);
BOOL
ChangeCenter(
LONG x,
LONG y
);
BOOL GetStiffness ( LONG &lStiffness );
BOOL GetWallThickness( DWORD &dwThickness );
BOOL GetSaturation ( DWORD &dwSaturation );
BOOL GetStiffnessMask( DWORD &dwStiffnessMask );
BOOL GetClippingMask ( DWORD &dwClippingMask );
BOOL GetRect( RECT* pRect );
BOOL GetCenter( POINT &pntCenter );
BOOL GetCenter( LONG &x, LONG &y);
CImmEffect* GetInsideEffect();
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwWidth = IMM_ELLIPSE_DEFAULT_WIDTH,
DWORD dwHeight = IMM_ELLIPSE_DEFAULT_HEIGHT,
LONG lStiffness = IMM_ELLIPSE_DEFAULT_STIFFNESS,
DWORD dwWallWidth = IMM_ELLIPSE_DEFAULT_WALL_WIDTH,
DWORD dwSaturation = IMM_ELLIPSE_DEFAULT_SATURATION,
DWORD dwStiffnessMask = IMM_ELLIPSE_DEFAULT_STIFFNESS_MASK,
DWORD dwClippingMask = IMM_ELLIPSE_DEFAULT_CLIPPING_MASK,
POINT pntCenter = IMM_ELLIPSE_DEFAULT_CENTER_POINT,
CImmEffect* pInsideEffect = NULL,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwNoDownload = 0
);
BOOL
Initialize(
CImmDevice* pDevice,
LPCRECT pRectOutside,
LONG lStiffness = IMM_ELLIPSE_DEFAULT_STIFFNESS,
DWORD dwWallWidth = IMM_ELLIPSE_DEFAULT_WALL_WIDTH,
DWORD dwSaturation = IMM_ELLIPSE_DEFAULT_SATURATION,
DWORD dwStiffnessMask = IMM_ELLIPSE_DEFAULT_STIFFNESS_MASK,
DWORD dwClippingMask = IMM_ELLIPSE_DEFAULT_CLIPPING_MASK,
CImmEffect* pInsideEffect = NULL,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwNoDownload = 0
);
virtual BOOL
Start(
DWORD dwIterations = 1,
DWORD dwFlags = 0,
BOOL bAllowStartDelayEmulation = true
);
HRESULT Unload();
void Reload();
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
LPCRECT pRectOutside,
LONG lStiffness,
DWORD dwWallWidth,
DWORD dwSaturation,
DWORD dwStiffnessMask,
DWORD dwClippingMask,
CImmEffect* pInsideEffect,
LONG lAngle
);
DWORD
change_parameters(
LPCRECT prectBoundary,
LONG lStiffness,
DWORD dwWallThickness,
DWORD dwSaturation,
DWORD dwStiffnessMask,
DWORD dwClippingMask,
CImmEffect* pInsideEffect,
LONG lAngle
);
int
buffer_ifr_data(
TCHAR* pData
);
//
// INTERNAL DATA
//
protected:
IMM_ELLIPSE m_ellipse;
BOOL m_bUseMousePosAtStart;
// Needed for co-ordinating events for Enclosures/Ellipes and the inside effects.
CImmEffect* m_pInsideEffect;
};
//
// INLINES
//
inline BOOL
CImmEllipse::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Ellipse);
}
#endif // !defined(AFX_IMMELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

325
code/ff/IFC/ImmEnclosure.h Normal file
View File

@@ -0,0 +1,325 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmEnclosure.h
PURPOSE: Base Enclosure Class for Immersion Foundation Classes
STARTED: 10/29/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
#define IMM_ENCLOSURE_DEFAULT_STIFFNESS 5000
#define IMM_ENCLOSURE_DEFAULT_SATURATION 10000
#define IMM_ENCLOSURE_DEFAULT_WIDTH 10
#define IMM_ENCLOSURE_HEIGHT_AUTO MAXDWORD
#define IMM_ENCLOSURE_DEFAULT_HEIGHT IMM_ENCLOSURE_HEIGHT_AUTO
#define IMM_ENCLOSURE_WALL_WIDTH_AUTO MAXDWORD
#define IMM_ENCLOSURE_DEFAULT_WALL_WIDTH IMM_ENCLOSURE_WALL_WIDTH_AUTO
#define IMM_ENCLOSURE_DEFAULT_STIFFNESS_MASK IMM_STIFF_ANYWALL
#define IMM_ENCLOSURE_DEFAULT_CLIPPING_MASK IMM_CLIP_NONE
#define IMM_ENCLOSURE_DEFAULT_CENTER_POINT IMM_EFFECT_MOUSE_POS_AT_START
//================================================================
// CImmEnclosure
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmEnclosure : public CImmEffect
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmEnclosure();
// Destructor
virtual
~CImmEnclosure();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_ENCLOSURE; }
BOOL
ChangeParameters(
POINT pntCenter,
DWORD dwWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwHeight = IMM_EFFECT_DONT_CHANGE,
LONG lTopAndBottomWallStiffness = IMM_EFFECT_DONT_CHANGE,
LONG lLeftAndRightWallStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwTopAndBottomWallWallWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwLeftAndRightWallWallWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwTopAndBottomWallSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwLeftAndRightWallSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwStiffnessMask = IMM_EFFECT_DONT_CHANGE,
DWORD dwClippingMask = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParameters(
LPCRECT pRectOutside,
LONG lTopAndBottomWallStiffness = IMM_EFFECT_DONT_CHANGE,
LONG lLeftAndRightWallStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwTopAndBottomWallWallThickness = IMM_EFFECT_DONT_CHANGE,
DWORD dwLeftAndRightWallWallThickness = IMM_EFFECT_DONT_CHANGE,
DWORD dwTopAndBottomWallSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwLeftAndRightWallSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwStiffnessMask = IMM_EFFECT_DONT_CHANGE,
DWORD dwClippingMask = IMM_EFFECT_DONT_CHANGE,
CImmEffect* pInsideEffect = (CImmEffect*) IMM_EFFECT_DONT_CHANGE,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
BOOL ChangeTopAndBottomWallStiffness ( LONG lTopAndBottomWallStiffness );
BOOL ChangeLeftAndRightWallStiffness ( LONG lLeftAndRightWallStiffness );
BOOL ChangeTopAndBottomWallThickness ( DWORD dwTopAndBottomWallThickness );
BOOL ChangeLeftAndRightWallThickness ( DWORD dwLeftAndRightWallThickness );
BOOL ChangeTopAndBottomWallSaturation( DWORD dwTopAndBottomWallSaturation );
BOOL ChangeLeftAndRightWallSaturation( DWORD dwLeftAndRightWallSaturation );
BOOL ChangeStiffnessMask ( DWORD dwStiffnessMask );
BOOL ChangeClippingMask ( DWORD dwClippingMask );
BOOL ChangeInsideEffect ( CImmEffect* pInsideEffect );
BOOL
ChangeRect(
LPCRECT pRect
);
BOOL
ChangeCenter(
POINT pntCenter
);
BOOL
ChangeCenter(
LONG x,
LONG y
);
BOOL
ShowRect(
BOOL bRectOn
);
BOOL GetTopAndBottomWallStiffness ( LONG &lTopAndBottomWallStiffness );
BOOL GetLeftAndRightWallStiffness ( LONG &lLeftAndRightWallStiffness );
BOOL GetTopAndBottomWallThickness ( DWORD &dwTopAndBottomWallThickness );
BOOL GetLeftAndRightWallThickness ( DWORD &dwLeftAndRightWallThickness );
BOOL GetTopAndBottomWallSaturation ( DWORD &dwTopAndBottomWallSaturation );
BOOL GetLeftAndRightWallSaturation ( DWORD &dwLeftAndRightWallSaturation );
BOOL GetStiffnessMask ( DWORD &dwStiffnessMask );
BOOL GetClippingMask ( DWORD &dwClippingMask );
BOOL GetRect( RECT* pRect );
BOOL GetCenter( POINT &pntCenter );
BOOL GetCenter( LONG &x, LONG &y);
CImmEffect* GetInsideEffect ();
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwWidth = IMM_ENCLOSURE_DEFAULT_WIDTH,
DWORD dwHeight = IMM_ENCLOSURE_DEFAULT_HEIGHT,
LONG lTopAndBottomWallStiffness = IMM_ENCLOSURE_DEFAULT_STIFFNESS,
LONG lLeftAndRightWallStiffness = IMM_ENCLOSURE_DEFAULT_STIFFNESS,
DWORD dwTopAndBottomWallWallWidth = IMM_ENCLOSURE_DEFAULT_WALL_WIDTH,
DWORD dwLeftAndRightWallWallWidth = IMM_ENCLOSURE_DEFAULT_WALL_WIDTH,
DWORD dwTopAndBottomWallSaturation = IMM_ENCLOSURE_DEFAULT_SATURATION,
DWORD dwLeftAndRightWallSaturation = IMM_ENCLOSURE_DEFAULT_SATURATION,
DWORD dwStiffnessMask = IMM_ENCLOSURE_DEFAULT_STIFFNESS_MASK,
DWORD dwClippingMask = IMM_ENCLOSURE_DEFAULT_CLIPPING_MASK,
POINT pntCenter = IMM_ENCLOSURE_DEFAULT_CENTER_POINT,
CImmEffect* pInsideEffect = NULL,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwNoDownload = 0
);
BOOL
Initialize(
CImmDevice* pDevice,
LPCRECT pRectOutside,
LONG lTopAndBottomWallStiffness = IMM_ENCLOSURE_DEFAULT_STIFFNESS,
LONG lLeftAndRightWallStiffness = IMM_ENCLOSURE_DEFAULT_STIFFNESS,
DWORD dwTopAndBottomWallWallWidth = IMM_ENCLOSURE_DEFAULT_WALL_WIDTH,
DWORD dwLeftAndRightWallWallWidth = IMM_ENCLOSURE_DEFAULT_WALL_WIDTH,
DWORD dwTopAndBottomWallSaturation = IMM_ENCLOSURE_DEFAULT_SATURATION,
DWORD dwLeftAndRightWallSaturation = IMM_ENCLOSURE_DEFAULT_SATURATION,
DWORD dwStiffnessMask = IMM_ENCLOSURE_DEFAULT_STIFFNESS_MASK,
DWORD dwClippingMask = IMM_ENCLOSURE_DEFAULT_CLIPPING_MASK,
CImmEffect* pInsideEffect = NULL,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwNoDownload = 0
);
virtual BOOL
Start(
DWORD dwIterations = 1,
DWORD dwFlags = 0,
BOOL bAllowStartDelayEmulation = true
);
virtual BOOL
Stop();
HRESULT Unload();
void Reload();
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
LPCRECT pRectOutside,
LONG lTopAndBottomWallStiffness,
LONG lLeftAndRightWallStiffness,
DWORD dwTopAndBottomWallWallWidth,
DWORD dwLeftAndRightWallWallWidth,
DWORD dwTopAndBottomWallSaturation,
DWORD dwLeftAndRightWallSaturation,
DWORD dwStiffnessMask,
DWORD dwClippingMask,
CImmEffect* pInsideEffect,
LONG lAngle
);
DWORD
change_parameters(
LPCRECT prectBoundary,
LONG lTopAndBottomWallStiffness,
LONG lLeftAndRightWallStiffness,
DWORD dwTopAndBottomWallThickness,
DWORD dwLeftAndRightWallThickness,
DWORD dwTopAndBottomWallSaturation,
DWORD dwLeftAndRightWallSaturation,
DWORD dwStiffnessMask,
DWORD dwClippingMask,
CImmEffect* pInsideEffect,
LONG lAngle
);
int
buffer_ifr_data(
TCHAR* pData
);
//
// INTERNAL DATA
//
protected:
IMM_ENCLOSURE m_enclosure;
BOOL m_bUseMousePosAtStart;
// Needed for co-ordinating events for Enclosures/Ellipes and the inside effects.
CImmEffect* m_pInsideEffect;
};
//
// INLINES
//
inline BOOL
CImmEnclosure::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Enclosure);
}
#endif // !defined(AFX_IMMENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

176
code/ff/IFC/ImmFriction.h Normal file
View File

@@ -0,0 +1,176 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmFriction.h
PURPOSE: Immersion Foundation Classes Friction Effect
STARTED: Dec.29.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_ImmFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_ImmFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmCondition.h"
//================================================================
// Constants
//================================================================
#define IMM_FRICTION_DEFAULT_COEFFICIENT 2500
#define IMM_FRICTION_DEFAULT_MIN_VELOCITY 0
//================================================================
// CImmFriction
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmFriction : public CImmCondition
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmFriction();
// Destructor
virtual
~CImmFriction();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
BOOL
ChangeParameters(
DWORD dwCoefficient,
DWORD dwMinVelocity = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParametersPolar(
DWORD dwCoefficient,
DWORD dwMinVelocity,
LONG lAngle
);
BOOL ChangeMinVelocityX( DWORD dwMinVelocity );
BOOL ChangeMinVelocityY( DWORD dwMinVelocity );
//For setting both axes to the same value
BOOL ChangeMinVelocity( DWORD dwMinVelocity );
BOOL GetMinVelocityX( DWORD &dwMinVelocity );
BOOL GetMinVelocityY( DWORD &dwMinVelocity );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwCoefficient = IMM_FRICTION_DEFAULT_COEFFICIENT,
DWORD dwMinVelocity = IMM_FRICTION_DEFAULT_MIN_VELOCITY,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
DWORD dwCoefficient,
DWORD dwMinVelocity,
LONG lAngle,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
//
// INLINES
//
inline BOOL
CImmFriction::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Friction);
}
#endif // !defined(AFX_ImmFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

179
code/ff/IFC/ImmGrid.h Normal file
View File

@@ -0,0 +1,179 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmGrid.h
PURPOSE: Immersion Foundation Classes Grid Effect
STARTED: Dec.11.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.02.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmCondition.h"
//================================================================
// Constants
//================================================================
#define IMM_GRID_DEFAULT_HORIZ_OFFSET 0
#define IMM_GRID_DEFAULT_VERT_OFFSET 0
#define IMM_GRID_DEFAULT_HORIZ_SPACING 100
#define IMM_GRID_DEFAULT_VERT_SPACING 100
#define IMM_GRID_DEFAULT_NODE_STRENGTH 5000
#define IMM_GRID_DEFAULT_NODE_SATURATION 10000
//================================================================
// CImmGrid
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmGrid : public CImmCondition
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmGrid();
// Destructor
virtual
~CImmGrid();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
BOOL
ChangeParameters(
DWORD dwHorizSpacing,
DWORD dwVertSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lHorizNodeStrength = IMM_EFFECT_DONT_CHANGE,
LONG lVertNodeStrength = IMM_EFFECT_DONT_CHANGE,
LONG lHorizOffset = IMM_EFFECT_DONT_CHANGE,
LONG lVertOffset = IMM_EFFECT_DONT_CHANGE,
DWORD dwHorizNodeSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwVertNodeSaturation = IMM_EFFECT_DONT_CHANGE
);
BOOL ChangeHSpacing( DWORD dwHorizSpacing );
BOOL ChangeVSpacing( DWORD dwVertSpacing );
BOOL ChangeHNodeStrength( LONG lHorizNodeStrength );
BOOL ChangeVNodeStrength( LONG lVertNodeStrength );
BOOL ChangeOffset( POINT pntOffset );
BOOL ChangeHNodeSaturation( DWORD dwHorizNodeSaturation );
BOOL ChangeVNodeSaturation( DWORD dwVertNodeSaturation );
BOOL GetHSpacing( DWORD &dwHorizSpacing );
BOOL GetVSpacing( DWORD &dwVertSpacing );
BOOL GetHNodeStrength( LONG &lHorizNodeStrength );
BOOL GetVNodeStrength( LONG &lVertNodeStrength );
BOOL GetOffset( POINT &pntOffset );
BOOL GetHNodeSaturation( DWORD &dwHorizNodeSaturation );
BOOL GetVNodeSaturation( DWORD &dwVertNodeSaturation );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwHorizSpacing = IMM_GRID_DEFAULT_HORIZ_SPACING,
DWORD dwVertSpacing = IMM_GRID_DEFAULT_VERT_SPACING,
LONG lHorizNodeStrength = IMM_GRID_DEFAULT_NODE_STRENGTH,
LONG lVertNodeStrength = IMM_GRID_DEFAULT_NODE_STRENGTH,
DWORD dwHorizOffset = IMM_GRID_DEFAULT_HORIZ_OFFSET,
DWORD dwVertOffset = IMM_GRID_DEFAULT_VERT_OFFSET,
DWORD dwHorizNodeSaturation = IMM_GRID_DEFAULT_NODE_SATURATION,
DWORD dwVertNodeSaturation = IMM_GRID_DEFAULT_NODE_SATURATION,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
//
// INLINES
//
inline BOOL
CImmGrid::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Grid);
}
#endif // !defined(AFX_IMMGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

308
code/ff/IFC/ImmIFR.h Normal file
View File

@@ -0,0 +1,308 @@
/**********************************************************************
Copyright (c) 1999 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: FEELitIFR.h
PURPOSE: Input/Output for IFR Files, FEELit version
STARTED:
NOTES/REVISIONS:
**********************************************************************/
#if !defined( _IMMIFR_H_)
#define _IMMIFR_H_
#ifndef __FEELITAPI_INCLUDED__
#error include 'dinput.h' before including this file for structures.
#endif /* !__DINPUT_INCLUDED__ */
#define IFRAPI __stdcall
#if !defined(_IFCDLL_)
#define DLLAPI __declspec(dllimport)
#else
#define DLLAPI __declspec(dllexport)
#endif
#if defined __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
** CONSTANTS
*/
/*
** RT_IMMERSION - Resource type for IFR projects stored as resources.
** This is the resource type looked for by IFLoadProjectResource().
*/
#define RT_IMMERSION ((LPCSTR)"IMMERSION")
/*
** TYPES/STRUCTURES
*/
/*
** HIFRPROJECT - used to identify a loaded project as a whole.
** individual objects within a project are uniquely referenced by name.
** Created by the IFLoadProject*() functions and released by IFReleaseProject().
*/
typedef LPVOID HIFRPROJECT;
/*
** IFREffect - contains the information needed to create a DI effect
** using IDirectInputEffect::CreateEffect(). An array of pointers to these
** structures is allocated and returned by IFCreateEffectStructs().
*/
typedef struct {
GUID guid;
DWORD dwIterations;
char *effectName;
LPIMM_EFFECT lpDIEffect;
} IFREffect;
/*
** FUNCTION DECLARATIONS
*/
/*
** IFLoadProjectResource() - Load a project from a resource.
** hRsrcModule - handle of the module containing the project definition resource.
** pRsrcName - name or MAKEINTRESOURCE(id) identifier of resource to load.
** pDevice - device for which the project is being loaded. If NULL,
** effects will be created generically, and IFCreateEffects() will fail.
** Returns an identifier for the loaded project, or NULL if unsuccessful.
*/
DLLAPI
HIFRPROJECT
IFRAPI
IFRLoadProjectResource(
HMODULE hRsrcModule,
LPCSTR pRsrcName,
LPIIMM_DEVICE pDevice );
/*
** IFLoadProjectPointer() - Load a project from a pointer.
** pProject - points to a project definition.
** pDevice - device for which the project is being loaded. If NULL,
** effects will be created generically, and IFCreateEffects() will fail.
** Returns an identifier for the loaded project, or NULL if unsuccessful.
*/
DLLAPI
HIFRPROJECT
IFRAPI
IFRLoadProjectPointer(
LPVOID pProject,
LPIIMM_DEVICE pDevice );
/*
** IFLoadProjectFile() - Load a project from a file.
** pProjectFileName - points to a project file name.
** pDevice - device for which the project is being loaded. If NULL,
** effects will be created generically, and IFCreateEffects() will fail.
** Returns an identifier for the loaded project, or NULL if unsuccessful.
*/
DLLAPI
HIFRPROJECT
IFRAPI
IFRLoadProjectFile(
LPCSTR pProjectFileName,
LPIIMM_DEVICE pDevice );
/*
** IFRLoadProjectFromMemory() - Load a project from memory.
**
** In cases where a file or resource is readily accessible, it may
** be necessary to pass IFR formated information through memory.
**
** pProjectDef - memory addres that contains information from an IFR file.
** pDevice - device for which the project is being loaded. If NULL,
** effects will be created generically, and IFRCreateEffects() will fail.
** Returns an identifier for the loaded project, or NULL if unsuccessful.
*/
DLLAPI
HIFRPROJECT
IFRAPI
IFRLoadProjectFromMemory(
LPVOID pProjectDef,
LPIIMM_DEVICE pDevice );
/*
** IFLoadProjectObjectPointer() - Load a project from a pointer to a single
** object definition (usually used only by the editor).
** pObject - points to an object definition.
** pDevice - device for which the project is being loaded. If NULL,
** effects will be created generically, and IFCreateEffects() will fail.
** Returns an identifier for the loaded project, or NULL if unsuccessful.
*/
DLLAPI
HIFRPROJECT
IFRAPI
IFRLoadProjectObjectPointer(
LPVOID pObject,
LPIIMM_DEVICE pDevice );
/*
** IFReleaseProject() - Release a loaded project.
** hProject - identifies the project to be released.
** Returns TRUE if the project is released, FALSE if it is an invalid project.
*/
DLLAPI
BOOL
IFRAPI
IFRReleaseProject(
HIFRPROJECT hProject );
/*
** IFCreateEffectStructs() - Create IFREffects for a named effect.
** hProject - identifies the project containing the object.
** pObjectName - name of the object for which to create structures.
** pNumEffects - if not NULL will be set to a count of the IFREffect
** structures in the array (not including the terminating NULL pointer.)
** Returns a pointer to the allocated array of pointers to IFREffect
** structures. The array is terminated with a NULL pointer. If the
** function fails, a NULL pointer is returned.
*/
DLLAPI
IFREffect **
IFRAPI
IFRCreateEffectStructs(
HIFRPROJECT hProject,
LPCSTR pObjectName,
int *pNumEffects );
DLLAPI
IFREffect **
IFRAPI
IFRCreateEffectStructsByIndex(
HIFRPROJECT hProject,
int nObjectIndex,
int *pNumEffects );
DLLAPI
int
IFRAPI
IFRGetNumEffects(
HIFRPROJECT hProject
);
DLLAPI
LPCSTR
IFRAPI
IFRGetObjectNameByIndex(
HIFRPROJECT hProject,
int nObjectIndex );
DLLAPI
LPCSTR
IFRAPI
IFRGetObjectSoundPath(
HIFRPROJECT hProject,
LPCSTR pObjectName );
DLLAPI
DWORD
IFRAPI
IFRGetObjectType(
HIFRPROJECT hProject,
LPCSTR pObjectName );
DLLAPI
DWORD
IFRAPI
IFRGetObjectTypeByIndex(
HIFRPROJECT hProject,
int nObjectIndex );
DLLAPI
LPCSTR
IFRAPI
IFRGetObjectNameByGUID(
HIFRPROJECT hProject,
GUID *pGUID );
DLLAPI
GUID
IFRAPI
IFRGetObjectID(
HIFRPROJECT hProject,
LPCSTR pObjectName);
DLLAPI
GUID*
IFRAPI
IFRGetContainedObjIDs(
HIFRPROJECT hProject,
LPCSTR pCompoundObjName);
/*
** IFReleaseEffectStructs() - Release an array of IFREffects.
** hProject - identifies the project for which the effects were created.
** pEffects - points to the array of IFREffect pointers to be released.
** Returns TRUE if the array is released, FALSE if it is an invalid array.
*/
DLLAPI
BOOL
IFRAPI
IFRReleaseEffectStructs(
HIFRPROJECT hProject,
IFREffect **pEffects );
/*
** IFCreateEffects() - Creates the DirectInput effects using
** IDirectInput::CreateEffect().
** hProject - identifies the project containing the object.
** pObjectName - name of the object for which to create effects.
** pNumEffects - if not NULL will be set to a count of the IDirectInputEffect
** pointers in the array (not including the terminating NULL pointer.)
** Returns a pointer to the allocated array of pointers to IDirectInputEffects.
** The array is terminated with a NULL pointer. If the function fails,
** a NULL pointer is returned.
*/
DLLAPI
LPIIMM_EFFECT *
IFRAPI
IFRCreateEffects(
HIFRPROJECT hProject,
LPCSTR pObjectName,
int *pNumEffects );
/*
** IFReleaseEffects() - Releases an array of IDirectInputEffect structures.
** hProject - identifies the project for which the effects were created.
** pEffects - points to the array if IDirectInputEffect pointers to be released.
** Returns TRUE if the array is released, FALSE if it is an invalid array.
*/
DLLAPI
BOOL
IFRAPI
IFRReleaseEffects(
HIFRPROJECT hProject,
LPIIMM_EFFECT *pEffects );
#if defined __cplusplus
}
#endif /* __cplusplus */
#endif /* !IMMIFR_h */

183
code/ff/IFC/ImmInertia.h Normal file
View File

@@ -0,0 +1,183 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmInertia.h
PURPOSE: Immersion Foundation Classes Inertia Effect
STARTED: Dec.29.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmCondition.h"
//================================================================
// Constants
//================================================================
#define IMM_INERTIA_DEFAULT_COEFFICIENT 2500
#define IMM_INERTIA_DEFAULT_SATURATION 10000
#define IMM_INERTIA_DEFAULT_MIN_ACCELERATION 0
//================================================================
// CImmInertia
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmInertia : public CImmCondition
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmInertia();
// Destructor
virtual
~CImmInertia();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
BOOL
ChangeParameters(
DWORD dwCoefficient,
DWORD dwSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwMinAcceleration = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParametersPolar(
DWORD dwCoefficient,
DWORD dwSaturation,
DWORD dwMinAcceleration,
LONG lAngle
);
BOOL ChangeMinAccelerationX( DWORD dwMinAcceleration );
BOOL ChangeMinAccelerationY( DWORD dwMinAcceleration );
BOOL ChangeMinAcceleration( DWORD dwMinAcceleration );
BOOL GetMinAccelerationX( DWORD &dwMinAcceleration );
BOOL GetMinAccelerationY( DWORD &dwMinAcceleration );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwCoefficient = IMM_INERTIA_DEFAULT_COEFFICIENT,
DWORD dwSaturation = IMM_INERTIA_DEFAULT_SATURATION,
DWORD dwMinAcceleration = IMM_INERTIA_DEFAULT_MIN_ACCELERATION,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
DWORD dwCoefficient,
DWORD dwSaturation,
DWORD dwMinAcceleration,
LONG lAngle,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
//
// INLINES
//
inline BOOL
CImmInertia::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Inertia);
}
#endif // !defined(AFX_IMMInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

164
code/ff/IFC/ImmMouse.h Normal file
View File

@@ -0,0 +1,164 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmMouse.h
PURPOSE: Abstraction of Feelit mouse device
STARTED: 10/10/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#ifndef ImmMouse_h
#define ImmMouse_h
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmDevice.h"
//================================================================
// CImmMouse
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmMouse : public CImmDevice
{
//
// CONSTRUCTOR/DESCTRUCTOR
//
public:
// Constructor
CImmMouse();
// Destructor
virtual
~CImmMouse();
//
// ATTRIBUTES
//
public:
virtual LPIIMM_API
GetAPI()
{ return m_piApi; }
virtual LPIIMM_DEVICE
GetDevice()
{ return m_piDevice; }
virtual DWORD GetProductType();
virtual BOOL GetDriverVersion(
DWORD &dwFFDriverVersion,
DWORD &dwFirmwareRevision,
DWORD &dwHardwareRevision);
virtual int GetProductName(LPTSTR lpszProductName, int nMaxCount);
virtual int GetProductGUIDString(LPTSTR lpszGUID, int nMaxCount);
virtual GUID GetProductGUID();
BOOL
HaveImmMouse()
{ return m_piDevice != NULL; }
//
// OPERATIONS
//
public:
BOOL
Initialize(
HANDLE hinstApp,
HANDLE hwndApp,
DWORD dwCooperativeFlag = IMM_COOPLEVEL_FOREGROUND,
BOOL bEnumerate = TRUE
);
virtual BOOL
ChangeScreenResolution(
BOOL bAutoSet,
DWORD dwXScreenSize = 0,
DWORD dwYScreenSize = 0
);
// Another syntax for SwitchToAbsoluteMode.
// The default is Absolute mode. Call only to switch to Relative mode or
// to switch back to Absolute mode.
virtual BOOL
SwitchToAbsoluteMode(
BOOL bAbsMode
);
virtual BOOL
GetCurrentPosition( long &lXPos, long &lYPos );
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
virtual void
reset();
virtual BOOL
prepare_device();
friend class CImmDevices;
static BOOL CALLBACK
devices_enum_proc(
LPIMM_DEVICEINSTANCE pImmDevInst,
LPVOID pv
);
//
// INTERNAL DATA
//
protected:
LPIIMM_API m_piApi;
LPIIMM_DEVICE m_piDevice;
};
#endif // ImmMouse_h

259
code/ff/IFC/ImmPeriodic.h Normal file
View File

@@ -0,0 +1,259 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmPeriodic.h
PURPOSE: Base Periodic Class for Immersion Foundation Classes
STARTED: 11/03/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
#define IMM_PERIODIC_DEFAULT_DURATION 1000 // Milliseconds
#define IMM_PERIODIC_DEFAULT_MAGNITUDE 5000
#define IMM_PERIODIC_DEFAULT_PERIOD 100 // Milliseconds
#define IMM_PERIODIC_DEFAULT_OFFSET 0
#define IMM_PERIODIC_DEFAULT_PHASE 0 // Degrees
#define IMM_PERIODIC_DEFAULT_DIRECTION_X 1 // Pixels
#define IMM_PERIODIC_DEFAULT_DIRECTION_Y 0 // Pixels
#define IMM_PERIODIC_DEFAULT_ANGLE 9000 // 100ths of degrees
//================================================================
// CImmPeriodic
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmPeriodic : public CImmEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructors
// You may use this form if you will immediately initialize it
// from an IFR file...
CImmPeriodic();
// Otherwise use this form...
CImmPeriodic(
const GUID& rguidEffect
);
// Destructor
virtual
~CImmPeriodic();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_PERIODIC; }
BOOL
ChangeParameters(
DWORD dwMagnitude,
DWORD dwPeriod = IMM_EFFECT_DONT_CHANGE,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE,
LONG lOffset = IMM_EFFECT_DONT_CHANGE,
DWORD dwPhase = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL
ChangeParametersPolar(
DWORD dwMagnitude,
DWORD dwPeriod = IMM_EFFECT_DONT_CHANGE,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lAngle = IMM_EFFECT_DONT_CHANGE,
LONG lOffset = IMM_EFFECT_DONT_CHANGE,
DWORD dwPhase = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL ChangeMagnitude( DWORD dwMagnitude );
BOOL ChangePeriod( DWORD dwPeriod );
BOOL ChangeOffset( LONG lOffset );
BOOL ChangePhase( DWORD dwPhase );
BOOL GetMagnitude( DWORD &dwMagnitude );
BOOL GetPeriod( DWORD &dwPeriod );
BOOL GetOffset( LONG &lOffset );
BOOL GetPhase( DWORD &dwPhase );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
virtual BOOL
Initialize(
CImmDevice* pDevice,
DWORD dwMagnitude = IMM_PERIODIC_DEFAULT_MAGNITUDE,
DWORD dwPeriod = IMM_PERIODIC_DEFAULT_PERIOD,
DWORD dwDuration = IMM_PERIODIC_DEFAULT_DURATION,
LONG lDirectionX = IMM_PERIODIC_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_PERIODIC_DEFAULT_DIRECTION_Y,
LONG lOffset = IMM_PERIODIC_DEFAULT_OFFSET,
DWORD dwPhase = IMM_PERIODIC_DEFAULT_PHASE,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
DWORD dwMagnitude = IMM_PERIODIC_DEFAULT_MAGNITUDE,
DWORD dwPeriod = IMM_PERIODIC_DEFAULT_PERIOD,
DWORD dwDuration = IMM_PERIODIC_DEFAULT_DURATION,
LONG lAngle = IMM_PERIODIC_DEFAULT_ANGLE,
LONG lOffset = IMM_PERIODIC_DEFAULT_OFFSET,
DWORD dwPhase = IMM_PERIODIC_DEFAULT_PHASE,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
DWORD dwMagnitude,
DWORD dwPeriod,
LONG lOffset,
DWORD dwPhase,
LPIMM_ENVELOPE pEnvelope
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
DWORD dwMagnitude,
DWORD dwPeriod,
LONG lOffset,
DWORD dwPhase,
LPIMM_ENVELOPE pEnvelope
);
int
buffer_ifr_data(
TCHAR* pData
);
BOOL
get_ffe_data(
LPDIEFFECT pdiEffect
);
//
// INTERNAL DATA
//
protected:
IMM_PERIODIC m_Periodic;
};
//
// INLINES
//
inline BOOL
CImmPeriodic::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Sine) ||
IsEqualGUID(guid, GUID_Imm_Square) ||
IsEqualGUID(guid, GUID_Imm_Triangle) ||
IsEqualGUID(guid, GUID_Imm_SawtoothUp) ||
IsEqualGUID(guid, GUID_Imm_SawtoothDown);
}
#endif // !defined(AFX_IMMPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

392
code/ff/IFC/ImmProjects.h Normal file
View File

@@ -0,0 +1,392 @@
/**********************************************************************
Copyright (c) 1999 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmProjects.h
PURPOSE: CImmProject
Manages a set of forces in a project.
There will be a project for each opened IFR file.
CImmProjects
Manages a set of projects
STARTED: 2/22/99 by Jeff Mallett
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#ifndef __IMM_PROJECTS_H
#define __IMM_PROJECTS_H
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "IFCErrors.h"
#include "ImmBaseTypes.h"
#include "ImmDevice.h"
#include "ImmCompoundEffect.h"
class CImmProjects;
//================================================================
// CImmProject
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmProject
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
CImmProject();
~CImmProject();
void
Close();
//
// ATTRIBUTES
//
public:
CImmDevice*
GetDevice() const
{ return m_pDevice; }
BOOL
GetIsOpen() const
{ return m_hProj != NULL; }
CImmCompoundEffect *
GetCreatedEffect(
LPCSTR lpszEffectName
);
CImmCompoundEffect *
GetCreatedEffect(
int nIndex
);
int
GetNumEffectsFromIFR();
LPCSTR
GetEffectNameFromIFRbyIndex(
int nEffectIndex
);
LPCSTR
GetEffectSoundPathFromIFR(
LPCSTR lpszEffectName
);
DWORD
GetEffectType(
LPCSTR lpszEffectName
);
DWORD
GetEffectTypeFromIFR(
LPCSTR lpszEffectName
);
DWORD
GetEffectTypeFromIFR(
int nEffectIndex
);
int
GetNumCreatedEffects()
{ return m_nCreatedEffects;}
//
// OPERATIONS
//
public:
BOOL
Start(
LPCSTR lpszEffectName = NULL,
DWORD dwIterations = IMM_EFFECT_DONT_CHANGE,
DWORD dwFlags = 0,
CImmDevice* pDevice = NULL
);
BOOL
Stop(
LPCSTR lpszEffectName = NULL
);
BOOL
OpenFile(
LPCSTR lpszFilePath,
CImmDevice *pDevice
);
BOOL
LoadProjectFromResource(
HMODULE hRsrcModule,
LPCSTR pRsrcName,
CImmDevice *pDevice
);
BOOL
LoadProjectFromMemory(
LPVOID pProjectDef,
CImmDevice *pDevice
);
BOOL
LoadProjectObjectPointer(
BYTE *pMem,
CImmDevice *pDevice
);
BOOL
WriteToFile(
LPCSTR lpszFilename
);
CImmCompoundEffect *
CreateEffect(
LPCSTR lpszEffectName,
CImmDevice* pDevice = NULL,
DWORD dwNoDownload = 0
);
CImmCompoundEffect *
CreateEffectByIndex(
int nEffectIndex,
CImmDevice* pDevice = NULL,
DWORD dwNoDownload = 0
);
CImmCompoundEffect *
AddEffect(
LPCSTR lpszEffectName,
GENERIC_EFFECT_PTR pObject
);
#if (IFC_VERSION >= 0x0101)
void
DestroyEffect(
CImmCompoundEffect *pCompoundEffect
);
#endif
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
void
set_next(
CImmProject *pNext
)
{ m_pNext = pNext; }
CImmProject *
get_next() const
{ return m_pNext; }
void
append_effect_to_list(
CImmCompoundEffect* pEffect
);
#if (IFC_VERSION >= 0x0101)
BOOL
remove_effect_from_list(
CImmCompoundEffect* pEffect
);
#endif
IFREffect **
create_effect_structs(
LPCSTR lpszEffectName,
int &nEff
);
IFREffect **
create_effect_structs_by_index(
int nEffectIndex,
int &nEff
);
BOOL
release_effect_structs(
IFREffect **hEffects
);
//
// FRIENDS
//
public:
friend BOOL
CImmEffect::InitializeFromProject(
CImmProject &project,
LPCSTR lpszEffectName,
CImmDevice* pDevice, /* = NULL */
DWORD dwNoDownload // = 0
);
#ifdef PROTECT_AGAINST_DELETION
friend CImmCompoundEffect::~CImmCompoundEffect();
#endif
friend class CImmProjects;
//
// INTERNAL DATA
//
protected:
HIFRPROJECT m_hProj;
DWORD m_dwProjectFileType;
CImmCompoundEffect* m_pCreatedEffects;
CImmDevice* m_pDevice;
LPDIRECTINPUT m_piDI7;
LPDIRECTINPUTDEVICE2 m_piDIDevice7;
TCHAR m_szProjectFileName[MAX_PATH];
int m_nCreatedEffects;
private:
CImmProject* m_pNext;
};
//================================================================
// CImmProjects
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmProjects
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
CImmProjects() : m_pProjects(NULL) { }
~CImmProjects();
void
Close();
//
// ATTRIBUTES
//
public:
CImmProject *
GetProject(
int index = 0
);
//
// OPERATIONS
//
public:
BOOL
Stop();
long
OpenFile(
LPCSTR lpszFilePath,
CImmDevice *pDevice
);
long
LoadProjectFromResource(
HMODULE hRsrcModule,
LPCSTR pRsrcName,
CImmDevice *pDevice
);
long
LoadProjectFromMemory(
LPVOID pProjectDef,
CImmDevice *pDevice
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
CImmProject *m_pProjects;
};
#endif // __IMM_PROJECTS_H

225
code/ff/IFC/ImmRamp.h Normal file
View File

@@ -0,0 +1,225 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmRamp.h
PURPOSE: Base Ramp Force Class for Immersion Foundation Classes
STARTED: 12/11/97
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
11/15/99 sdr (Steve Rank): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
#define IMM_RAMP_DEFAULT_DURATION 1000 // Milliseconds
#define IMM_RAMP_DEFAULT_MAGNITUDE_START 0
#define IMM_RAMP_DEFAULT_MAGNITUDE_END 10000
//================================================================
// CImmRamp
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmRamp : public CImmEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmRamp();
// Destructor
virtual
~CImmRamp();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_RAMPFORCE; }
BOOL
ChangeParameters(
LONG lDirectionX,
LONG lDirectionY,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lMagStart = IMM_EFFECT_DONT_CHANGE,
LONG lMagEnd = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL
ChangeParametersPolar(
LONG lAngle,
DWORD dwDuration = IMM_EFFECT_DONT_CHANGE,
LONG lMagStart = IMM_EFFECT_DONT_CHANGE,
LONG lMagEnd = IMM_EFFECT_DONT_CHANGE,
LPIMM_ENVELOPE pEnvelope = (LPIMM_ENVELOPE) IMM_EFFECT_DONT_CHANGE_PTR
);
BOOL ChangeStartMagnitude( LONG lMagStart );
BOOL ChangeEndMagnitude( LONG lMagEnd );
BOOL GetStartMagnitude( LONG &lMagStart );
BOOL GetEndMagnitude( LONG &lMagEnd );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwFlags = 0
);
virtual BOOL
Initialize(
CImmDevice* pDevice,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwDuration = IMM_RAMP_DEFAULT_DURATION,
LONG lMagStart = IMM_RAMP_DEFAULT_MAGNITUDE_START,
LONG lMagEnd = IMM_RAMP_DEFAULT_MAGNITUDE_END,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwFlags = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwDuration = IMM_RAMP_DEFAULT_DURATION,
LONG lMagStart = IMM_RAMP_DEFAULT_MAGNITUDE_START,
LONG lMagEnd = IMM_RAMP_DEFAULT_MAGNITUDE_END,
LPIMM_ENVELOPE pEnvelope = NULL,
DWORD dwFlags = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
LONG lMagStart,
LONG lMagEnd,
LPIMM_ENVELOPE pEnvelope
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
DWORD dwDuration,
LONG lMagStart,
LONG lMagEnd,
LPIMM_ENVELOPE pEnvelope
);
int
buffer_ifr_data(
TCHAR* pData
);
BOOL
get_ffe_data(
LPDIEFFECT pdiEffect
);
//
// INTERNAL DATA
//
protected:
IMM_RAMPFORCE m_RampForce;
};
//
// INLINES
//
inline BOOL
CImmRamp::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_RampForce);
}
#endif // !defined(AFX_IMMRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

183
code/ff/IFC/ImmSpring.h Normal file
View File

@@ -0,0 +1,183 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmSpring.h
PURPOSE: Immersion Foundation Classes Spring Effect
STARTED: Oct.10.97
NOTES/REVISIONS:
Mar.02.99 jrm (Jeff Mallett): Force-->Feel renaming
Mar.02.99 jrm: Added GetIsCompatibleGUID
Mar.15.99 jrm: __declspec(dllimport/dllexport) the whole class
Nov.15.99 efw (Evan Wies): Converted to IFC
**********************************************************************/
#if !defined(AFX_IMMSpring_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_IMMSpring_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmCondition.h"
//================================================================
// Constants
//================================================================
#define IMM_SPRING_DEFAULT_STIFFNESS 2500
#define IMM_SPRING_DEFAULT_SATURATION 10000
#define IMM_SPRING_DEFAULT_DEADBAND 100
#define IMM_SPRING_DEFAULT_CENTER_POINT IMM_EFFECT_MOUSE_POS_AT_START
#define IMM_SPRING_DEFAULT_DIRECTION_X 1
#define IMM_SPRING_DEFAULT_DIRECTION_Y 0
#define IMM_SPRING_DEFAULT_ANGLE 0
//================================================================
// CImmSpring
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmSpring : public CImmCondition
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmSpring();
// Destructor
virtual
~CImmSpring();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
BOOL
ChangeParameters(
POINT pntCenter,
LONG lStiffness = IMM_EFFECT_DONT_CHANGE,
DWORD dwSaturation = IMM_EFFECT_DONT_CHANGE,
DWORD dwDeadband = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeParametersPolar(
POINT pntCenter,
LONG lStiffness,
DWORD dwSaturation,
DWORD dwDeadband,
LONG lAngle
);
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
LONG lStiffness = IMM_SPRING_DEFAULT_STIFFNESS,
DWORD dwSaturation = IMM_SPRING_DEFAULT_SATURATION,
DWORD dwDeadband = IMM_SPRING_DEFAULT_DEADBAND,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
POINT pntCenter = IMM_SPRING_DEFAULT_CENTER_POINT,
LONG lDirectionX = IMM_SPRING_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_SPRING_DEFAULT_DIRECTION_Y,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
virtual BOOL
InitializePolar(
CImmDevice* pDevice,
LONG lStiffness,
DWORD dwSaturation,
DWORD dwDeadband,
POINT pntCenter,
LONG lAngle,
BOOL bUseDeviceCoordinates = FALSE,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
//
// INTERNAL DATA
//
protected:
};
//
// INLINES
//
inline BOOL
CImmSpring::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Spring);
}
#endif // !defined(AFX_IMMSpring_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

407
code/ff/IFC/ImmTexture.h Normal file
View File

@@ -0,0 +1,407 @@
/**********************************************************************
Copyright (c) 1997 - 2000 Immersion Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation may be granted without fee;
interested parties are encouraged to request permission from
Immersion Corporation
801 Fox Lane
San Jose, CA 95131
408-467-1900
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
FILE: ImmTexture.h
PURPOSE: Texture Class for Feelit API Foundation Classes
STARTED: 2/27/98
NOTES/REVISIONS:
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
3/2/99 jrm: Added GetIsCompatibleGUID
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
**********************************************************************/
#if !defined(AFX_ImmTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
#define AFX_ImmTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef _IFCDLL_
#define DLLIFC __declspec(dllimport)
#else
#define DLLIFC __declspec(dllexport)
#endif
#include <windows.h>
#include "ImmBaseTypes.h"
#include "ImmEffect.h"
//================================================================
// Constants
//================================================================
const POINT IMM_TEXTURE_PT_NULL = { 0, 0 };
const POINT IMM_TEXTURE_DEFAULT_OFFSET_POINT = { 0, 0};
#define IMM_TEXTURE_DEFAULT_MAGNITUDE 5000
#define IMM_TEXTURE_DEFAULT_WIDTH 10
#define IMM_TEXTURE_DEFAULT_SPACING 20
//================================================================
// CImmTexture
//================================================================
//
// ------ PUBLIC INTERFACE ------
//
class DLLIFC CImmTexture : public CImmEffect
{
//
// CONSTRUCTOR/DESTRUCTOR
//
public:
// Constructor
CImmTexture();
// Destructor
virtual
~CImmTexture();
//
// ATTRIBUTES
//
public:
virtual BOOL
GetIsCompatibleGUID(
GUID &guid
);
virtual DWORD GetEffectType()
{ return IMM_EFFECTTYPE_TEXTURE; }
// Use this form for single-axis and dual-axis effects
BOOL
ChangeTextureParams(
LPCIMM_TEXTURE pTextureX,
LPCIMM_TEXTURE pTextureY
);
// Use this form for directional effects
BOOL
ChangeTextureParams(
LPCIMM_TEXTURE pTexture,
LONG lDirectionX,
LONG lDirectionY
);
// Use this form for directional effects
BOOL
ChangeTextureParamsPolar(
LPCIMM_TEXTURE pTexture,
LONG lAngle
);
// Use this form for single-axis, dual-axis symetrical, or directional effects
BOOL
ChangeTextureParams(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
// Use this form for single-axis, dual-axis, or directional effects
BOOL
ChangeTextureParamsX(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeTextureParamsY(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lDirectionX = IMM_EFFECT_DONT_CHANGE,
LONG lDirectionY = IMM_EFFECT_DONT_CHANGE
);
// Use this form for single-axis, dual-axis symetrical, or directional effects
BOOL
ChangeTextureParamsPolar(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
// Use this form for single-axis, dual-axis, or directional effects
BOOL
ChangeTextureParamsPolarX(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
BOOL
ChangeTextureParamsPolarY(
LONG lPosBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwPosBumpSpacing = IMM_EFFECT_DONT_CHANGE,
LONG lNegBumpMag = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpWidth = IMM_EFFECT_DONT_CHANGE,
DWORD dwNegBumpSpacing = IMM_EFFECT_DONT_CHANGE,
POINT pntOffset = IMM_EFFECT_DONT_CHANGE_POINT,
LONG lAngle = IMM_EFFECT_DONT_CHANGE
);
// Use these to change the the X Axis parameters for a dual-axis effect
BOOL ChangePositiveBumpMagX( LONG lPosBumpMag );
BOOL ChangeNegativeBumpMagX( LONG lNegBumpMag );
BOOL ChangePositiveBumpSpacingX( DWORD dwPosBumpSpacing );
BOOL ChangeNegativeBumpSpacingX( DWORD dwNegBumpSpacing );
BOOL ChangePositiveBumpWidthX( DWORD dwPosBumpWidth );
BOOL ChangeNegativeBumpWidthX( DWORD dwNegBumpWidth );
// Use these to change the the Y Axis parameters for a dual-axis effect
BOOL ChangePositiveBumpMagY( LONG lPosBumpMag );
BOOL ChangeNegativeBumpMagY( LONG lNegBumpMag );
BOOL ChangePositiveBumpSpacingY( DWORD dwPosBumpSpacing );
BOOL ChangeNegativeBumpSpacingY( DWORD dwNegBumpSpacing );
BOOL ChangePositiveBumpWidthY( DWORD dwPosBumpWidth );
BOOL ChangeNegativeBumpWidthY( DWORD dwNegBumpWidth );
// Use these to change the the parameters for a single-axis or
// dual-axis symetrical effect
BOOL ChangePositiveBumpMag( LONG lPosBumpMag );
BOOL ChangeNegativeBumpMag( LONG lNegBumpMag );
BOOL ChangePositiveBumpSpacing( DWORD dwPosBumpSpacing );
BOOL ChangeNegativeBumpSpacing( DWORD dwNegBumpSpacing );
BOOL ChangePositiveBumpWidth( DWORD dwPosBumpWidth );
BOOL ChangeNegativeBumpWidth( DWORD dwNegBumpWidth );
BOOL ChangeOffset( POINT pntOffset );
BOOL GetPositiveBumpMagX( LONG &lPosBumpMag );
BOOL GetNegativeBumpMagX( LONG &lNegBumpMag );
BOOL GetPositiveBumpSpacingX( DWORD &dwPosBumpSpacing );
BOOL GetNegativeBumpSpacingX( DWORD &dwNegBumpSpacing );
BOOL GetPositiveBumpWidthX( DWORD &dwPosBumpWidth );
BOOL GetNegativeBumpWidthX( DWORD &dwNegBumpWidth );
BOOL GetPositiveBumpMagY( LONG &lPosBumpMag );
BOOL GetNegativeBumpMagY( LONG &lNegBumpMag );
BOOL GetPositiveBumpSpacingY( DWORD &dwPosBumpSpacing );
BOOL GetNegativeBumpSpacingY( DWORD &dwNegBumpSpacing );
BOOL GetPositiveBumpWidthY( DWORD &dwPosBumpWidth );
BOOL GetNegativeBumpWidthY( DWORD &dwNegBumpWidth );
BOOL GetOffset( POINT &pntOffset );
//
// OPERATIONS
//
public:
virtual BOOL
Initialize(
CImmDevice* pDevice,
const IMM_EFFECT &effect,
DWORD dwNoDownload = 0
);
// Use this form for single-axis and dual-axis effects
BOOL
InitTexture(
CImmDevice* pDevice,
LPCIMM_TEXTURE pTextureX,
LPCIMM_TEXTURE pTextureY,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitTexture(
CImmDevice* pDevice,
LPCIMM_TEXTURE pTexture,
LONG lDirectionX,
LONG lDirectionY,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitTexturePolar(
CImmDevice* pDevice,
LPCIMM_TEXTURE pTexture,
LONG lAngle,
DWORD dwNoDownload = 0
);
// Use this form for single-axis, dual-axis symetrical, or directional effects
BOOL
InitTexture(
CImmDevice* pDevice,
LONG lPosBumpMag = IMM_TEXTURE_DEFAULT_MAGNITUDE,
DWORD dwPosBumpWidth = IMM_TEXTURE_DEFAULT_WIDTH,
DWORD dwPosBumpSpacing = IMM_TEXTURE_DEFAULT_SPACING,
LONG lNegBumpMag = IMM_TEXTURE_DEFAULT_MAGNITUDE,
DWORD dwNegBumpWidth = IMM_TEXTURE_DEFAULT_WIDTH,
DWORD dwNegBumpSpacing = IMM_TEXTURE_DEFAULT_SPACING,
DWORD dwfAxis = IMM_EFFECT_AXIS_BOTH,
POINT pntOffset = IMM_TEXTURE_DEFAULT_OFFSET_POINT,
LONG lDirectionX = IMM_EFFECT_DEFAULT_DIRECTION_X,
LONG lDirectionY = IMM_EFFECT_DEFAULT_DIRECTION_Y,
DWORD dwNoDownload = 0
);
// Use this form for directional effects
BOOL
InitTexturePolar(
CImmDevice* pDevice,
LONG lPosBumpMag = IMM_TEXTURE_DEFAULT_MAGNITUDE,
DWORD dwPosBumpWidth = IMM_TEXTURE_DEFAULT_WIDTH,
DWORD dwPosBumpSpacing = IMM_TEXTURE_DEFAULT_SPACING,
LONG lNegBumpMag = IMM_TEXTURE_DEFAULT_MAGNITUDE,
DWORD dwNegBumpWidth = IMM_TEXTURE_DEFAULT_WIDTH,
DWORD dwNegBumpSpacing = IMM_TEXTURE_DEFAULT_SPACING,
POINT pntOffset = IMM_TEXTURE_DEFAULT_OFFSET_POINT,
LONG lAngle = IMM_EFFECT_DEFAULT_ANGLE,
DWORD dwNoDownload = 0
);
//
// ------ PRIVATE INTERFACE ------
//
//
// HELPERS
//
protected:
BOOL
set_parameters(
DWORD dwfAxis,
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
LPCIMM_TEXTURE pTextureX,
LPCIMM_TEXTURE pTextureY
);
BOOL
set_parameters(
DWORD dwfAxis,
DWORD dwfCoordinates,
LONG lDirection0,
LONG lDirection1,
LONG lPosBumpMag,
DWORD dwPosBumpWidth,
DWORD dwPosBumpSpacing,
LONG lNegBumpMag,
DWORD dwNegBumpWidth,
DWORD dwNegBumpSpacing,
POINT pntOffset
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
LPCIMM_TEXTURE pTextureX,
LPCIMM_TEXTURE pTextureY
);
DWORD
change_parameters(
LONG lDirection0,
LONG lDirection1,
LONG lPosBumpMag,
DWORD dwPosBumpWidth,
DWORD dwPosBumpSpacing,
LONG lNegBumpMag,
DWORD dwNegBumpWidth,
DWORD dwNegBumpSpacing,
POINT pntOffset,
int fAxis
);
int
buffer_ifr_data(
TCHAR* pData
);
//
// INTERNAL DATA
//
IMM_TEXTURE m_aTexture[2];
DWORD m_dwfAxis;
protected:
};
//
// INLINES
//
inline BOOL
CImmTexture::GetIsCompatibleGUID(GUID &guid)
{
return IsEqualGUID(guid, GUID_Imm_Texture);
}
#endif // !defined(AFX_ImmTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)

72
code/ff/cl_ff.cpp Normal file
View File

@@ -0,0 +1,72 @@
//#include "../server/exe_headers.h"
#include "../client/client.h"
#ifdef _IMMERSION
#include "ff_public.h"
#include "ff.h"
#include "ff_snd.h"
extern clientActive_t cl;
void CL_InitFF( void )
{
cvar_t *use_ff = Cvar_Get( "use_ff", "1", CVAR_ARCHIVE );
if (!use_ff
|| !use_ff->integer
|| !FF_Init()
){
FF_Shutdown();
}
}
void CL_ShutdownFF( void )
{
FF_Shutdown();
}
qboolean IsLocalClient( int clientNum )
{
return qboolean
( clientNum == 0 //clientNum == cl.snap.ps.clientNum
|| clientNum == FF_CLIENT_LOCAL // assumed local
);
}
void CL_FF_Start( ffHandle_t ff, int clientNum )
{
if ( IsLocalClient( clientNum ) )
{
//FF_Play( ff ); // plays instantly
FF_AddForce( ff ); // plays at end of frame
}
}
void CL_FF_Stop( ffHandle_t ff, int clientNum )
{
if ( IsLocalClient( clientNum ) )
{
FF_Stop( ff );
}
}
/*
void CL_FF_EnsurePlaying( ffHandle_t ff, int clientNum )
{
if ( IsLocalClient( clientNum ) )
{
FF_EnsurePlaying( ff );
}
}
*/
void CL_FF_AddLoopingForce( ffHandle_t ff, int clientNum )
{
if ( IsLocalClient( clientNum ) )
{
FF_AddLoopingForce( ff );
}
}
#endif // _IMMERSION

13
code/ff/cl_ff.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef __CL_FF_H
#define __CL_FF_H
#include "ff_public.h"
void CL_InitFF ( void );
void CL_ShutdownFF ( void );
void CL_FF_Start ( ffHandle_t ff, int clientNum = FF_CLIENT_LOCAL );
void CL_FF_Stop ( ffHandle_t ff, int clientNum = FF_CLIENT_LOCAL );
void CL_FF_AddLoopingForce ( ffHandle_t ff, int clientNum = FF_CLIENT_LOCAL );
#endif // __CL_FF_H

50
code/ff/common_headers.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef FF_COMMON_HEADERS_H
#define FF_COMMON_HEADERS_H
#ifdef _IMMERSION
#include "ff_local.h"
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4032)
#pragma warning(disable : 4051)
#pragma warning(disable : 4057) // slightly different base types
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4115)
#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4136)
#pragma warning(disable : 4152) // nonstandard extension, function/data pointer conversion in expression
#pragma warning(disable : 4201)
#pragma warning(disable : 4214) // bitfields on type other than int
#pragma warning(disable : 4244) // conversion from double to float
#pragma warning(disable : 4284) // return type not UDT
#pragma warning(disable : 4305) // truncation from const double to float
#pragma warning(disable : 4310) // cast truncates constant value
#pragma warning(disable : 4503) // decorated name length truncated
#pragma warning(disable : 4505) // unreferenced local function has been removed
#pragma warning(disable : 4511) // copy ctor could not be genned
#pragma warning(disable : 4512) // assignment op could not be genned
#pragma warning(disable : 4514) // unreffed inline removed
#pragma warning(disable : 4663) // c++ lang change
#pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4711) // selected for automatic inline expansion
#pragma warning(disable : 4220) // varargs matches remaining parameters
#pragma warning(disable : 4786) // identifier was truncated
#pragma warning(disable : 4800) // forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(disable : 4702)
#pragma warning( push, 3 )
#include <map>
#include <string>
#include <set>
#include <vector>
#pragma warning( pop )
using namespace std;
#include "ifc.h"
#include "ff_utils.h"
#include "ff_system.h"
#endif // _IMMERSION
#endif // FF_COMMON_HEADERS_H

383
code/ff/ff.cpp Normal file
View File

@@ -0,0 +1,383 @@
#include "common_headers.h"
#ifdef _IMMERSION
#define INITGUID // this will need removing if already defined in someone else's module. Only one must exist in whole game
//#include "ff.h"
//#include "ff_ffset.h"
//#include "ff_compound.h"
//#include "ff_system.h"
FFSystem gFFSystem;
cvar_t *use_ff;
cvar_t *ensureShake;
cvar_t *ff_developer;
#ifdef FF_DELAY
cvar_t *ff_delay;
#endif
cvar_t *ff_channels;
static const char *_pass = "SUCCEEDED";
static const char *_fail = "FAILED";
const char *gChannelName[ FF_CHANNEL_MAX ] =
{ "FF_CHANNEL_WEAPON"
, "FF_CHANNEL_MENU"
, "FF_CHANNEL_TOUCH"
, "FF_CHANNEL_DAMAGE"
, "FF_CHANNEL_BODY"
, "FF_CHANNEL_FORCE"
, "FF_CHANNEL_FOOT"
};
// Enable/Disable Com_Printf in FF_* functions
#if( 1 )
#ifdef FF_PRINT
#define FF_PROLOGUE( name, string ) qboolean result = qfalse; if ( FF_IsAvailable() ) { if ( ff_developer && ff_developer->integer ) Com_Printf( "%s: \"%s\" ", #name, string );
#define FF_PROLOGUE_NOQUOTE( name, string ) qboolean result = qfalse; if ( FF_IsAvailable() ) { if ( ff_developer && ff_developer->integer ) Com_Printf( "%s: %s ", #name, string );
#define FF_EPILOGUE FF_EPILOGUE_NORETURN; return result;
#define FF_EPILOGUE_NORETURN } if ( ff_developer && ff_developer->integer ) Com_Printf( "[%s]\n", ( result ? _pass : _fail ) );
#define FF_RESULT( function ) result = qboolean( function );
#else
#define FF_PROLOGUE( name, string ) qboolean result = qfalse; if ( FF_IsAvailable() ) {
#define FF_PROLOGUE_NOQUOTE( name, string ) qboolean result = qfalse; if ( FF_IsAvailable() ) {
#define FF_EPILOGUE FF_EPILOGUE_NORETURN; return result;
#define FF_EPILOGUE_NORETURN }
#define FF_RESULT( function ) result = qboolean( function );
#endif
#else
#define FF_PROLOGUE( name, string ) qboolean result = qfalse;
#define FF_PROLOGUE_NOQUOTE( name, string ) qboolean result = qfalse;
#define FF_EPILOGUE return result;
#define FF_EPILOGUE_NORETURN
#define FF_RESULT( function ) result = qboolean( function );
#endif
////--------------
/// FF_IsAvailable
//------------------
// Test to see if force feedback is currently operating. This is almost useless.
// The only good it does currently is temporarily toggle effects on/off for users
// amusement... feedback on, feedback off, feedback on, feedback off. Results are
// instantaneous. FF_* calls basically skip themselves harmlessly.
//
// Assumptions:
// * External system unloads this module if no device is present.
// * External system unloads this module if feedback is disabled when system (re)starts
//
// Parameters:
// None
//
// Returns:
// - true: feedback currently enabled
// - false: feedback currently disabled
//
qboolean FF_IsAvailable(void)
{
return (use_ff && use_ff->integer && gFFSystem.IsInitialized()) ? qtrue : qfalse;
}
qboolean FF_IsInitialized(void)
{
return gFFSystem.IsInitialized();
}
////-------
/// FF_Init
//-----------
// Initializes the force feedback system.
//
// This function may be called multiple times to apply changes in cvars.
//
// Assumptions:
// * If FF_Init returns qfalse, caller calls FF_Shutdown
//
// Parameters:
// None
//
// Returns:
// - qtrue: module initialized properly.
// - qfalse: module experienced an error. Caller MUST call FF_Shutdown.
//
qboolean FF_Init( void )
{
if ( !gFFSystem.IsInitialized() )
{
//
// Console variable setup
//
#ifdef FF_CONSOLECOMMAND
Cmd_AddCommand( "ff_stopall", CMD_FF_StopAll );
Cmd_AddCommand( "ff_info", CMD_FF_Info );
#endif
use_ff = Cvar_Get( "use_ff", "1", CVAR_ARCHIVE /*| CVAR_LATCH*/);
ensureShake = Cvar_Get( "ff_ensureShake", "1", CVAR_TEMP);
ff_developer = Cvar_Get( "ff_developer", "0", CVAR_TEMP);
ff_channels = Cvar_Get( "ff_channels", FF_CHANNEL, CVAR_ARCHIVE);
#ifdef FF_DELAY
ff_delay = Cvar_Get( "ff_delay", FF_DELAY, CVAR_ARCHIVE);
#endif
}
return qboolean // assumes external system will call FF_Shutdown in case of failure
( ff_channels != NULL
&& gFFSystem.Init( ff_channels->string )
);
}
////-----------
/// FF_Shutdown
//---------------
// Shut force feedback system down and free resources.
//
// Assumptions:
// * Always called if FF_Init returns qfalse. ALWAYS. (Or memory leaks occur)
// * Never called twice in succession. (always in response to previous assumption)
//
// Parameters:
// None
//
// Returns:
// None
//
void FF_Shutdown(void)
{
#ifdef FF_CONSOLECOMMAND
Cmd_RemoveCommand( "ff_stopall" );
Cmd_RemoveCommand( "ff_info" );
#endif
gFFSystem.Shutdown();
}
////-----------
/// FF_Register
//---------------
// Loads a named effect from an .ifr file through the game's file system. The handle
// returned is not tied to any particular device. The feedback system may even change
// which device receives the effect without the need to restart the external system.
// The is ONE EXCEPTION. If this module is not loaded when the registration phase
// passes, the external system will need to be restarted to register effects properly.
//
// Parameters:
// * name: effect name from .ifr (case-sensitive)
// * channel: channel to output effect. A channel may play on 0+ devices.
// * notfound: return a valid handle even if effect is not found
// - Allows temporary disabling of a channel in-game without losing effects
// - Only use with trusted effect names, not user input. See CMD_FF_Play.
//
// Returns:
// Handle to loaded effect
//
ffHandle_t FF_Register( const char *name, int channel, qboolean notfound )
{
ffHandle_t ff = FF_HANDLE_NULL;
// Removed console print... too much spam with AddLoopingForce.
/*
FF_PROLOGUE( FF_Register, ( name ? name : "" ) );
ff = gFFSystem.Register( name, channel, notfound );
FF_RESULT( ff != FF_HANDLE_NULL );
FF_EPILOGUE_NORETURN;
*/
if ( FF_IsAvailable() )
ff = gFFSystem.Register( name, channel, notfound );
return ff;
}
////----------------
/// FF_EnsurePlaying
//--------------------
// Starts an effect if the effect is not currently playing.
// Does not restart currently playing effects.
//
// Parameters:
// * ff: handle of an effect
//
// Returns:
// - qtrue: effect started
// - qfalse: effect was not started
//
qboolean FF_EnsurePlaying(ffHandle_t ff)
{
FF_PROLOGUE( FF_EnsurePlaying, gFFSystem.GetName( ff ) );
FF_RESULT( gFFSystem.EnsurePlaying( ff ) );
FF_EPILOGUE;
}
////-------
/// FF_Play
//-----------
// Start an effect on its registered channel.
//
// Parameters
// * ff: handle to an effect
//
// Returns:
// - qtrue: effect started
// - qfalse: effect was not started
//
qboolean FF_Play(ffHandle_t ff)
{
FF_PROLOGUE( FF_Play, gFFSystem.GetName( ff ) );
FF_RESULT( gFFSystem.Play( ff ) );
FF_EPILOGUE;
}
////----------
/// FF_StopAll
//--------------
// Stop all currently playing effects.
//
// Parameters:
// None
//
// Returns:
// - qtrue: no errors occurred
// - qfalse: an error occurred
//
qboolean FF_StopAll(void)
{
FF_PROLOGUE( FF_StopAll, "" );
FF_RESULT( gFFSystem.StopAll() );
FF_EPILOGUE;
}
////-------
/// FF_Stop
//-----------
// Stop an effect. Only returns qfalse if there's an error
//
// Parameters:
// * ff: handle to a playing effect
//
// Returns:
// - qtrue: no errors occurred
// - qfalse: an error occurred
//
qboolean FF_Stop(ffHandle_t ff)
{
FF_PROLOGUE( FF_Stop, gFFSystem.GetName( ff ) );
FF_RESULT( gFFSystem.Stop( ff ) );
FF_EPILOGUE;
}
////--------
/// FF_Shake
//------------
// Shake the mouse (play the special "shake" effect) at a given strength
// for a given duration. The shake effect can be a compound containing
// multiple component effects, but each component effect's magnitude and
// duration will be set to the parameters passed in this function.
//
// Parameters:
// * intensity [0..10000] - Magnitude of effect
// * duration [0..MAXINT] - Length of shake in milliseconds
//
// Returns:
// - qtrue: shake started
// - qfalse: shake did not start
//
qboolean FF_Shake(int intensity, int duration)
{
char message[64];
message[0] = 0;
sprintf( message, "intensity=%d, duration=%d", intensity, duration );
FF_PROLOGUE_NOQUOTE( FF_Shake, message );
FF_RESULT( gFFSystem.Shake( intensity, duration, qboolean( ensureShake->integer != qfalse ) ) );
FF_EPILOGUE;
}
#ifdef FF_CONSOLECOMMAND
////--------------
/// CMD_FF_StopAll
//------------------
// Console function which stops all currently playing effects
//
// Parameters:
// None
//
// Returns:
// None
//
void CMD_FF_StopAll(void)
{
// Display messages
if ( FF_StopAll() )
{
Com_Printf( "stopping all effects\n" );
}
else
{
Com_Printf( "failed to stop all effects\n" );
}
}
////-----------
/// CMD_FF_Info
//---------------
// Console function which displays various ff-system information.
//
// Parameters:
// * 'devices' display list of ff devices currently connected
// * 'channels' display list of support ff channels
// * 'order' display search order used by ff name-resolution system (ff_ffset.cpp)
// * 'files' display currently loaded .ifr files sorted by device
// * 'effects' display currently registered effects sorted by device
//
// Returns:
// None
//
void CMD_FF_Info(void)
{
TNameTable Unprocessed, Processed;
int i, max;
for
( i = 1, max = Cmd_Argc()
; i < max
; i++
){
Unprocessed.push_back( Cmd_Argv( i ) );
}
if ( Unprocessed.size() == 0 )
{
if ( ff_developer->integer )
Com_Printf( "Usage: ff_info [devices] [channels] [order] [files] [effects]\n" );
else
Com_Printf( "Usage: ff_info [devices] [channels]\n" );
return;
}
gFFSystem.Display( Unprocessed, Processed );
if ( Unprocessed.size() > 0 )
{
Com_Printf( "invalid parameters:" );
for
( i = 0
; i < Unprocessed.size()
; i++
){
Com_Printf( " %s", Unprocessed[ i ].c_str() );
}
if ( ff_developer->integer )
Com_Printf( "Usage: ff_info [devices] [channels] [order] [files] [effects]\n" );
else
Com_Printf( "Usage: ff_info [devices] [channels]\n" );
}
}
#endif // FF_CONSOLECOMMAND
#endif // _IMMERSION

33
code/ff/ff.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef __FF_H
#define __FF_H
#include "../ff/ff_public.h"
#ifdef _FF
//
// Externally visible functions
//
qboolean FF_Init (void);
void FF_Shutdown (void);
qboolean FF_IsAvailable (void);
qboolean FF_IsInitialized (void);
ffHandle_t FF_Register (const char* ff, int channel, qboolean notfound = qtrue);
qboolean FF_Play (ffHandle_t ff);
qboolean FF_EnsurePlaying (ffHandle_t ff);
qboolean FF_Stop (ffHandle_t ff);
qboolean FF_StopAll (void);
qboolean FF_Shake (int intensity, int duration);
#ifdef FF_CONSOLECOMMAND
typedef void (*xcommand_t) (void);
void CMD_FF_StopAll (void);
void CMD_FF_Info (void);
#endif
//ffExport_t* GetFFAPI ( int apiVersion, ffImport_t *ffimp );
#endif // _FF
#endif // __FF_H

View File

@@ -0,0 +1,64 @@
#ifndef FF_CHANNELCOMPOUND_H
#define FF_CHANNELCOMPOUND_H
#include "ff_MultiCompound.h"
////---------------
/// ChannelCompound
//-------------------
// Stored in THandleTable. This class associates MultiCompound with some arbitrary 'channel.'
// Further, this class assumes that its MultiEffects have the same name and are probably
// initialized on different devices. None of this is enforced at this time.
//
class ChannelCompound : public MultiCompound
{
protected:
int mChannel;
public:
ChannelCompound( int channel = FF_CHANNEL_MAX )
: MultiCompound()
{
mChannel =
( (channel >= 0 && channel < FF_CHANNEL_MAX)
? channel
: FF_CHANNEL_MAX
);
}
ChannelCompound( Set &compound, int channel = FF_CHANNEL_MAX )
: MultiCompound( compound )
{
mChannel =
( (channel >= 0 && channel < FF_CHANNEL_MAX)
? channel
: FF_CHANNEL_MAX
);
}
int GetChannel()
{
return mChannel;
}
const char *GetName()
{
return mSet.size()
? (*mSet.begin())->GetName()
: NULL
;
}
qboolean operator == ( ChannelCompound &channelcompound )
{
return qboolean
( mChannel == channelcompound.mChannel
&& (*(MultiCompound*)this) == *(MultiCompound*)&channelcompound
);
}
qboolean operator != ( ChannelCompound &channelcompound )
{
return qboolean( !( (*this) == channelcompound ) );
}
};
typedef vector<ChannelCompound> THandleTable;
#endif // FF_CHANNELCOMPOUND_H

162
code/ff/ff_ChannelSet.cpp Normal file
View File

@@ -0,0 +1,162 @@
#include "common_headers.h"
#ifdef _IMMERSION
extern const char *gChannelName[];
////---------------------------
/// FFChannelSet::ParseChannels
//-------------------------------
// This is the worst hack of a parser ever devised.
//
qboolean FFChannelSet::ParseChannels( const char *channels )
{
if ( !channels )
return qfalse;
int channel;
const char *pos;
for
( pos = channels
; pos && sscanf( pos, "%d", &channel ) == 1
;
){
int device;
char *endpos;
endpos = strchr( pos, ';' );
if ( channel >= 0 && channel < FF_CHANNEL_MAX )
{
for
( pos = strchr( pos, ',' )
; pos && ( !endpos || pos < endpos ) && sscanf( pos, " ,%d", &device ) == 1
; pos = strchr( pos + 1, ',' )
){
if ( device >= 0 && device < mSet.size() )
{
for
( ChannelIterator itChannel( mChannel, channel )
; itChannel != mChannel.end()
&& (**itChannel).second != device // found duplicate
; ++itChannel
);
// Don't allow duplicates
if ( itChannel == mChannel.end() )
{
FFChannelSet::Channel::value_type Value( channel, device );
Value.second = device;
mChannel.insert( Value );
}
}
}
}
pos = ( endpos ? endpos + 1 : NULL);
}
// FIX ME -- return qfalse if there is a parse error
return qtrue;
}
////----------------------
/// FFChannelSet::Register
//--------------------------
//
// Assumptions:
// * 'compound' is empty of effects and contains the desired channel prior to entry.
//
// Parameters:
// * compound: its channel parameter is an input. its effect set is filled with registered
// - effects. 'compound' should not contain any effects prior to this function call.
// * name: effect name to register in each FFSet on the channel
// * create: qtrue if FFSet should create the effect, qfalse if it should just look it up.
//
qboolean FFChannelSet::Register( ChannelCompound &compound, const char *name, qboolean create )
{
for
( ChannelIterator itChannel( mChannel, compound.GetChannel() )
; itChannel != mChannel.end()
; ++itChannel
){
MultiEffect *Effect;
Effect = mSet[ (**itChannel).second ]->Register( name, create );
if ( Effect )
compound.GetSet().insert( Effect );
}
return qboolean( compound.GetSet().size() != 0 );
}
#ifdef FF_CONSOLECOMMAND
void FFChannelSet::GetDisplayTokens( TNameTable &Tokens )
{
FFMultiSet::GetDisplayTokens( Tokens );
Tokens.push_back( "channels" );
Tokens.push_back( "devices" );
}
void FFChannelSet::Display( TNameTable &Unprocessed, TNameTable &Processed )
{
FFMultiSet::Display( Unprocessed, Processed );
for
( TNameTable::iterator itName = Unprocessed.begin()
; itName != Unprocessed.end()
;
){
if ( stricmp( "channels", (*itName).c_str() ) == 0 )
{
Com_Printf( "[available channels]\n" );
for
( int i = 0
; i < FF_CHANNEL_MAX
; i++
){
Com_Printf( "%d) %s devices:", i, gChannelName[ i ] );
for
( ChannelIterator itChannel( mChannel, i )
; itChannel != mChannel.end()
; ++itChannel
){
Com_Printf( " %d", (**itChannel).second );
}
Com_Printf( "\n" );
}
Processed.push_back( *itName );
itName = Unprocessed.erase( itName );
}
else if ( stricmp( "devices", (*itName).c_str() ) == 0 )
{
Com_Printf( "[initialized devices]\n" );
for
( int i = 0
; i < mDevices->GetNumDevices()
; i++
){
char ProductName[ FF_MAX_PATH ];
ProductName[ 0 ] = 0;
mDevices->GetDevice( i )->GetProductName( ProductName, FF_MAX_PATH - 1 );
Com_Printf( "%d) %s\n", i, ProductName );
}
Processed.push_back( *itName );
itName = Unprocessed.erase( itName );
}
else
{
itName++;
}
}
}
#endif // FF_CONSOLECOMMAND
#endif // _IMMERSION

59
code/ff/ff_ChannelSet.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef FF_CHANNELSET_H
#define FF_CHANNELSET_H
#include "ff_utils.h"
#include "ff_MultiSet.h"
#include "ff_ChannelCompound.h"
//===[FFChannelSet]===================================================/////////////
//
// An extension to FFMultiSet that operates on a subset of its
// elements specified by a channel. This channel may be inherent
// to a ChannelCompound passed as a parameter.
//
//====================================================================/////////////
class FFChannelSet : public FFMultiSet
{
public:
typedef multimap<int, int> Channel;
protected:
Channel mChannel;
qboolean ParseChannels( const char *channels );
public:
qboolean Init( FFConfigParser &config, const char *channels )
{
return qboolean
( FFMultiSet::Init( config ) // Initialize devices
&& ParseChannels( channels ) // Assign channels to devices
);
}
void clear()
{
mChannel.clear();
FFMultiSet::clear();
}
qboolean Register( ChannelCompound &compound, const char *name, qboolean create );
//
// Optional
//
#ifdef FF_ACCESSOR
// Channel& GetAll() { return mChannel; }
#endif
#ifdef FF_CONSOLECOMMAND
void Display( TNameTable &Unprocessed, TNameTable &Processed );
static void GetDisplayTokens( TNameTable &Tokens );
#endif
};
class ChannelIterator : public multimapIterator<FFChannelSet::Channel>
{
public:
ChannelIterator( FFChannelSet::Channel &map, int channel )
: multimapIterator<FFChannelSet::Channel>( map, channel )
{}
};
#endif // FF_CHANNELSET_H

483
code/ff/ff_ConfigParser.cpp Normal file
View File

@@ -0,0 +1,483 @@
#include "common_headers.h"
#ifdef _IMMERSION
//#include "ff_ConfigParser.h"
//#include "ifc.h"
//#include "ff_utils.h"
////--------------------
/// FFConfigParser::Init
//------------------------
// Reads the force feedback configuration file. Call this once after the device
// is initialized.
//
// Parameters:
// * filename
//
// Returns:
// * qtrue - the effects set directory has been set according to the initialized
// device. (See base/fffx/fffx.cfg)
// * qfalse - no effects set could be determined for this device.
//
qboolean FFConfigParser::Init( const char *filename )
{
Clear(); // Always cleanup
return qboolean( filename && Parse( LoadFile( filename ) ) );
}
////---------------------
/// FFConfigParser::Clear
//-------------------------
//
//
// Parameters:
//
// Returns:
//
void FFConfigParser::Clear( void )
{
mMap.clear();
mDefaultSet.clear();
}
////---------------------
/// FFConfigParser::Parse
//-------------------------
//
//
// Parameters:
//
// Returns:
//
qboolean FFConfigParser::Parse( void *file )
{
qboolean result = qboolean( file != NULL );
if ( file )
{
const char *token = 0, *pos = (const char*)file;
for
( token = COM_ParseExt( &pos, qtrue )
; token[ 0 ]
&& result // fail if any problem
; token = COM_ParseExt( &pos, qtrue )
){
if ( !stricmp( token, "ffdefaults" ) )
{
result &= ParseDefaults( &pos );
}
else
if ( !stricmp( token, "ffsets" ) )
{
result &= ParseSets( &pos );
}
else
{
// unexpected field
result = qfalse;
}
}
FS_FreeFile( file );
}
return result;
}
////---------------------------------
/// FFConfigParser::ParseDefaultBlock
//-------------------------------------
//
//
// Parameters:
//
// Returns:
//
qboolean FFConfigParser::ParseDefault( const char **pos, TDeviceType &defaultSet )
{
qboolean result = qboolean( pos != NULL );
if ( pos )
{
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
int device = 0;
if ( sscanf( token, "%d", &device ) )
{
string &str = defaultSet[ device ];
if ( !str.size() )
{
str = COM_ParseExt( pos, qfalse );
result &= qboolean( str.size() > 0 );
}
else
{
result = qfalse;
#ifdef FF_PRINT
ConsoleParseError
( "Redefinition of DeviceType index"
, token
);
#endif
}
}
else
{
result = qfalse;
#ifdef FF_PRINT
ConsoleParseError
( "DeviceType field should begin with an integer"
, token
);
#endif
}
}
}
}
return result;
}
////----------------------------
/// FFConfigParser::ParseDefault
//--------------------------------
//
//
// Parameters:
//
// Returns:
//
qboolean FFConfigParser::ParseDefaults( const char **pos )
{
qboolean result = qboolean( pos != NULL );
if ( pos )
{
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
int techType = 0;
if ( sscanf( token, "%d", &techType ) )
{
TDeviceType &deviceType = mDefaultSet[ techType ];
if ( !deviceType.size() )
{
result &= ParseDefault( pos, deviceType );
mDefaultPriority.push_back( techType );
}
else
{
result = qfalse;
#ifdef FF_PRINT
ConsoleParseError
( "Redefinition of TechType index"
, token
);
#endif
}
}
else
{
result = qfalse;
#ifdef FF_PRINT
ConsoleParseError
( "TechType fields should begin with integers"
, token
);
#endif
}
}
}
else
{
// expected '{'
result = qfalse;
}
}
return result;
}
////--------------------------
/// FFConfigParser::RightOfSet
//------------------------------
//
//
// Parameters:
//
// Returns:
//
const char* FFConfigParser::RightOfSet( const char *effectname )
{
const char *s = effectname;
// Check through all set names and test effectname against it
for
( TMap::iterator itMap = mMap.begin()
; itMap != mMap.end() && s == effectname
; itMap++
){
s = RightOf( effectname, (*itMap).first.c_str() );
}
return s ? s : effectname;
}
qboolean FFConfigParser::ParseSetDevices( const char **pos, TDevice &device )
{
qboolean result = qboolean( pos != NULL );
if ( pos )
{
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
device.insert( token );
}
result = qboolean( token[ 0 ] != 0 );
}
else
{
// expected '{'
result = qfalse;
}
}
return result;
}
qboolean FFConfigParser::ParseSetIncludes( const char **pos, TInclude &include )
{
qboolean result = qboolean( pos != NULL );
if ( pos )
{
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
include.push_back( token );
}
result = qboolean( token[ 0 ] != 0 );
}
else
{
// expected '{'
result = qfalse;
}
}
return result;
}
qboolean FFConfigParser::ParseSet( const char **pos, TData &data )
{
qboolean result = qboolean( pos != NULL );
if ( pos )
{
const char *oldpos = *pos; // allows set declarations with no attributes to have no "{}"
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
if ( !stricmp( token, "includes" ) )
{
result &= ParseSetIncludes( pos, data.include );
}
else
if ( !stricmp( token, "devices" ) )
{
result &= ParseSetDevices( pos, data.device );
}
else
{
result = qfalse;
#ifdef FF_PRINT
ConsoleParseError
( "Invalid set parameter. Should be 'includes' or 'devices'"
, token
);
#endif
}
}
}
else
{
// expected '{' (no longer expected!)
//result = qfalse; (no longer an error!)
*pos = oldpos;
}
}
return result;
}
////-------------------------
/// FFConfigParser::ParseSets
//-----------------------------
//
//
// Parameters:
//
// Returns:
//
qboolean FFConfigParser::ParseSets( const char **pos )
{
qboolean result = qboolean( pos != NULL );
string groupName;
if ( pos )
{
char *token = COM_ParseExt( pos, qtrue );
if ( token[ 0 ] == '{' )
{
for
( token = COM_ParseExt( pos, qtrue )
; token[ 0 ]
&& token[ 0 ] != '}'
&& result // fail if any problem
; token = COM_ParseExt( pos, qtrue )
){
TData &data = mMap[ token ];
result &= ParseSet( pos, data );
}
}
else
{
// expected '{'
result = qfalse;
}
}
return result;
}
////---------------------------
/// FFConfigParser::GetIncludes
//-------------------------------
//
//
// Parameters:
//
// Returns:
//
FFConfigParser::TInclude& FFConfigParser::GetIncludes( const char *name )
{
TMap::iterator itMap = mMap.find( name );
if ( itMap != mMap.end() )
return (*itMap).second.include;
// No includes present
static TInclude emptyInclude;
return emptyInclude;
}
const char * FFConfigParser::GetFFSet( CImmDevice *Device )
{
char devName[ FF_MAX_PATH ];
const char *ffset = NULL;
//
// Check explicit name
//
devName[0] = 0;
Device->GetProductName( devName, FF_MAX_PATH - 1 );
for
( TMap::iterator itmap = mMap.begin()
; itmap != mMap.end()
; itmap++
){
TDevice::iterator itdev;
itdev = (*itmap).second.device.find( devName );
if ( itdev != (*itmap).second.device.end() )
ffset = (*itmap).first.c_str();
}
//
// Check device defaults
//
for
( int i = 0
; !ffset && i < mDefaultPriority.size()
; i++
){
int defaultTechType;
DWORD productType = Device->GetProductType();
WORD deviceType = HIWORD( productType );
WORD techType = LOWORD( productType );
defaultTechType = mDefaultPriority[ i ];
//
// Check for minimum required features
//
if ( (techType & defaultTechType) >= defaultTechType )
{
//
// Check that device exists in this technology section
//
TDeviceType::iterator itDeviceType = mDefaultSet[ defaultTechType ].find( deviceType );
if ( itDeviceType != mDefaultSet[ defaultTechType ].end() )
{
ffset = (*itDeviceType).second.c_str();
}
}
//
// If not, try next technology section
//
}
return ffset;
}
#endif // _IMMERSION

51
code/ff/ff_ConfigParser.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef __FF_CONFIGPARSER_H
#define __FF_CONFIGPARSER_H
//#include "ff_public.h" // in precompiled header
//class CImmDevice;
class FFConfigParser
{
public:
typedef vector<string> TInclude;
typedef set<string> TDevice;
typedef map<int, string> TDeviceType;
typedef map<int, TDeviceType> TTechType;
typedef vector<int> TDefaultPriority;
typedef struct
{
TInclude include;
TDevice device;
} TData;
typedef map<string, TData> TMap;
protected:
TTechType mDefaultSet;
TDefaultPriority mDefaultPriority;
TMap mMap; // Contains all effect sets by name
qboolean Parse( void *file );
qboolean ParseSets( const char **pos );
qboolean ParseSet( const char **pos, TData &data );
qboolean ParseSetIncludes( const char **pos, TInclude &include );
qboolean ParseSetDevices( const char **pos, TDevice &device );
qboolean ParseDefaults( const char **pos );
qboolean ParseDefault( const char **pos, TDeviceType &defaultSet );
public:
qboolean Init( const char *filename/*, CImmDevice *Device = NULL*/ );
void Clear( void );
// const char* RightOfBase( const char *effectname );
// const char* RightOfGame( const char *effectname );
const char* RightOfSet( const char *effectname );
const char* GetFFSet( CImmDevice *Device );
TInclude& GetIncludes( const char *name = NULL );
};
#endif // __FF_CONFIGPARSER_H

133
code/ff/ff_HandleTable.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include "common_headers.h"
#ifdef _IMMERSION
////----------------------
/// FFHandleTable::Convert
//--------------------------
//
//
ffHandle_t FFHandleTable::Convert( ChannelCompound &compound, const char *name, qboolean create )
{
ffHandle_t ff = FF_HANDLE_NULL;
// Reserve a handle for effects that failed to create.
// Rerouting channels to other devices may cause an effect to become lost.
// This assumes that FF_Register is always called with legitimate effect names.
// See CMD_FF_Play on how to handle possibly-bogus user input.
// (It does not call this function)
if ( compound.GetSet().size() )
ff = Convert( compound );
else
{
for
( FFHandleTable::RegFail::iterator itRegFail = mRegFail.begin()
; itRegFail != mRegFail.end()
&& (*itRegFail).second != name
; itRegFail++
);
ff =
( itRegFail != mRegFail.end()
? (*itRegFail).first
: FF_HANDLE_NULL
);
}
if ( ff == FF_HANDLE_NULL )
{
mVector.push_back( compound );
ff = mVector.size() - 1;
// Remember effect name for future 'ff_restart' calls.
if ( create && !compound.GetSet().size() )
mRegFail[ ff ] = name;
}
return ff;
}
////----------------------
/// FFHandleTable::Convert
//--------------------------
// Looks for 'compound' in the table.
//
// Assumes:
// * 'compound' is non-empty
//
// Returns:
// ffHandle_t
//
ffHandle_t FFHandleTable::Convert( ChannelCompound &compound )
{
for
( int i = 1
; i < mVector.size()
&& mVector[ i ] != compound
; i++
);
return
( i < mVector.size()
? i
: FF_HANDLE_NULL
);
}
////-----------------------------
/// FFHandleTable::GetFailedNames
//---------------------------------
//
//
qboolean FFHandleTable::GetFailedNames( TNameTable &NameTable )
{
for
( RegFail::iterator itRegFail = mRegFail.begin()
; itRegFail != mRegFail.end()
; itRegFail++
){
NameTable[ (*itRegFail).first ] = (*itRegFail).second;
}
return qboolean( mRegFail.size() != 0 );
}
////--------------------------
/// FFHandleTable::GetChannels
//------------------------------
//
//
qboolean FFHandleTable::GetChannels( vector<int> &channel )
{
//ASSERT( channel.size() >= mVector.size() );
for
( int i = 1
; i < mVector.size()
; i++
){
channel[ i ] = mVector[ i ].GetChannel();
}
return qtrue;
}
const char *FFHandleTable::GetName( ffHandle_t ff )
{
const char *result = NULL;
if ( !mVector[ ff ].IsEmpty() )
{
result = mVector[ ff ].GetName();
}
else
{
RegFail::iterator itRegFail = mRegFail.find( ff );
if ( itRegFail != mRegFail.end() )
result = (*itRegFail).second.c_str();
}
return result;
}
#endif // _IMMERSION

61
code/ff/ff_HandleTable.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef FF_HANDLETABLE_H
#define FF_HANDLETABLE_H
//===[FFHandleTable]==================================================/////////////
//
// This table houses the master list of initialized effects. Indices
// into this table are handles used by external modules. This way
// effects may be reinitialized on other devices, removed entirely,
// and perused informatively at any time without invalidating pointers.
//
//====================================================================/////////////
class FFHandleTable
{
public:
typedef vector<ChannelCompound> Vector;
typedef map<int, string> RegFail;
protected:
Vector mVector;
RegFail mRegFail;
public:
FFHandleTable()
: mVector()
, mRegFail()
{
//Init(); // guarantees operator [] always works
}
void Init()
{
ChannelCompound handle_null;
mVector.push_back( handle_null );
}
// Empties handle table except for FF_HANDLE_NULL
void clear()
{
mVector.clear();
mRegFail.clear();
//Init(); // guarantees operator [] always works
}
int size()
{
return mVector.size();
}
ChannelCompound& operator [] ( ffHandle_t ff )
{
return mVector[ InRange<int>( ff, 0, mVector.size() - 1, FF_HANDLE_NULL ) ];
}
qboolean GetFailedNames( TNameTable &NameTable );
qboolean GetChannels( vector<int> &channels );
ffHandle_t Convert( ChannelCompound &compound, const char *name, qboolean create );
ffHandle_t Convert( ChannelCompound &compound );
const char *GetName( ffHandle_t ff );
//
// Optional
//
// qboolean Lookup( set<ffHandle_t> &result, MultiEffect *effect, const char *name );
// qboolean Lookup( set<ffHandle_t> &result, set<MultiEffect*> &effect, const char *name );
};
#endif // FF_HANDLETABLE_H

View File

@@ -0,0 +1,201 @@
#include "common_headers.h"
#ifdef _IMMERSION
////------------------
/// MultiCompound::Add
//----------------------
// Insert a single compound effect if it does not already exist.
// Only fails when parameter is NULL.
//
qboolean MultiCompound::Add( MultiEffect *effect )
{
return effect ? ( mSet.insert( effect ), qtrue ) : qfalse;
}
////------------------
/// MultiCompound::Add
//----------------------
// Merge set of compound effects with current set. NULL pointers are excluded.
// Returns false if set contains any NULL pointers.
//
qboolean MultiCompound::Add( Set &effect )
{
qboolean result = qtrue;
for
( Set::iterator itSet = effect.begin()
; itSet != effect.end()
; itSet++
){
result &= Add( *itSet );
}
return result;
}
////--------------------
/// MultiCompound::Start
//------------------------
// Analogous to CImmCompoundEffect::Start. Starts all contained compound effects.
// Returns false if any effect returns false.
//
qboolean MultiCompound::Start()
{
qboolean result = qtrue;
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
result &= (*itSet)->Start();
}
return qboolean
( result
&& mSet.size() != 0
);
}
qboolean MultiCompound::IsPlaying()
{
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
if ( !(*itSet)->IsPlaying() )
return qfalse;
}
return qtrue;
}
////----------------------------
/// MultiCompound::EnsurePlaying
//--------------------------------
// Starts any contained compound effects if they are not currently playing.
// Returns false if any effect returns false or any are playing.
//
qboolean MultiCompound::EnsurePlaying()
{
qboolean result = qtrue;
if ( !IsPlaying() )
{
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
result &= (*itSet)->Start();
}
}
return qboolean
( result
&& mSet.size() != 0
);
}
////-------------------
/// MultiCompound::Stop
//-----------------------
// Analogous to CImmCompoundEffect::Stop. Stops all contained compound effects.
// Returns false if any effect returns false.
//
qboolean MultiCompound::Stop()
{
qboolean result = qtrue;
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
result &= qboolean( (*itSet)->Stop() );
}
return qboolean
( result
&& mSet.size() != 0
);
}
////-----------------------------
/// MultiCompound::ChangeDuration
//---------------------------------
// Changes duration of all compounds.
// Returns false if any effect returns false.
//
qboolean MultiCompound::ChangeDuration( DWORD Duration )
{
qboolean result = qtrue;
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
result &= (*itSet)->ChangeDuration( Duration );
}
return qboolean
( result
&& mSet.size() != 0
);
}
////-------------------------
/// MultiCompound::ChangeGain
//-----------------------------
// Changes gain of all compounds.
// Returns false if any effect returns false.
//
qboolean MultiCompound::ChangeGain( DWORD Gain )
{
qboolean result = qtrue;
for
( Set::iterator itSet = mSet.begin()
; itSet != mSet.end()
; itSet++
){
result &= (*itSet)->ChangeGain( Gain );
}
return qboolean
( result
&& mSet.size() != 0
);
}
////--------------------------
/// MultiCompound::operator ==
//------------------------------
// Returns qtrue if the sets are EXACTLY equal, including order. This is not good
// in general. (Fix me)
//
qboolean MultiCompound::operator == ( MultiCompound &compound )
{
Set &other = compound.mSet;
qboolean result = qfalse;
if ( mSet.size() == other.size() )
{
for
( Set::iterator itSet = mSet.begin(), itOther = other.begin()
; itSet != mSet.end()
//&& itOther != other.end() // assumed since mSet.size() == other.size()
&& (*itSet) == (*itOther)
; itSet++, itOther++
);
result = qboolean( itSet == mSet.end() );
}
return result;
}
#endif // _IMMERSION

View File

@@ -0,0 +1,54 @@
#ifndef FF_MULTICOMPOUND_H
#define FF_MULTICOMPOUND_H
//#include "common_headers.h"
#include "ff_MultiEffect.h"
////-------------
/// MultiCompound
//-----------------
// MultiCompound is a container for MultiEffect pointers.
// It is not a single, complex effect and should not be treated as such.
//
class MultiCompound
{
public:
typedef set<MultiEffect*> Set;
protected:
Set mSet;
public:
MultiCompound()
: mSet()
{}
MultiCompound( Set &compound )
: mSet()
{
Add( compound );
}
Set& GetSet() { return mSet; }
qboolean Add( MultiEffect *Compound );
qboolean Add( Set &compound );
// CImmEffect iterations
qboolean Start();
qboolean Stop();
qboolean ChangeDuration( DWORD Duration );
qboolean ChangeGain( DWORD Gain );
// Utilities
qboolean IsEmpty() { return qboolean( mSet.size() == 0 ); }
qboolean operator == ( MultiCompound &compound );
qboolean operator != ( MultiCompound &compound )
{
return qboolean( !( (*this) == compound ) );
}
// Other iterations
qboolean IsPlaying();
qboolean EnsurePlaying();
};
#endif // FF_MULTICOMPOUND_H

281
code/ff/ff_MultiEffect.cpp Normal file
View File

@@ -0,0 +1,281 @@
#include "common_headers.h"
#ifdef _IMMERSION
////--------------------------
/// MultiEffect::GetStartDelay
//------------------------------
// Determines the shortest start delay.
//
qboolean MultiEffect::GetStartDelay( DWORD &StartDelay )
{
StartDelay = MAXDWORD;
qboolean result = qtrue;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
DWORD CurrentStartDelay;
CImmEffect* pIE = GetContainedEffect( i );
if ( pIE
&& pIE->GetStartDelay( CurrentStartDelay )
){
StartDelay = Min( StartDelay, CurrentStartDelay );
}
else
{
result = qfalse;
}
}
return qboolean
( result
&& max > 0
);
}
////------------------------
/// MultiEffect::GetDelayEnd
//----------------------------
// Computes end of earliest start delay. Compare this value with ::GetTickCount()
// to determine if any component waveform started playing on the device.
//
qboolean MultiEffect::GetDelayEnd( DWORD &DelayEnd )
{
DelayEnd = MAXDWORD;
qboolean result = qtrue;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
DWORD StartDelay;
CImmEffect* pIE = GetContainedEffect( i );
if ( pIE
&& pIE->GetStartDelay( StartDelay )
){
DelayEnd = Min( DelayEnd, StartDelay + pIE->m_dwLastStarted );
}
else
{
result = qfalse;
}
}
return qboolean
( result
&& max > 0
);
}
////---------------------------
/// MultiEffect::ChangeDuration
//-------------------------------
// Analogous to CImmEffect::ChangeDuration. Changes duration of all component effects.
// Returns false if any effect returns false. Attempts to change duration of all effects
// regardless of individual return values.
//
qboolean MultiEffect::ChangeDuration( DWORD Duration )
{
DWORD CurrentDuration;
qboolean result = GetDuration( CurrentDuration );
if ( result )
{
DWORD RelativeDuration = Duration - CurrentDuration;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
IMM_ENVELOPE Envelope = {0};
CImmEffect* pIE = GetContainedEffect( i );
result &= qboolean
( pIE
&& pIE->GetDuration( CurrentDuration )
&& pIE->ChangeDuration( CurrentDuration + RelativeDuration )
&& ( !pIE->GetEnvelope( &Envelope )
|| ( Envelope.dwAttackTime = ( CurrentDuration ? (DWORD)((float)Envelope.dwAttackTime * (float)Duration / (float)CurrentDuration) : 0 )
, Envelope.dwFadeTime = ( CurrentDuration ? (DWORD)((float)Envelope.dwFadeTime * (float)Duration / (float)CurrentDuration) : 0 )
, pIE->ChangeEnvelope( &Envelope )
)
)
);
}
result &= qboolean( max > 0 );
}
return result;
}
////-----------------------
/// MultiEffect::ChangeGain
//---------------------------
// Analogous to CImmEffect::ChangeGain. Changes gain of all component effects.
// Returns false if any effect returns false. Attempts to change gain of all effects
// regardless of individual return values.
//
qboolean MultiEffect::ChangeGain( DWORD Gain )
{
DWORD CurrentGain;
qboolean result = GetGain( CurrentGain );
if ( result )
{
DWORD RelativeGain = Gain - CurrentGain;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
CImmEffect* pIE = GetContainedEffect( i );
result &= qboolean
( pIE
&& pIE->GetGain( CurrentGain )
&& pIE->ChangeGain( CurrentGain + RelativeGain )
);
}
result &= qboolean( max > 0 );
}
return result;
}
////----------------------
/// MultiEffect::GetStatus
//--------------------------
// Analogous to CImmEffect::GetStatus. ORs all status flags from all component effects.
// Returns false if any effect returns false. Attempts to get status of all effects
// regardless of individual return values.
//
qboolean MultiEffect::GetStatus( DWORD &Status )
{
Status = 0;
qboolean result = qtrue;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
DWORD CurrentStatus;
CImmEffect* pIE = GetContainedEffect( i );
if ( pIE
&& pIE->GetStatus( &CurrentStatus )
){
Status |= CurrentStatus;
}
else
{
result = qfalse;
}
}
return qboolean
( result
&& max > 0
);
}
qboolean MultiEffect::ChangeStartDelay( DWORD StartDelay )
{
DWORD CurrentStartDelay;
qboolean result = GetStartDelay( CurrentStartDelay );
if ( result )
{
DWORD RelativeStartDelay = StartDelay - CurrentStartDelay;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
CImmEffect* pIE = GetContainedEffect( i );
result &= qboolean
( pIE
&& pIE->GetStartDelay( CurrentStartDelay )
&& pIE->ChangeStartDelay( CurrentStartDelay + RelativeStartDelay )
);
}
result &= qboolean( max > 0 );
}
return result;
}
qboolean MultiEffect::GetDuration( DWORD &Duration )
{
Duration = 0;
qboolean result = qtrue;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
DWORD CurrentDuration;
CImmEffect* pIE = GetContainedEffect( i );
if ( pIE
&& pIE->GetDuration( CurrentDuration )
){
Duration = Max( Duration, CurrentDuration );
}
else
{
result = qfalse;
}
}
return qboolean
( result
&& max > 0
);
}
qboolean MultiEffect::GetGain( DWORD &Gain )
{
Gain = 0;
qboolean result = qtrue;
int i,max;
for
( i = 0, max = GetNumberOfContainedEffects()
; i < max
; i++
){
DWORD CurrentGain;
CImmEffect* pIE = GetContainedEffect( i );
if ( pIE
&& pIE->GetGain( CurrentGain )
){
Gain = Max( Gain, CurrentGain );
}
else
{
result = qfalse;
}
}
return qboolean
( result
&& max > 0
);
}
#endif // _IMMERSION

59
code/ff/ff_MultiEffect.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef MULTIEFFECT_H
#define MULTIEFFECT_H
//#include "common_headers.h"
//#include "ifc.h"
////-----------
/// MultiEffect
//---------------
// CImmCompoundEffect makes no assumption that its contained effects form a more
// complex, single effect. MultiEffect makes this assumption and provides member
// functions available in CImmEffect to operate on this "complex" effect.
//
// Do not instantiate. (Do not call constructor)
// Instead, cast existing CImmCompoundEffect* to MultiEffect*
// Utility functions are specific to the needs of this system.
//
class MultiEffect : public CImmCompoundEffect
{
public:
// dummy constructor
MultiEffect() : CImmCompoundEffect( NULL, 0, NULL ) {} // Never call (cast instead)
// CImmEffect extensions
qboolean GetStatus( DWORD &Status );
qboolean GetStartDelay( DWORD &StartDelay );
qboolean GetDuration( DWORD &Duration );
qboolean GetGain( DWORD &Gain );
qboolean ChangeDuration( DWORD Duration );
qboolean ChangeGain( DWORD Gain );
qboolean ChangeStartDelay( DWORD StartDelay );
// utility functions
qboolean GetDelayEnd( DWORD &DelayEnd );
qboolean IsBeyondStartDelay()
{
DWORD DelayEnd;
return qboolean
( GetDelayEnd( DelayEnd )
&& DelayEnd < ::GetTickCount() // Does not account for counter overflow.
);
}
qboolean IsPlaying()
{
DWORD Status;
return qboolean( GetStatus( Status ) && (Status & IMM_STATUS_PLAYING) );
}
// CImmCompoundEffect overrides
qboolean Start( DWORD dwIterations = IMM_EFFECT_DONT_CHANGE, DWORD dwFlags = 0 )
{
return qboolean
( IsBeyondStartDelay()
&& CImmCompoundEffect::Start( dwIterations, dwFlags )
);
}
};
#endif // MULTIEFFECT_H

140
code/ff/ff_MultiSet.cpp Normal file
View File

@@ -0,0 +1,140 @@
#include "common_headers.h"
#ifdef _IMMERSION
#include "..\win32\win_local.h"
////----------------
/// FFMultiSet::Init
//--------------------
// Initializes all attached force feedback devices. An empty FFSet is created
// for each device. Each device will have its own copy of whatever .ifr file
// set 'config' specifies.
//
// Always pair with clear()
//
qboolean FFMultiSet::Init( FFSystem::Config &config )
{
mConfig = &config;
#ifdef FF_PRINT
//Com_Printf( "Feedback devices:\n" );
#endif
HINSTANCE hInstance = (HINSTANCE)g_wv.hInstance;
HWND hWnd = (HWND)g_wv.hWnd;
mDevices = new CImmDevices;
if ( mDevices && mDevices->CreateDevices( hInstance, hWnd ) )
{
for
( int i = 0
; i < mDevices->GetNumDevices()
; i++
){
FFSet *ffSet = NULL;
ffSet = new FFSet( config, mDevices->GetDevice( i ) );
if ( ffSet )
{
#ifdef FF_PRINT
char ProductName[ FF_MAX_PATH ];
*ProductName = 0;
mDevices->GetDevice( i )->GetProductName( ProductName, FF_MAX_PATH - 1 );
Com_Printf( "%d) %s\n", i, ProductName );
#endif
mSet.push_back( ffSet );
}
}
}
return qboolean( mSet.size() );
}
////------------------------------
/// FFMultiSet::GetRegisteredNames
//----------------------------------
//
//
qboolean FFMultiSet::GetRegisteredNames( TNameTable &NameTable )
{
for
( int i = 0
; i < mSet.size()
; i++
){
mSet[ i ]->GetRegisteredNames( NameTable );
}
return qtrue;
}
////-------------------
/// FFMultiSet::StopAll
//-----------------------
// Stops all effects in every FFSet.
// Returns qfalse if any return false.
//
qboolean FFMultiSet::StopAll()
{
qboolean result = qtrue;
for
( int i = 0
; i < mSet.size()
; i++
){
result &= mSet[ i ]->StopAll();
}
return result;
}
////-----------------
/// FFMultiSet::clear
//---------------------
// Cleans up.
//
void FFMultiSet::clear()
{
mConfig = NULL;
for
( int i = 0
; i < mSet.size()
; i++
){
DeletePointer( mSet[ i ] );
}
mSet.clear();
DeletePointer( mDevices );
}
#ifdef FF_CONSOLECOMMAND
void FFMultiSet::GetDisplayTokens( TNameTable &Tokens )
{
FFSet::GetDisplayTokens( Tokens );
}
////-------------------
/// FFMultiSet::Display
//-----------------------
//
//
void FFMultiSet::Display( TNameTable &Unprocessed, TNameTable &Processed )
{
for
( int i = 0
; i < mSet.size()
; i++
){
TNameTable Temp1, Temp2;
Temp1.clear();
Temp2.clear();
Temp1.insert( Temp1.begin(), Processed.begin(), Processed.end() );
mSet[ i ]->Display( Temp1, Temp2 );
}
}
#endif // FF_CONSOLECOMMAND
#endif // _IMMERSION

43
code/ff/ff_MultiSet.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef FF_MULTISET_H
#define FF_MULTISET_H
#include "ff_ffset.h"
//===[FFMultiSet]=====================================================/////////////
//
// A collection class of FFSet objects. These functions generally
// iterate over the entire set of FFSets, performing the same operation
// on all contained FFSets.
//
//====================================================================/////////////
class FFMultiSet
{
public:
typedef vector<FFSet*> Set;
protected:
FFConfigParser *mConfig;
Set mSet;
CImmDevices *mDevices;
public:
qboolean Init( FFConfigParser &config );
// qboolean Lookup( set<MultiEffect*> &effect, const char *name );
qboolean GetRegisteredNames( TNameTable &NameTable );
qboolean StopAll();
void clear();
//
// Optional
//
#ifdef FF_ACCESSOR
Set& GetSets() { return mSet; }
CImmDevices* GetDevices() { return mDevices; }
#endif
#ifdef FF_CONSOLECOMMAND
void Display( TNameTable &Unprocessed, TNameTable &Processed );
static void GetDisplayTokens( TNameTable &Tokens );
#endif
};
#endif // FF_MULTISET_H

287
code/ff/ff_console.cpp Normal file
View File

@@ -0,0 +1,287 @@
/*
* Stubs to allow linking with FF_ fnuctions declared.
* Brian Osman
*/
//JLFRUMBLE includes modified to avoid typename collision field_t MPSKIPPED
#ifdef _JK2MP
#include "../namespace_begin.h"
#endif
#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
#include "../client/keycodes.h"
//#include "../client/client.h"
#include "../client/fffx.h"
#include "../win32/win_input.h"
#ifdef _JK2MP
#include "../namespace_end.h"
#endif
void FF_StopAll(void)
{
Com_Printf("FF_StopAll: Please implement.\n");
// Do nothing
}
void FF_Stop(ffFX_e effect)
{
Com_Printf("FF_Stop: Please implement fffx_id = %i\n",effect);
// Do nothing
}
void FF_EnsurePlaying(ffFX_e effect)
{
Com_Printf("FF_EnsurePlaying: Please implement fffx_id = %i\n",effect);
// Do nothing
}
void FF_Play(ffFX_e effect)
{
int s; // script id
static int const_rumble[2] = {-1, -1}; // script id for constant rumble
int client;
// super huge switch for rumble effects
switch(effect)
{
case fffx_AircraftCarrierTakeOff:
case fffx_BasketballDribble:
case fffx_CarEngineIdle:
case fffx_ChainsawIdle:
case fffx_ChainsawInAction:
case fffx_DieselEngineIdle:
case fffx_Jump:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 50000, 10000, 200);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Land:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 50000, 10000, 200);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_MachineGun:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 56000, 20000, 230);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Punched:
case fffx_RocketLaunch:
case fffx_SecretDoor:
case fffx_SwitchClick: // used by saber
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
IN_AddRumbleState(s, 30000, 10000, 120);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_WindGust:
case fffx_WindShear:
case fffx_Pistol:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 50000, 10000, 200);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Shotgun:
case fffx_Laser1:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 25000, 25000, 75);
IN_AddRumbleState(s, 0, 0, 15);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Laser2:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 20000, 20000, 75);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Laser3:
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
IN_AddRumbleState(s, 35000, 35000, 100);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_Laser4:
case fffx_Laser5:
case fffx_Laser6:
case fffx_OutOfAmmo:
case fffx_LightningGun:
case fffx_Missile:
case fffx_GatlingGun:
s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
if (s != -1)
{
IN_AddRumbleState(s, 39000, 0, 220);
IN_AddRumbleState(s, 0, 0, 10);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_ShortPlasma:
case fffx_PlasmaCannon1:
case fffx_PlasmaCannon2:
case fffx_Cannon:
case fffx_FallingShort:
case fffx_FallingMedium:
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
IN_AddRumbleState(s, 25000,10000, 230);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_FallingFar:
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
IN_AddRumbleState(s, 32000,10000, 230);
IN_ExecuteRumbleScript(s);
}
break;
case fffx_StartConst:
client = 0;
if(const_rumble[client] == -1)
{
const_rumble[client] = IN_CreateRumbleScript(IN_GetMainController(), 4, true);
if (const_rumble[client] != -1)
{
IN_AddEffectFade4(const_rumble[client], 0,0, 50000, 50000, 1000);
//IN_AddRumbleState(const_rumble[client], 40000, 40000, 300);
//IN_AddEffectFade4(const_rumble[client], 50000,50000, 0, 0, 1000);
IN_ExecuteRumbleScript(const_rumble[client]);
}
}
break;
case fffx_StopConst:
client = 0;
if (const_rumble[client] == -1)
return;
IN_KillRumbleScript(const_rumble[client]);
const_rumble[client] = -1;
break;
default:
Com_Printf("No rumble script is defined for fffx_id = %i\n",effect);
break;
}
}
/*********
FF_XboxShake
intensity - speed of rumble
duration - length of rumble
*********/
#define FF_SH_MIN_MOTOR_SPEED 25000
#define FF_SH_MOTOR_SPEED_MODIFIER (65535 - FF_SH_MIN_MOTOR_SPEED)
void FF_XboxShake(float intensity, int duration)
{
int s;
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
int speed;
// figure out the speed
speed = (FF_SH_MIN_MOTOR_SPEED) + (FF_SH_MOTOR_SPEED_MODIFIER * intensity);
// Add the state and execute
IN_AddRumbleState(s, speed, speed, duration);
IN_ExecuteRumbleScript(s);
}
}
/*********
FF_XboxDamage
damage - Amount of damage
xpos - x position for the damage ( -1.0 - 1.0 )
The following function various the rumble based upon
the amount of damage and the position of the damage.
*********/
#define FF_DA_MIN_MOTOR_SPEED 20000 // use this to vary the minimum intensity
#define FF_DA_MOTOR_SPEED_MODIFIER (65535 - FF_DA_MIN_MOTOR_SPEED)
void FF_XboxDamage(int damage, float xpos)
{
int s;
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
int leftMotorSpeed;
int rightMotorSpeed;
int duration;
float per;
duration = 175;
// how much damage?
if(damage > 100)
{
per = 1.0;
}
else
{
per = damage/100;
}
if(xpos >= -0.2 && xpos <= 0.2) // damge to center
{
leftMotorSpeed = rightMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per);
}
else if(xpos > 0.2) // damage to right
{
rightMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per);
leftMotorSpeed = 0;
}
else // damage to left
{
leftMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per);;
rightMotorSpeed = 0;
}
// Add the state and execute
IN_AddRumbleState(s, leftMotorSpeed, rightMotorSpeed, duration);
IN_ExecuteRumbleScript(s);
}
}
void FF_XboxSaberRumble( void )
{
int s;
s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
if (s != -1)
{
// Add the state and execute
IN_AddRumbleState(s, 55000, 55000, 100);
IN_ExecuteRumbleScript(s);
}
}

356
code/ff/ff_ffset.cpp Normal file
View File

@@ -0,0 +1,356 @@
#include "common_headers.h"
#ifdef _IMMERSION
//#include "ff.h"
//#include "ff_ffset.h"
//#include "ff_compound.h"
//#include "ff_system.h"
extern cvar_t *ff_developer;
#ifdef FF_DELAY
extern cvar_t *ff_delay;
#endif
extern FFSystem gFFSystem;
FFSet::FFSet( FFConfigParser &ConfigParser, CImmDevice *Device )
: mParser( ConfigParser )
, mDevice( Device )
, mInclude()
, mIncludePath()
{
const char *setname = mParser.GetFFSet( mDevice );
if ( setname )
{
TProject temp;
mInclude.push_back( temp );
mIncludePath.push_back( setname );
InitIncludes( setname );
}
}
FFSet::~FFSet()
{
for
( TInclude::iterator itInclude = mInclude.begin()
; itInclude != mInclude.end()
; itInclude++
){
for
( TProject::iterator itProject = (*itInclude).begin()
; itProject != (*itInclude).end()
; itProject++
){
DeletePointer( (*itProject).second );
}
}
}
void FFSet::InitIncludes( const char *setname )
{
FFConfigParser::TInclude &include = mParser.GetIncludes( setname );
for // each include listed in config file
( int i = 0
; i < include.size()
; i++
){
for // each include entered into current list
( unsigned int j = 0
; j < mIncludePath.size()
; j++
){
if ( include[ i ] == mIncludePath[ j ] ) // exists in current list
break;
}
if ( j == mIncludePath.size() ) // does not exist in current list
{
TProject temp;
mInclude.push_back( temp );
mIncludePath.push_back( include[ i ] );
InitIncludes( include[ i ].c_str() ); // recurse
}
}
}
MultiEffect* FFSet::Register( const char *path, qboolean create )
{
char outpath[ FF_MAX_PATH ];
MultiEffect* effect = NULL;
if ( FS_VerifyName( "FFSet::Register", path, outpath ) )
{
for // each included set
( int i = 0
; i < mInclude.size() && !effect
; i++
){
char setpath[ FF_MAX_PATH ], *afterincludepath;
// need to use explicit path if provided.
sprintf( setpath, "%s/%s", mIncludePath[ i ].c_str(), UncommonDirectory( path, mIncludePath[ i ].c_str() ) );
afterincludepath = setpath + mIncludePath[ i ].length() + 1;
for // each possible file/effectname combination
( int separator = _rcpos( afterincludepath, '/' )
; separator >= 0 && !effect
; separator = _rcpos( afterincludepath, '/', separator )
){
CImmProject *immProject;
char temp[4];
temp[0] = 0;
afterincludepath[separator] = 0;
if ( stricmp( afterincludepath + separator - 4, ".ifr" ) )
{
memcpy( temp, afterincludepath + separator + 1, 4 );
sprintf( afterincludepath + separator, ".ifr" );
}
immProject = NULL;
TProject::iterator itProject = mInclude[ i ].find( afterincludepath );
if ( itProject != mInclude[ i ].end() )
{
immProject = (*itProject).second;
}
else if ( create )
{
void *buffer = LoadFile( setpath );
if ( buffer )
{
immProject = new CImmProject;
if ( immProject )
{
if ( !immProject->LoadProjectFromMemory( buffer, mDevice ) )
{
DeletePointer( immProject );
#ifdef FF_PRINT
if ( ff_developer->integer )
Com_Printf( "...Corrupt or invalid file: %s\n", setpath );
}
else
{
if ( ff_developer->integer )
Com_Printf( "...Adding file \"%s\"\n", setpath );
#endif FF_PRINT
}
}
FS_FreeFile( buffer );
}
mInclude[ i ][ afterincludepath ] = immProject;
}
if ( temp[ 0 ] )
{
afterincludepath[ separator ] = '/';
memcpy( afterincludepath + separator + 1, temp, 4 );
}
if ( immProject )
{
effect = (MultiEffect*)immProject->GetCreatedEffect( afterincludepath + separator + 1 );
if ( !effect && create )
{
effect = (MultiEffect*)immProject->CreateEffect( afterincludepath + separator + 1, mDevice, IMM_PARAM_NODOWNLOAD );
#ifdef FF_DELAY
// Delay the effect (better sound synchronization)
if ( effect
&& ff_delay
//&& *ff_delay
){
effect->ChangeStartDelay( ff_delay->integer );
}
#endif // FF_DELAY
}
}
}
}
}
return effect;
}
qboolean FFSet::StopAll( void )
{
for
( TInclude::iterator itInclude = mInclude.begin()
; itInclude != mInclude.end()
; itInclude++
){
for
( TProject::iterator itProject = (*itInclude).begin()
; itProject != (*itInclude).end()
; itProject++
){
if ( (*itProject).second )
(*itProject).second->Stop();
}
}
return qtrue;
}
void FFSet::GetRegisteredNames( TNameTable &NameTable )
{
FFSystem::Handle ffHandle = gFFSystem.GetHandles();
for
( int IncludeIndex = 0
; IncludeIndex < mInclude.size()
; IncludeIndex++
){
for
( TProject::iterator itProject = mInclude[ IncludeIndex ].begin()
; itProject != mInclude[ IncludeIndex ].end()
; itProject++
){
char effectname[ FF_MAX_PATH ];
int i;
if ( !(*itProject).second )
continue;
i = 0;
for
( MultiEffect *Effect = (MultiEffect*)(*itProject).second->GetCreatedEffect( i )
; Effect
; Effect = (MultiEffect*)(*itProject).second->GetCreatedEffect( ++i )
){
sprintf( effectname, "%s/%s/%s", mIncludePath[ IncludeIndex ].c_str(), (*itProject).first.c_str(), Effect->GetName() );
for
( int i = 0
; i < ffHandle.size()
; i++
){
ChannelCompound::Set &compound = ffHandle[ i ].GetSet();
if
( NameTable[ i ].length() == 0
&& compound.find( Effect ) != compound.end()
){
NameTable[ i ] = effectname;
}
}
}
}
}
}
////////////////////////////////////////////////
#ifdef FF_CONSOLECOMMAND
void FFSet::GetDisplayTokens( TNameTable &Tokens )
{
if ( ff_developer->integer )
{
Tokens.push_back( "order" );
Tokens.push_back( "files" );
}
}
void FFSet::Display( TNameTable &Unprocessed, TNameTable &Processed )
{
for
( TNameTable::iterator itName = Unprocessed.begin()
; itName != Unprocessed.end()
;
){
if ( stricmp( "order", (*itName).c_str() ) == 0 )
{
if ( ff_developer->integer )
DisplaySearchOrder();
//else
// Com_Printf( "\"order\" only available when ff_developer is set\n" );
Processed.push_back( *itName );
itName = Unprocessed.erase( itName );
}
else
if ( stricmp( "files", (*itName).c_str() ) == 0 )
{
if ( ff_developer->integer )
DisplayLoadedFiles();
//else
// Com_Printf( "\"files\" only available when ff_developer is set\n" );
Processed.push_back( *itName );
itName = Unprocessed.erase( itName );
}
else
{
itName++;
}
}
}
void FFSet::DisplaySearchOrder( void )
{
char ProductName[ FF_MAX_PATH ];
*ProductName = 0;
mDevice->GetProductName( ProductName, FF_MAX_PATH - 1 );
Com_Printf( "[search order] -\"%s\"\n", ProductName );
for
( int i = 0
; i < mInclude.size()
; i++
){
Com_Printf( "%d) %s\n", i, mIncludePath[ i ].c_str() );
}
}
void FFSet::DisplayLoadedFiles( void )
{
int total = 0;
#ifdef _DEBUG
int nulltotal = 0; // Variable to indicate how bad my algorithm is
#endif
char ProductName[ FF_MAX_PATH ];
*ProductName = 0;
mDevice->GetProductName( ProductName, FF_MAX_PATH - 1 );
Com_Printf( "[loaded files] -\"%s\"\n", ProductName );
for
( int i = 0
; i < mInclude.size()
; i++
){
for
( TProject::iterator itProject = mInclude[ i ].begin()
; itProject != mInclude[ i ].end()
; itProject++
){
if ( (*itProject).second )
{
++total;
Com_Printf( "%s/%s\n", mIncludePath[ i ].c_str(), (*itProject).first.c_str() );
}
#ifdef _DEBUG
else
{
++nulltotal;
Com_Printf( "%s/%s [null]\n", mIncludePath[ i ].c_str(), (*itProject).first.c_str() );
}
#endif
}
}
Com_Printf( "Total: %d files\n", total );
#ifdef _DEBUG
Com_Printf( "Total: %d null files\n", nulltotal );
#endif
}
#endif // FF_CONSOLECOMMAND
#endif // _IMMERSION

64
code/ff/ff_ffset.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef FFSET_H
#define FFSET_H
//#include "ff_ConfigParser.h"
//#include "ff_utils.h"
//#include "ff_compound.h"
//class MultiEffect;
//#include "ifc.h"
//class CImmDevice;
//class CImmProject;
#include "ff_MultiEffect.h"
class FFSet
{
//
// Types
//
public:
typedef map<string, CImmProject*> TProject;
typedef vector<TProject> TInclude;
typedef vector<string> TIncludePath;
//
// Variables
//
protected:
TInclude mInclude;
TIncludePath mIncludePath;
CImmDevice *mDevice;
FFConfigParser &mParser;
//
// Functions
//
public:
FFSet( FFConfigParser &ConfigParser, CImmDevice *Device );
~FFSet();
MultiEffect* Register( const char *path, qboolean create = qtrue );
void GetRegisteredNames( TNameTable &NameTable );
qboolean StopAll( void );
protected:
void InitIncludes( const char *setname = NULL );
//
// Optional
//
#ifdef FF_ACCESSOR
public:
CImmDevice* GetDevice( void ) { return mDevice; }
#endif
#ifdef FF_CONSOLECOMMAND
public:
void Display( TNameTable &Unprocessed, TNameTable &Processed );
void DisplaySearchOrder( void );
void DisplayLoadedFiles( void );
static void GetDisplayTokens( TNameTable &Tokens );
#endif
};
#endif // FFSET_H

24
code/ff/ff_local.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef FF_LOCAL_H
#define FF_LOCAL_H
#define FF_ACCESSOR
#define FF_API_VERSION 1
// Better sound synchronization
// This is default value for cvar ff_delay. User may tweak this.
#define FF_DELAY "40"
// Default: all channels output to primary device
#define FF_CHANNEL "0,0;1,0;2,0;3,0;4,0;5,0"
// Optional system features
#define FF_PRINT
#ifdef FF_PRINT
#define FF_CONSOLECOMMAND
#endif
// (end) Optional system features
#include "..\game\q_shared.h" // includes ff_public.h
#include "..\qcommon\qcommon.h"
#define FF_MAX_PATH MAX_QPATH
#endif // FF_LOCAL_H

43
code/ff/ff_public.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef __FF_PUBLIC_H
#define __FF_PUBLIC_H
#define FF_HANDLE_NULL 0
#define FF_CLIENT_LOCAL (-2)
#define FF_CLIENT( client ) (FF_CLIENT_LOCAL - client)
typedef int ffHandle_t;
/*
enum FFChannel_e
{ FF_CHANNEL_WEAPON
, FF_CHANNEL_MENU
, FF_CHANNEL_TOUCH
, FF_CHANNEL_DAMAGE
, FF_CHANNEL_VEHICLE
, FF_CHANNEL_MAX
};
*/
#define FF_CHANNEL_WEAPON 0
#define FF_CHANNEL_MENU 1
#define FF_CHANNEL_TOUCH 2
#define FF_CHANNEL_DAMAGE 3
#define FF_CHANNEL_BODY 4
#define FF_CHANNEL_FORCE 5
#define FF_CHANNEL_FOOT 6
#define FF_CHANNEL_MAX 7
#ifdef _FF
/*
inline qboolean operator &= ( qboolean &lvalue, qboolean rvalue )
{
lvalue = qboolean( (int)lvalue && (int)rvalue );
return lvalue;
}
*/
#include "../ff/ff.h" // basic system functions
#include "../ff/ff_snd.h" // sound system similarities
#endif // _FF
#endif // __FF_PUBLIC_H

503
code/ff/ff_snd.cpp Normal file
View File

@@ -0,0 +1,503 @@
#include "common_headers.h"
#ifdef _IMMERSION
#include "ff_snd.h"
#include "ff.h"
extern FFSystem gFFSystem;
#define FF_GAIN_STEP 500
//
// Internal data structures
//
// This whole system should mirror snd_dma.cpp to some degree.
// Right now, not much works.
/*
template<typename T>
static T RelativeDistance( T Volume, T Min, T Max )
{
if ( Min == Max )
if ( Volume < Min )
return 0.f;
else
return 1.f;
return (Volume - Min) / (Max - Min);
};
template<typename T>
int Round( T value, int mod )
{
int intval = (int)value;
int intmod = intval % mod;
int roundup = intmod >= mod / 2;
return
( intval
? roundup
? intval + mod - intmod
: intval - intmod
: roundup
? mod
: 0
);
}
*/
class SndForce
{
public:
ffHandle_t mHandle;
int mRefs;
qboolean mPlaying;
// int mEntNum;
// vec3_t mOrigin;
// struct SDistanceLimits
// { int min;
// int max;
// } mDistance;
public:
void zero()
{
mHandle = FF_HANDLE_NULL;
mRefs = 0;
mPlaying = qfalse;
// mEntNum = 0;
// mDistance.min = 0;
// mDistance.max = 0;
// mOrigin[0] = 1.f;
// mOrigin[1] = 0.f;
// mOrigin[2] = 0.f;
}
SndForce()
{
zero();
}
SndForce( const SndForce &other )
{
memcpy( this, &other, sizeof(SndForce) );
}
SndForce( ffHandle_t handle/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
: mHandle( handle )
, mRefs( 0 )
, mPlaying( qfalse )
// , mEntNum( entNum )
{
// mDistance.min = minDistance;
// mDistance.max = maxDistance;
// memcpy( mOrigin, origin, sizeof(mOrigin) );
}
void AddRef()
{
++mRefs;
}
void SubRef()
{
--mRefs;
}
qboolean Update( void ) const
{
return qboolean
( mRefs != 0
&& (ChannelCompound*)mHandle
);
}
/* int GetGain()
{
float distance = 1.f - GetRelativeDistance();
return distance == 0.f
? 10000
: Clamp<int>
( Round<int>
( distance * 10000
, FF_GAIN_STEP
)
, 0
, 10000
)
;
}
float GetRelativeDistance()
{
return !mRefs
? 1.f
: IsOrigin()
? 0.f
: RelativeDistance<float>
( sqrt
( mOrigin[0] * mOrigin[0]
+ mOrigin[1] * mOrigin[1]
+ mOrigin[2] * mOrigin[2]
)
, mDistance.min
, mDistance.max
) / mRefs
;
}
qboolean IsOrigin()
{
return qboolean
( !mOrigin[0]
&& !mOrigin[1]
&& !mOrigin[2]
);
}
void Respatialize( int entNum, const vec3_t origin )
{
extern vec3_t s_entityPosition[];
if ( mEntNum != entNum )
{
// Assumes all forces follow its entity and is centered on entity
mOrigin[0] = s_entityPosition[ entNum ][0] - origin[0];
mOrigin[1] = s_entityPosition[ entNum ][1] - origin[1];
mOrigin[2] = s_entityPosition[ entNum ][2] - origin[2];
}
else
{
memset( mOrigin, 0, sizeof(mOrigin) );
}
}*/
void operator += ( SndForce &other );
};
// Fancy comparator
struct SndForceLess : public less<SndForce>
{
bool operator() ( const SndForce &x, const SndForce &y )
{
return bool
(/* x.mEntNum < y.mEntNum
||*/x.mHandle < y.mHandle
// || x.mOrigin < y.mOrigin // uhhh... compare components
|| x.mPlaying < y.mPlaying
);
}
};
class LoopForce : public SndForce
{
public:
LoopForce(){}
LoopForce( const LoopForce &other )
{
memcpy( this, &other, sizeof(LoopForce) );
}
LoopForce( ffHandle_t handle/*int entNum, , const vec3_t origin, float maxDistance, float minDistance*/ )
: SndForce( handle/*, entNum, origin, maxDistance, minDistance*/ )
{}
void Add( ffHandle_t ff/*, int entNum, const vec3_t origin*/ );
// void Respatialize( int entNum, const vec3_t origin );
qboolean Update( void )
{
qboolean result = SndForce::Update();
mRefs = 0;
return result;
}
};
class SndForceSet
{
public:
typedef set<SndForce, SndForceLess> PendingSet;
typedef map<ffHandle_t, SndForce> ActiveSet;
ActiveSet mActive;
PendingSet mPending;
public:
void Add( ffHandle_t handle/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
const_cast <SndForce&> (*mPending.insert( SndForce( handle/*, entNum, origin, maxDistance, minDistance*/ ) ).first).AddRef();
}
qboolean Update( void );
/* void Respatialize( int entNum, const vec3_t origin )
{
for
( PendingSet::iterator itPending = mPending.begin()
; itPending != mPending.end()
; itPending++
){
(*itPending).Respatialize( entNum, origin );
}
}*/
};
class LoopForceSet
{
public:
typedef set<LoopForce, SndForceLess> PendingSet;
typedef map<ffHandle_t, LoopForce> ActiveSet;
ActiveSet mActive;
PendingSet mPending;
public:
void Add( ffHandle_t handle/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
const_cast <LoopForce&>(*mPending.insert( LoopForce( handle/*, entNum, origin, maxDistance, minDistance*/ ) ).first).AddRef();
}
qboolean Update( void );
/* void Respatialize( int entNum, const vec3_t origin )
{
for
( PendingSet::iterator itPending = mPending.begin()
; itPending != mPending.end()
; itPending++
){
(*itPending).Respatialize( entNum, origin );
}
}*/
};
class MasterForceSet
{
protected:
int mEntityNum;
// vec3_t mOrigin;
SndForceSet mSnd;
LoopForceSet mLoop;
public:
void Add( ffHandle_t handle/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
mSnd.Add( handle/*, entNum, origin, maxDistance, minDistance*/ );
}
void AddLoop( ffHandle_t handle/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
mLoop.Add( handle/*, entNum, origin, maxDistance, minDistance*/ );
}
/* void Respatialize( int entNum, const vec3_t origin )
{
memcpy( mOrigin, origin, sizeof(mOrigin) );
mEntityNum = entNum;
mSnd.Respatialize( entNum, origin );
mLoop.Respatialize( entNum, origin );
}
*/ void Update( void );
};
//
// ===================================================================================
//
static MasterForceSet _MasterForceSet;
void FF_AddForce( ffHandle_t ff/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
_MasterForceSet.Add( ff/*, entNum, origin, maxDistance, minDistance*/ );
}
void FF_AddLoopingForce( ffHandle_t ff/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ )
{
_MasterForceSet.AddLoop( ff/*, entNum, origin, maxDistance, minDistance*/ );
}
/*
void FF_Respatialize( int entNum, const vec3_t origin )
{
_MasterForceSet.Respatialize( entNum, origin );
}
*/
void FF_Update( void )
{
_MasterForceSet.Update();
}
//
// ===================================================================================
//
void MasterForceSet::Update()
{
mSnd.Update();
mLoop.Update();
}
////-----------------
/// LoopForce::Update
//---------------------
// Starts/Stops/Updates looping forces.
// Call once per frame after all looping forces have been added and respatialized.
//
qboolean LoopForceSet::Update()
{
ActiveSet::iterator itActive;
PendingSet::iterator itPending;
// Sum effects
ActiveSet active;
for
( itPending = mPending.begin()
; itPending != mPending.end()
; itPending++
){
if ( (const_cast <LoopForce&> (*itPending)).Update() )
{
active[ (*itPending).mHandle ] += const_cast <LoopForce&> (*itPending) ;
}
}
// Stop and remove unreferenced effects
for
( itActive = mActive.begin()
; itActive != mActive.end()
; //itActive++
){
if ( active.find( (*itActive).first ) != active.end() )
{
itActive++;
}
else
{
SndForce &sndForce = (*itActive).second;
FF_Stop( sndForce.mHandle );
itActive = mActive.erase( itActive );
}
}
// Decide whether to start or update
for
( itActive = active.begin()
; itActive != active.end()
; itActive++
){
SndForce &sndForce = mActive[ (*itActive).first ];
sndForce.mHandle = (*itActive).first;
if ( sndForce.mPlaying )
{
// Just update it
// if ( (*itActive).second.GetGain() != sndForce.GetGain() )
// {
// gFFSystem.ChangeGain( sndForce.mHandle, sndForce.GetGain() );
// }
}
else
{
// Update and start it
// gFFSystem.ChangeGain( sndForce.mHandle, sndForce.GetGain() );
FF_Play( sndForce.mHandle );
sndForce.mPlaying = qtrue;
}
}
mPending.clear();
return qtrue;
}
////-------------------
/// SndForceSet::Update
//-----------------------
//
//
qboolean SndForceSet::Update()
{
ActiveSet::iterator itActive;
PendingSet::iterator itPending;
/*
// Remove finished effects from active //and pending sets
for
( itActive = mActive.begin()
; itActive != mActive.end()
; //itActive++
){
if ( gFFSystem.IsPlaying( (*itActive).first ) )
{
++itActive;
}
else
{
#if( 0 )
for
( itPending = mPending.begin()
; itPending != mPending.end()
; itPending++
){
if
( (*itPending).mHandle == (*itActive).first
&& (*itPending).mPlaying
){
itPending = mPending.erase( itPending );
}
}
#endif
itActive = mActive.erase( itActive );
}
}
*/
// Sum effects
ActiveSet start;
for
( itPending = mPending.begin()
; itPending != mPending.end()
; itPending++
){
if ( (*itPending).Update() )
{
start[ (*itPending).mHandle ] += const_cast <SndForce&> (*itPending);
}
}
// Decide whether to start ( no updating one-shots )
for
( itActive = start.begin()
; itActive != start.end()
; itActive++
){
/* SndForce &sndForce = mActive[ (*itActive).first ];
sndForce.mHandle = (*itActive).first;
if ( (*itActive).second.GetGain() >= sndForce.GetGain() )
{
//gFFSystem.ChangeGain( sndForce.mHandle, sndForce.GetGain() );
FF_Start( sndForce.mHandle );
sndForce.mPlaying = qtrue;
}
*/ FF_Play( (*itActive).first );
}
mPending.clear();
return qfalse;
}
void SndForce::operator += ( SndForce &other )
{
/*
float dist = other.GetRelativeDistance();
if ( dist < 1.f )
{
float thisdist = GetRelativeDistance();
if ( thisdist < 1.f )
{
if ( dist == 0.f || thisdist == 0.f )
{
mOrigin[0] = 0.f;
mOrigin[1] = 0.f;
mOrigin[2] = 0.f;
}
else
{
// This is so shitty
mOrigin[0] *= dist;
mOrigin[1] *= dist;
mOrigin[2] *= dist;
}
}
else
{
memcpy( mOrigin, other.mOrigin, sizeof(mOrigin) );
}
*/
mRefs += other.mRefs;
// }
}
#endif // _IMMERSION

11
code/ff/ff_snd.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef FF_SND_H
#define FF_SND_H
#include "../ff/ff_public.h"
void FF_AddForce( ffHandle_t ff/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ );
void FF_AddLoopingForce( ffHandle_t ff/*, int entNum, const vec3_t origin, float maxDistance, float minDistance*/ );
//void FF_Respatialize( int entNum, const vec3_t origin );
void FF_Update( void );
#endif // FF_SND_H

151
code/ff/ff_system.cpp Normal file
View File

@@ -0,0 +1,151 @@
#include "common_headers.h"
#ifdef _IMMERSION
//#include "ff.h"
//#include "ff_ffset.h"
//#include "ff_compound.h"
//#include "ff_system.h"
extern cvar_t *ff_developer;
////--------------
/// FFSystem::Init
//------------------
//
//
qboolean FFSystem::Init( const char *channels )
{
// kludgy restart mechanism
typedef struct
{ TNameTable name;
vector<int> channel;
} TRestartInfo;
TRestartInfo restart;
if ( mInitialized )
{
restart.name.resize( mHandle.size(), "" );
restart.channel.resize( mHandle.size(), FF_CHANNEL_MAX );
mChannel.GetRegisteredNames( restart.name );
mHandle.GetFailedNames( restart.name );
mHandle.GetChannels( restart.channel );
Shutdown();
}
mHandle.Init();
if ( mConfig.Init( "fffx/fffx.cfg" ) // Process config file
&& mChannel.Init( mConfig, channels ) ) // Init devices
{
if ( restart.name.size() > 1 )
{
for
( int i = 1
; i < restart.name.size()
; i++
){ // ignore leading device-specific set name -- (may be switching devices)
Register( mConfig.RightOfSet( restart.name[ i ].c_str() ), restart.channel[ i ] );
}
}
else
ffShake = Register( "fffx/player/shake", FF_CHANNEL_BODY );
mInitialized = qtrue;
}
return mInitialized;
}
#ifdef FF_CONSOLECOMMAND
void FFSystem::GetDisplayTokens( TNameTable &Tokens )
{
FFChannelSet::GetDisplayTokens( Tokens );
if ( ff_developer->integer )
{
Tokens.push_back( "effects" );
}
}
void FFSystem::Display( TNameTable &Unprocessed, TNameTable &Processed )
{
for
( TNameTable::iterator itName = Unprocessed.begin()
; itName != Unprocessed.end()
;
){
if ( stricmp( "effects", (*itName).c_str() ) == 0 )
{
if ( ff_developer->integer )
{
Com_Printf( "[registered effects]\n" );
TNameTable EffectNames;
int total = 0;
Channel::Set &ffSet = mChannel.GetSets();
for
( int i = 0
; i < ffSet.size()
; i++
){
char ProductName[ FF_MAX_PATH ];
*ProductName = 0;
ffSet[ i ]->GetDevice()->GetProductName( ProductName, FF_MAX_PATH - 1 );
Com_Printf( "%s...\n", ProductName );
EffectNames.clear();
EffectNames.resize( mHandle.size(), "" );
ffSet[ i ]->GetRegisteredNames( EffectNames );
for
( int j = 1
; j < EffectNames.size()
; j++
){
if ( EffectNames[ j ].length() )
Com_Printf( "%3d) \"%s\" channel=%d\n", total++, EffectNames[ j ].c_str(), mHandle[ j ].GetChannel() );
}
}
EffectNames.clear();
EffectNames.resize( mHandle.size(), "" );
if ( mHandle.GetFailedNames( EffectNames ) )
{
Com_Printf( "Failed Registrants...\n" );
for
( int j = 1
; j < EffectNames.size()
; j++
){
if ( EffectNames[ j ].length() )
Com_Printf( "%3d) \"%s\" channel=%d\n", total++, EffectNames[ j ].c_str(), mHandle[ j ].GetChannel() );
}
}
}
//else
//{
// Com_Printf( "\"effects\" only available when ff_developer is set\n" );
//}
Processed.push_back( *itName );
itName = Unprocessed.erase( itName );
}
else
{
itName++;
}
}
mChannel.Display( Unprocessed, Processed );
}
#endif // FF_CONSOLECOMMAND
#endif // _IMMERSION

117
code/ff/ff_system.h Normal file
View File

@@ -0,0 +1,117 @@
#ifndef FF_SYSTEM_H
#define FF_SYSTEM_H
//#include "ff_utils.h"
//#include "ff_compound.h"
//#include "ff_ffset.h"
//#include "ff_configparser.h"
#include "ff_ConfigParser.h"
#include "ff_ChannelSet.h"
#include "ff_HandleTable.h"
//===[FFSystem]=======================================================/////////////
//
// The main system for a single user with multiple channels for
// multiple simultaneous devices. All this is factored and 'classy'
// with the intent to make it more readable and easy to track bugs.
//
// That's the intent, at least.
//
//====================================================================/////////////
class FFSystem
{
public:
typedef FFConfigParser Config;
typedef FFChannelSet Channel;
typedef FFHandleTable Handle;
protected:
Config mConfig;
Channel mChannel;
Handle mHandle;
qboolean mInitialized;
ffHandle_t ffShake;
public:
qboolean Init( const char *channels );
void Shutdown()
{
mInitialized = qfalse;
mHandle.clear();
mChannel.clear();
mConfig.Clear();
}
ffHandle_t Register( const char *name, int channel, qboolean notfound = qtrue, qboolean create = qtrue )
{
ffHandle_t result = FF_HANDLE_NULL;
if ( name && name[ 0 ] )
{
ChannelCompound compound( channel );
mChannel.Register( compound, name, create );
result = mHandle.Convert( compound, name, notfound );
}
return result;
}
qboolean StopAll()
{
return mChannel.StopAll();
}
const char* GetName( ffHandle_t ff )
{
return mHandle.GetName( ff );
}
qboolean Stop( ffHandle_t ff )
{
return mHandle[ ff ].Stop();
}
qboolean Play( ffHandle_t ff )
{
return mHandle[ ff ].Start();
}
qboolean EnsurePlaying( ffHandle_t ff )
{
return mHandle[ ff ].EnsurePlaying();
}
qboolean Shake( int intensity, int duration, qboolean ensure = qtrue )
{
ChannelCompound &Compound = mHandle[ ffShake ];
Compound.ChangeDuration( duration );
Compound.ChangeGain( intensity );
return ensure
? EnsurePlaying( ffShake )
: Compound.Start()
;
}
qboolean IsInitialized() { return mInitialized; }
qboolean IsPlaying( ffHandle_t ff )
{
return mHandle[ ff ].IsPlaying();
}
qboolean ChangeGain( ffHandle_t ff, DWORD gain )
{
return mHandle[ ff ].ChangeGain( gain );
}
//
// Optional
//
// qboolean Lookup( set<ffHandle_t> &result, const char *name )
// {
// set<MultiEffect*> effect;
// return
// mChannel.Lookup( effect, name )
// && mHandle.Lookup( result, effect, name );
// }
#ifdef FF_ACCESSOR
// Channel& GetChannels() { return mChannel; } // for CMD_FF_Info
Handle& GetHandles() { return mHandle; } // for CMD_FF_Info
#endif
#ifdef FF_CONSOLECOMMAND
void Display( TNameTable &Unprocessed, TNameTable &Processed );
void GetDisplayTokens( TNameTable &Tokens );
#endif
};
#endif // FF_SYSTEM_H

105
code/ff/ff_utils.cpp Normal file
View File

@@ -0,0 +1,105 @@
#include "common_headers.h"
#ifdef _IMMERSION
//#include "ff_utils.h"
extern cvar_t *ff_developer;
//
// Didn't know about strrchr. This is slightly different anyway.
//
int _rcpos( const char* string, char c, int pos )
{
int length = strlen( string );
length = ( pos >= 0 && pos < length ? pos : length );
for ( int i = length - 1; i >= 0; i-- )
if ( string[i] == c )
return i;
return -1;
}
void* LoadFile( const char *filename )
{
void *buffer;
int length = FS_ReadFile( filename, &buffer );
return length != -1 ? buffer : NULL;
}
const char *UncommonDirectory( const char *target, const char *comp )
{
const char *pos = target;
for
( int i = 0
; target[ i ] && comp[ i ] && target[ i ] == comp[ i ]
; i++
){
if ( target[ i ] == '/' )
pos = target + i + 1;
}
if ( !comp[ i ] && target[ i ] == '/' )
pos = target + i + 1;
else
if ( !target[ i ] && comp[ i ] == '/' )
pos = target + i;
return pos;
}
////-------
/// RightOf
//-----------
//
//
// Parameters:
//
// Returns:
//
const char* RightOf( const char *str, const char *str2 )
{
if ( !str || !str2 )
return NULL;
const char *s = str;
int len1 = strlen( str );
int len2 = strlen( str2 );
if ( (len2)
&& (len1 >= len2)
){
s = strstr( str, str2 );
if ( s )
{
if ( ((s == str) && (*(s + len2) == '/'))
|| ((*(s - 1) == '/') && (*(s + len2) == '/'))
){
s += len2 + 1;
}
}
}
return s ? s : str;
}
#ifdef FF_PRINT
void ConsoleParseError( const char *message, const char *line, int pos /*=0*/)
{
if ( ff_developer && ff_developer->integer )
{
Com_Printf( "Parse error: %s\n%s\n%*c\n", message, line, pos + 1, '^' );
}
}
qboolean FS_VerifyName( const char *src, const char *name, char *out, int maxlen )
{
return qtrue;
}
#endif // FF_PRINT
#endif // _IMMERSION

154
code/ff/ff_utils.h Normal file
View File

@@ -0,0 +1,154 @@
#ifndef FF_UTILS_H
#define FF_UTILS_H
//#include "ff_public.h"
template<typename Type>
inline Type Clamp( Type arg, Type min, Type max )
{;
if ( arg <= min )
return min;
else
if ( arg > max )
return max;
return arg;
}
template<typename Type>
inline Type Max( Type arg, Type arg2 )
{
if ( arg < arg2 )
return arg2;
return arg;
}
template<typename Type>
inline Type Min( Type arg, Type arg2 )
{
if ( arg > arg2 )
return arg2;
return arg;
}
template<typename Type>
inline Type InRange( Type arg, Type min, Type max, Type invalid )
{
if ( arg < min || arg > max )
return invalid;
return arg;
}
typedef vector<string> TNameTable;
int _rcpos( const char* string, char c, int pos = -1 );
void* LoadFile( const char *filename );
const char *UncommonDirectory( const char *target, const char *comp );
const char* RightOf( const char *str, const char *str2 );
template< class Type >
void DeletePointer( Type &Pointer, const char *String = 0 )
{
if ( Pointer )
{
#ifdef FF_PRINT
if ( String )
Com_Printf( "%s\n", String );
#endif
delete Pointer;
Pointer = NULL;
}
}
#ifdef FF_PRINT
void ConsoleParseError( const char *message, const char *line, int pos = 0 );
#endif
qboolean FS_VerifyName( const char *src, const char *name, char *out, int maxlen = FF_MAX_PATH );
//===[multimapIterator]================================================/////////////
//
// Convenience class for iterating through a multimap. It's not actually
// all that convenient :( It's slightly more intuitive than the
// actual multimap iteration logic.
//
//====================================================================/////////////
template< class T >
class multimapIterator
{
protected:
T::iterator mIt;
T &mMap;
T::key_type mKey;
public:
multimapIterator( T &map, T::key_type key )
: mMap( map )
, mKey( key )
{
mIt = mMap.find( mKey );
}
multimapIterator& operator ++ ()
{
if ( mIt != mMap.end() )
{
mIt++;
if ( (*mIt).first != mKey )
mIt = mMap.end();
}
return *this;
}
qboolean operator != ( T::iterator it )
{
return qboolean( mIt != it );
}
qboolean operator == ( T::iterator it )
{
return qboolean( mIt == it );
}
T::iterator operator * ()
{
return mIt; // must dereference twice to access first and second
}
T::iterator operator = ( T::iterator it )
{
mIt = it;
return mIt;
}
operator qboolean ()
{
return qboolean( mIt != mMap.end() );
}
};
/*
template< class T >
class multimapIteratorIterator
{
protected:
multimapIterator mIt;
public:
multimapIteratorIterator( T &map )
: mIt( map, map.begin() )
{
}
multimapIteratorIterator& operator ++ ()
{
for
( T::iterator last = *mIt
; mIt
; last = mIt, ++mIt
);
mIt = ++last;
return *this;
}
multimapIterator& operator * ()
{
return mIt;
}
};
*/
#endif // FF_UTILS_H