You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
8.1 KiB
302 lines
8.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
#include "cbase.h" |
|
#include "forcefeedback.h" |
|
#include "hud_macros.h" |
|
#include "input.h" |
|
|
|
#define FF_CLIENT_FLAG 0x8000 |
|
|
|
class FFParams |
|
{ |
|
public: |
|
FORCEFEEDBACK_t m_nEffectType; |
|
FFBaseParams_t m_BaseParams; |
|
}; |
|
|
|
struct FFEffectInfo_t |
|
{ |
|
FORCEFEEDBACK_t effectType; |
|
char const *name; |
|
}; |
|
|
|
#define DECLARE_FFEFFECT( name ) { name, #name } |
|
|
|
static FFEffectInfo_t g_EffectTypes[] = |
|
{ |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_SINGLE ), |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_DOUBLE ), |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_TAKEDAMAGE ), |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SCREENSHAKE ), |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SKIDDING ), |
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_BREAKING ) |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : effect - |
|
// Output : char const |
|
//----------------------------------------------------------------------------- |
|
char const *NameForForceFeedbackEffect( FORCEFEEDBACK_t effect ) |
|
{ |
|
int c = ARRAYSIZE( g_EffectTypes ); |
|
if ( (int)effect < 0 || (int)effect >= c ) |
|
return "???"; |
|
|
|
const FFEffectInfo_t& info = g_EffectTypes[ (int)effect ]; |
|
Assert( info.effectType == effect ); |
|
return info.name; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *name - |
|
// Output : FORCEFEEDBACK_t |
|
//----------------------------------------------------------------------------- |
|
FORCEFEEDBACK_t ForceFeedbackEffectForName( const char *name ) |
|
{ |
|
int c = ARRAYSIZE( g_EffectTypes ); |
|
for ( int i = 0 ; i < c; ++i ) |
|
{ |
|
const FFEffectInfo_t& info = g_EffectTypes[ i ]; |
|
|
|
if ( !Q_stricmp( info.name, name ) ) |
|
return info.effectType; |
|
} |
|
|
|
return ( FORCEFEEDBACK_t )-1; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
class CForceFeedback : public IForceFeedback, public CAutoGameSystem |
|
{ |
|
public: |
|
virtual bool Init(); |
|
virtual void Shutdown(); |
|
|
|
// API |
|
virtual void StopAllEffects( CBasePlayer *player ); |
|
virtual void StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect ); |
|
virtual void StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params ); |
|
|
|
virtual void PauseAll( CBasePlayer *player ); |
|
virtual void ResumeAll( CBasePlayer *player ); |
|
|
|
void MsgFunc_ForceFeedback( bf_read &msg ); |
|
|
|
private: |
|
|
|
void Internal_StopAllEffects(); |
|
void Internal_StopEffect( FORCEFEEDBACK_t effect ); |
|
void Internal_StartEffect( FORCEFEEDBACK_t, const FFBaseParams_t& params ); |
|
void Internal_PauseAll(); |
|
void Internal_ResumeAll(); |
|
}; |
|
|
|
static CForceFeedback g_ForceFeedbackSingleton; |
|
IForceFeedback *forcefeedback = &g_ForceFeedbackSingleton; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &msg - |
|
//----------------------------------------------------------------------------- |
|
void __MsgFunc_ForceFeedback( bf_read &msg ) |
|
{ |
|
g_ForceFeedbackSingleton.MsgFunc_ForceFeedback( msg ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CForceFeedback::Init() |
|
{ |
|
HOOK_MESSAGE( ForceFeedback ); |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Shutdown() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *player - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::StopAllEffects( CBasePlayer *player ) |
|
{ |
|
if ( !player ) |
|
return; |
|
|
|
Internal_StopAllEffects(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *player - |
|
// effect - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect ) |
|
{ |
|
if ( !player ) |
|
return; |
|
|
|
Internal_StopEffect( effect ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *player - |
|
// effect - |
|
// params - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params ) |
|
{ |
|
if ( !player ) |
|
{ |
|
return; |
|
} |
|
|
|
Internal_StartEffect( effect, params ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *player - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::PauseAll( CBasePlayer *player ) |
|
{ |
|
if ( !player ) |
|
return; |
|
|
|
Internal_PauseAll(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *player - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::ResumeAll( CBasePlayer *player ) |
|
{ |
|
if ( !player ) |
|
return; |
|
|
|
Internal_ResumeAll(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Internal_StopAllEffects() |
|
{ |
|
input->ForceFeedback_StopAll(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : heffect - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Internal_StopEffect( FORCEFEEDBACK_t effect ) |
|
{ |
|
input->ForceFeedback_Stop( effect ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : effect - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Internal_StartEffect( FORCEFEEDBACK_t effect, const FFBaseParams_t& params) |
|
{ |
|
char const *name = NameForForceFeedbackEffect( effect ); |
|
Msg( "Starting FF effect '%s'\n", name ); |
|
|
|
FFParams p; |
|
p.m_nEffectType = effect; |
|
p.m_BaseParams = params; |
|
|
|
input->ForceFeedback_Start( effect, params ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Internal_PauseAll() |
|
{ |
|
input->ForceFeedback_Pause(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::Internal_ResumeAll() |
|
{ |
|
input->ForceFeedback_Resume(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pszName - |
|
// iSize - |
|
// *pbuf - |
|
//----------------------------------------------------------------------------- |
|
void CForceFeedback::MsgFunc_ForceFeedback( bf_read &msg ) |
|
{ |
|
byte msgType = msg.ReadByte(); |
|
|
|
switch ( msgType ) |
|
{ |
|
default: |
|
{ |
|
Warning( "Bad parse in MsgFunc_ForceFeedback!\n" ); |
|
} |
|
break; |
|
case FFMSG_STOPALL: |
|
{ |
|
Internal_StopAllEffects(); |
|
} |
|
break; |
|
case FFMSG_START: |
|
{ |
|
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte(); |
|
|
|
FFBaseParams_t params; |
|
params.m_flDirection = 360.0f * ( (byte)msg.ReadByte() / 255.0f ); |
|
params.m_flDuration = (float)msg.ReadLong() / 1000.0f; |
|
params.m_flGain = ( (byte)msg.ReadByte() / 255.0f ); |
|
params.m_nPriority = msg.ReadByte(); |
|
params.m_bSolo = msg.ReadByte() == 0 ? false : true; |
|
|
|
if ( effectType >= 0 && effectType < NUM_FORCE_FEEDBACK_PRESETS ) |
|
{ |
|
Internal_StartEffect( effectType, params ); |
|
} |
|
else |
|
{ |
|
Warning( "Bad parse in MsgFunc_ForceFeedback, FFMSG_START (%i)!\n", effectType ); |
|
} |
|
} |
|
break; |
|
case FFMSG_STOP: |
|
{ |
|
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte(); |
|
|
|
Internal_StopEffect( effectType ); |
|
} |
|
break; |
|
case FFMSG_PAUSE: |
|
{ |
|
Internal_PauseAll(); |
|
} |
|
break; |
|
case FFMSG_RESUME: |
|
{ |
|
Internal_ResumeAll(); |
|
} |
|
break; |
|
} |
|
}
|
|
|