|
|
#include "cbase.h"
#include "forcefeedback.h"
#include "hud_macros.h"
#include "input.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.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; } }
|