Descent3/lib/forcefeedback.h

441 lines
14 KiB
C
Raw Normal View History

/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
--- HISTORICAL COMMENTS FOLLOW ---
2024-04-16 18:56:40 +00:00
* $Logfile: /DescentIII/Main/lib/forcefeedback.h $
* $Revision: 15 $
* $Date: 7/28/99 3:23p $
* $Author: Kevin $
*
* Low-Level ForceFeedback header
*
* $Log: /DescentIII/Main/lib/forcefeedback.h $
*
2024-04-16 03:43:29 +00:00
* 15 7/28/99 3:23p Kevin
* Macintosh
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 14 4/16/99 8:28p Jeff
* moved placement of #endif
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 13 4/15/99 1:44a Jeff
* changes for linux compile
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 12 1/30/99 11:27p Jeff
* added immersion support
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 11 1/28/99 12:09p Jeff
* added force feedback to player shake...fixed spelling error in define
* for forcefeedback
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 10 1/13/99 6:48a Jeff
* made file linux friendly (removed dinput specific stuff to ifdef)
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 8 11/10/98 5:16p Jeff
* updated forcefeedback system...pretty complete now
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 7 11/06/98 7:00p Jeff
* first round of new force feedback installed
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 6 11/03/98 6:43p Jeff
* new low-level & high level Force Feedback system implemented, handles
* window losing focus, etc.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 5 10/12/98 3:49p Jeff
* struct changes
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 4 9/21/98 11:10a Jeff
* general update, new low level, small high level implementation
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 3 9/18/98 7:38p Jeff
* creation of low-level forcefeedback and beginning of high-level
* forcefeedback
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 2 9/15/98 12:05p Jeff
* initial creation of low-level forcefeedback
2024-04-16 18:56:40 +00:00
*
* $NoKeywords: $
*/
2024-04-16 03:43:29 +00:00
#ifndef __DDIO_FORCEFEEDBACK_H_
#define __DDIO_FORCEFEEDBACK_H_
#include <cstdint>
2024-04-16 03:43:29 +00:00
#include "pstypes.h"
#include "string.h"
2024-04-16 18:56:40 +00:00
#define kMAX_Str 80
#define kInfinite_Duration 0xFFFFFF
#define FF_USEENVELOPE 0x01
#define HZ_to_uS(hz) ((int)(1000000.0 / (double)(hz) + 0.5))
#define DDIO_FF_MAXEFFECTS 30
2024-04-16 03:43:29 +00:00
#if defined(WIN32)
2024-04-16 18:56:40 +00:00
// WINDOWS
2024-04-16 03:43:29 +00:00
#include "win/DirectX/dinput.h"
2024-04-16 18:56:40 +00:00
#define FF_DEGREES DI_DEGREES
#define FF_NOMINALMAX DI_FFNOMINALMAX
#define FF_SECONDS DI_SECONDS
#else
2024-04-16 18:56:40 +00:00
#define FF_DEGREES 360 // fake value
#define FF_NOMINALMAX 10000 // fake value
#define FF_SECONDS 1000 // fake value
2024-04-16 03:43:29 +00:00
#endif
2024-04-16 18:56:40 +00:00
#define FORCEPROJECT void *
enum tDevice {
2024-04-16 18:56:40 +00:00
kJoy1 = 0,
kJoy2,
kJoy3,
kJoy4,
kJoy5,
kJoy6,
kJoy7,
kJoy8,
kJoy9,
kJoy10,
kJoy11,
kJoy12,
kJoy13,
kJoy14,
kJoy15,
kJoy16,
kMaxJoy,
kMouse,
kKeyBoard,
kAllDevices
};
enum tJoyButtons {
2024-04-16 18:56:40 +00:00
kNoButton = -1,
kButton0 = 0,
kButton1,
kButton2,
kButton3,
kButton4,
kButton5,
kButton6,
kButton7,
kButton8,
kButton9,
kButton10,
kButton31 = 31,
kButtonMax
};
enum tDeviceMask {
2024-04-16 18:56:40 +00:00
kStick = 1 << 0,
kWheel = 1 << 1,
kGamePad = 1 << 2,
};
struct tFFJoyInfo {
2024-04-16 18:56:40 +00:00
int ButtonMask;
int AxisMask;
tDeviceMask DevType;
char Name[kMAX_Str];
};
enum tLoadEffect {
2024-04-16 18:56:40 +00:00
kDontPlayNow = 0,
kPlayNow,
kPlayNowIfModified,
};
enum tEffType {
2024-04-16 18:56:40 +00:00
kConstant = 0,
kRamp,
kCustom,
kWave_Square,
kWave_Sine,
kWave_Triangle,
kWave_SawUp,
kWave_SawDown,
kCondition_Spring,
kCondition_Damper,
kCondition_Inertia,
kCondition_Friction,
kMaxEffectSubTypes
};
struct tEffConstant {
int32_t Mag; // +- 10,000
};
struct tEffRamp {
int32_t Start; // +- 10,000
int32_t End; // +- 10,000
};
struct tEffWave {
2024-05-24 02:51:16 +00:00
uint32_t Mag; // 0 to 10,000
int32_t Offset; // +- 10,000
2024-05-24 02:51:16 +00:00
uint32_t Phase; // 0 to 35,999
uint32_t Period;
};
struct tEffCondition {
int32_t Offset; // +- 10,000
int32_t PositiveCoefficient; // +- 10,000
int32_t NegativeCoefficient; // +- 10,000
2024-05-24 02:51:16 +00:00
uint32_t PositiveSaturation; // 0 to 10,000
uint32_t NegativeSaturation; // 0 to 10,000
int32_t DeadBand; // 0 to 10,000
};
struct tEffCustom {
2024-04-16 18:56:40 +00:00
int Channels;
int Period;
int Samples;
int32_t *ForceData;
};
union tEffInfo {
2024-04-16 18:56:40 +00:00
tEffConstant Constant;
tEffRamp Ramp;
tEffWave Wave;
tEffCondition Condition;
tEffCustom Custom;
};
struct tEffEnvelope {
2024-05-24 02:51:16 +00:00
uint32_t AttackLevel;
uint32_t AttackTime;
uint32_t FadeLevel;
uint32_t FadeTime;
};
enum tEffAxis { kXAxisOnly, kYAxisOnly, kBothAxes };
struct tFFB_Effect {
2024-04-16 18:56:40 +00:00
int Flags;
tEffType Type;
// tEffInfo TypeInfo[2];
tEffInfo TypeInfo;
2024-05-24 02:51:16 +00:00
uint32_t Duration;
uint32_t Gain; // 0-10000 -- scales all magnitudes and envelope
uint32_t Period;
2024-04-16 18:56:40 +00:00
tEffAxis Axis;
tJoyButtons Trigger;
2024-05-24 02:51:16 +00:00
uint32_t TriggerRepeatTime;
int32_t Direction; // 0 to 360 deg.
2024-04-16 18:56:40 +00:00
tEffEnvelope Envelope;
};
2024-04-16 18:56:40 +00:00
extern bool ddForce_found; // a Force Feedback device was found
extern bool ddForce_enabled; // Force Feedback is ready and can be used
2024-04-16 03:43:29 +00:00
// ===================================================================
// Function Prototypes
// ===================================================================
// -------------------------------------------------------------------
// ddio_ff_AttachForce
// Purpose:
// Attaches variables initialized in the general ddio system to
// the force feedback system.
// -------------------------------------------------------------------
void ddio_ff_AttachForce(void);
// -------------------------------------------------------------------
// ddio_ff_DetachForce
// Purpose:
// Detaches variables used by the force-feedback system from the
// ddio system
// -------------------------------------------------------------------
void ddio_ff_DetachForce(void);
// -------------------------------------------------------------------
// ddio_ff_Init
// Purpose:
// Initialize force feedback if available.
// -------------------------------------------------------------------
int ddio_ff_Init(void);
// -------------------------------------------------------------------
// ddio_ffjoy_Init
// Purpose:
// Creates and acquires all joysticks
//
// Input:
// None
//
// Return:
// # of sticks acquired
//
// Description:
//
// -------------------------------------------------------------------
int ddio_ffjoy_Init(void);
// -------------------------------------------------------------------
// ddio_ff_Acquire
// Purpose:
// Acquires a direct input device for use.
//
// Input:
2024-04-16 18:56:40 +00:00
// The device to acquire (use kDI_MaxJoy to acquire all available
2024-04-16 03:43:29 +00:00
// joysticks).
//
// Return:
// # of devices acquired.
//
// Description:
// Call this to gain access to a device after the device has been
// created & after regaining the focus after losing it.
//
// -------------------------------------------------------------------
int ddio_ff_Acquire(tDevice dev);
// -------------------------------------------------------------------
// ddio_ff_Unacquire
// Purpose:
// Unacquires a direct input device
//
// Input:
2024-04-16 18:56:40 +00:00
// The device to unacquire (use kDI_MaxJoy to unacquire all available
2024-04-16 03:43:29 +00:00
// joysticks).
//
// Return:
// # of devices unacquired.
//
// Description:
// Call this to lose access to a device after the device has been
// aquired
//
// -------------------------------------------------------------------
int ddio_ff_Unacquire(tDevice dev);
// -------------------------------------------------------------------
// ddio_ff_SetCoopLevel
// -------------------------------------------------------------------
static int ddio_ff_SetCoopLevel(tDevice dev, int coop_level);
// -------------------------------------------------------------------
// ddio_ffjoy_Query
// Purpose:
// Besides checking what buttons/axis are available, this function
// also checks for force feedback support.
// -------------------------------------------------------------------
2024-04-16 18:56:40 +00:00
int ddio_ffjoy_Query(int dev, int *but_flags, int *axis_flags);
2024-04-16 03:43:29 +00:00
/*
========================================================================
2024-04-16 18:56:40 +00:00
Force Feedback Effect Functions
2024-04-16 03:43:29 +00:00
========================================================================
*/
// -------------------------------------------------------------------
// ddio_ff_GetInfo
// Purpose:
// Returns information about the current state of the low-level
// Force Feedback system.
// -------------------------------------------------------------------
2024-04-16 18:56:40 +00:00
void ddio_ff_GetInfo(bool *ff_found, bool *ff_enabled);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_Pause
// Purpose:
// Pause the FFB output on the given device. Use ddio_ffb_Continue to
// continue where you left off.
// -------------------------------------------------------------------
void ddio_ffb_Pause(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffb_Continue
// Purpose:
// Unpause the FFB output on the given device. Complimentary to
// ddio_ffb_Pause.
// -------------------------------------------------------------------
void ddio_ffb_Continue(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffb_Enable
// Purpose:
2024-04-16 18:56:40 +00:00
// Must be called after initialization in order to activate the
2024-04-16 03:43:29 +00:00
// device.
// Use ddio_ffb_Pause & ddio_ffb_Continue if you want disable forces
// temporarily and resume later.
// -------------------------------------------------------------------
void ddio_ffb_Enable(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffb_Disable
// Purpose:
// Turns off FFB, but effects still play on processor.
// -------------------------------------------------------------------
void ddio_ffb_Disable(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffb_effectCreate
// Purpose:
// Create a single effect for future playback.
// Effect is given a logical ID
// -------------------------------------------------------------------
2024-04-16 18:56:40 +00:00
int ddio_ffb_effectCreate(tDevice dev, tFFB_Effect *eff);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_DestroyAll
// Purpose:
// Destroys all created effects
// -------------------------------------------------------------------
void ddio_ffb_DestroyAll(void);
// -------------------------------------------------------------------
// ddio_ffb_effectPlay
// Purpose:
// Play an effect that was previously created.
// -------------------------------------------------------------------
void ddio_ffb_effectPlay(int16_t eID);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_effectStop
// Purpose:
// Stop a single effect.
// -------------------------------------------------------------------
void ddio_ffb_effectStop(int16_t eID);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_effectStopAll
// Purpose:
// Stops all forces on the given device.
// -------------------------------------------------------------------
void ddio_ffb_effectStopAll(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffb_effectUnload
// Purpose:
// Unload a single effect... Necessary to make room for other
// effects.
// -------------------------------------------------------------------
void ddio_ffb_effectUnload(int16_t eID);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_effectModify
// Purpose:
// Modifies a single effect, only if the given parameters are
// different from what's currently loaded.
// -------------------------------------------------------------------
void ddio_ffb_effectModify(int16_t eID, int *Direction, uint32_t *Duration, uint32_t *Gain, uint32_t *Period,
2024-04-16 18:56:40 +00:00
tEffInfo *TypeInfo, tEffEnvelope *Envelope);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffb_GetEffectData
// Purpose:
// Retrieves affect data for the given parameters, pass NULL for those you don't want
// -------------------------------------------------------------------
void ddio_ffb_GetEffectData(int16_t eID, int *Direction, uint32_t *Duration, uint32_t *Gain, uint32_t *Period,
2024-04-16 18:56:40 +00:00
tEffInfo *TypeInfo, tEffEnvelope *Envelope);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffjoy_EnableAutoCenter
// Purpose:
// Disables/Enables the autocentering of the joystick
// -------------------------------------------------------------------
2024-04-16 18:56:40 +00:00
void ddio_ffjoy_EnableAutoCenter(tDevice dev, bool enable);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffjoy_SetGain
// Purpose:
// Sets the gain for joystick, pass a value of 0-1
// -------------------------------------------------------------------
2024-04-16 18:56:40 +00:00
void ddio_ffjoy_SetGain(tDevice dev, float value);
2024-04-16 03:43:29 +00:00
// -------------------------------------------------------------------
// ddio_ffjoy_IsAutoCentered
// Purpose:
// Returns true if the joystick is set for autocentering
// -------------------------------------------------------------------
bool ddio_ffjoy_IsAutoCentered(tDevice dev);
// -------------------------------------------------------------------
// ddio_ffjoy_SupportAutoCenter
// Purpose:
// Returns true if the FF joystick supports auto centering
// -------------------------------------------------------------------
bool ddio_ffjoy_SupportAutoCenter(tDevice dev);
/*
===========================================================================
2024-04-16 18:56:40 +00:00
Private Functions
2024-04-16 03:43:29 +00:00
===========================================================================
*/
// Given a filename resource, this loads the file and creates a resource
// for it. It returns a handle to that resource.
// If it returns NULL, then it couldn't load the project.
// Make sure device is aquired before calling.
2024-04-16 18:56:40 +00:00
FORCEPROJECT ddio_ForceLoadProject(char *filename, tDevice dev);
2024-04-16 03:43:29 +00:00
// Unloads a FORCEPROJECT file
void ddio_ForceUnloadProject(FORCEPROJECT prj);
// Given a handle to a resource, and the name of the effect to load
// it will load that effect. Returns the effect ID, or -1 if it couldn't
// be created
int ddio_CreateForceFromProject(FORCEPROJECT project, const char *forcename);
#endif