Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include "cbase.h"
  3. #include "forcefeedback.h"
  4. #include "hud_macros.h"
  5. #include "input.h"
  6. #define FF_CLIENT_FLAG 0x8000
  7. class FFParams
  8. {
  9. public:
  10. FORCEFEEDBACK_t m_nEffectType;
  11. FFBaseParams_t m_BaseParams;
  12. };
  13. struct FFEffectInfo_t
  14. {
  15. FORCEFEEDBACK_t effectType;
  16. char const *name;
  17. };
  18. #define DECLARE_FFEFFECT( name ) { name, #name }
  19. static FFEffectInfo_t g_EffectTypes[] =
  20. {
  21. DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_SINGLE ),
  22. DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_DOUBLE ),
  23. DECLARE_FFEFFECT( FORCE_FEEDBACK_TAKEDAMAGE ),
  24. DECLARE_FFEFFECT( FORCE_FEEDBACK_SCREENSHAKE ),
  25. DECLARE_FFEFFECT( FORCE_FEEDBACK_SKIDDING ),
  26. DECLARE_FFEFFECT( FORCE_FEEDBACK_BREAKING )
  27. };
  28. //-----------------------------------------------------------------------------
  29. // Purpose:
  30. // Input : effect -
  31. // Output : char const
  32. //-----------------------------------------------------------------------------
  33. char const *NameForForceFeedbackEffect( FORCEFEEDBACK_t effect )
  34. {
  35. int c = ARRAYSIZE( g_EffectTypes );
  36. if ( (int)effect < 0 || (int)effect >= c )
  37. return "???";
  38. const FFEffectInfo_t& info = g_EffectTypes[ (int)effect ];
  39. Assert( info.effectType == effect );
  40. return info.name;
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose:
  44. // Input : *name -
  45. // Output : FORCEFEEDBACK_t
  46. //-----------------------------------------------------------------------------
  47. FORCEFEEDBACK_t ForceFeedbackEffectForName( const char *name )
  48. {
  49. int c = ARRAYSIZE( g_EffectTypes );
  50. for ( int i = 0 ; i < c; ++i )
  51. {
  52. const FFEffectInfo_t& info = g_EffectTypes[ i ];
  53. if ( !Q_stricmp( info.name, name ) )
  54. return info.effectType;
  55. }
  56. return ( FORCEFEEDBACK_t )-1;
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Purpose:
  60. //-----------------------------------------------------------------------------
  61. class CForceFeedback : public IForceFeedback, public CAutoGameSystem
  62. {
  63. public:
  64. virtual bool Init();
  65. virtual void Shutdown();
  66. // API
  67. virtual void StopAllEffects( CBasePlayer *player );
  68. virtual void StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect );
  69. virtual void StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params );
  70. virtual void PauseAll( CBasePlayer *player );
  71. virtual void ResumeAll( CBasePlayer *player );
  72. void MsgFunc_ForceFeedback( bf_read &msg );
  73. private:
  74. void Internal_StopAllEffects();
  75. void Internal_StopEffect( FORCEFEEDBACK_t effect );
  76. void Internal_StartEffect( FORCEFEEDBACK_t, const FFBaseParams_t& params );
  77. void Internal_PauseAll();
  78. void Internal_ResumeAll();
  79. };
  80. static CForceFeedback g_ForceFeedbackSingleton;
  81. IForceFeedback *forcefeedback = &g_ForceFeedbackSingleton;
  82. //-----------------------------------------------------------------------------
  83. // Purpose:
  84. // Input : &msg -
  85. //-----------------------------------------------------------------------------
  86. void __MsgFunc_ForceFeedback( bf_read &msg )
  87. {
  88. g_ForceFeedbackSingleton.MsgFunc_ForceFeedback( msg );
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Purpose:
  92. // Output : Returns true on success, false on failure.
  93. //-----------------------------------------------------------------------------
  94. bool CForceFeedback::Init()
  95. {
  96. HOOK_MESSAGE( ForceFeedback );
  97. return true;
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. //-----------------------------------------------------------------------------
  102. void CForceFeedback::Shutdown()
  103. {
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Purpose:
  107. // Input : *player -
  108. //-----------------------------------------------------------------------------
  109. void CForceFeedback::StopAllEffects( CBasePlayer *player )
  110. {
  111. if ( !player )
  112. return;
  113. Internal_StopAllEffects();
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose:
  117. // Input : *player -
  118. // effect -
  119. //-----------------------------------------------------------------------------
  120. void CForceFeedback::StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect )
  121. {
  122. if ( !player )
  123. return;
  124. Internal_StopEffect( effect );
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose:
  128. // Input : *player -
  129. // effect -
  130. // params -
  131. //-----------------------------------------------------------------------------
  132. void CForceFeedback::StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params )
  133. {
  134. if ( !player )
  135. {
  136. return;
  137. }
  138. Internal_StartEffect( effect, params );
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose:
  142. // Input : *player -
  143. //-----------------------------------------------------------------------------
  144. void CForceFeedback::PauseAll( CBasePlayer *player )
  145. {
  146. if ( !player )
  147. return;
  148. Internal_PauseAll();
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose:
  152. // Input : *player -
  153. //-----------------------------------------------------------------------------
  154. void CForceFeedback::ResumeAll( CBasePlayer *player )
  155. {
  156. if ( !player )
  157. return;
  158. Internal_ResumeAll();
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Purpose:
  162. //-----------------------------------------------------------------------------
  163. void CForceFeedback::Internal_StopAllEffects()
  164. {
  165. input->ForceFeedback_StopAll();
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose:
  169. // Input : heffect -
  170. //-----------------------------------------------------------------------------
  171. void CForceFeedback::Internal_StopEffect( FORCEFEEDBACK_t effect )
  172. {
  173. input->ForceFeedback_Stop( effect );
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose:
  177. // Input : effect -
  178. //-----------------------------------------------------------------------------
  179. void CForceFeedback::Internal_StartEffect( FORCEFEEDBACK_t effect, const FFBaseParams_t& params)
  180. {
  181. char const *name = NameForForceFeedbackEffect( effect );
  182. Msg( "Starting FF effect '%s'\n", name );
  183. FFParams p;
  184. p.m_nEffectType = effect;
  185. p.m_BaseParams = params;
  186. input->ForceFeedback_Start( effect, params );
  187. }
  188. //-----------------------------------------------------------------------------
  189. // Purpose:
  190. //-----------------------------------------------------------------------------
  191. void CForceFeedback::Internal_PauseAll()
  192. {
  193. input->ForceFeedback_Pause();
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Purpose:
  197. //-----------------------------------------------------------------------------
  198. void CForceFeedback::Internal_ResumeAll()
  199. {
  200. input->ForceFeedback_Resume();
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Purpose:
  204. // Input : *pszName -
  205. // iSize -
  206. // *pbuf -
  207. //-----------------------------------------------------------------------------
  208. void CForceFeedback::MsgFunc_ForceFeedback( bf_read &msg )
  209. {
  210. byte msgType = msg.ReadByte();
  211. switch ( msgType )
  212. {
  213. default:
  214. {
  215. Warning( "Bad parse in MsgFunc_ForceFeedback!\n" );
  216. }
  217. break;
  218. case FFMSG_STOPALL:
  219. {
  220. Internal_StopAllEffects();
  221. }
  222. break;
  223. case FFMSG_START:
  224. {
  225. FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
  226. FFBaseParams_t params;
  227. params.m_flDirection = 360.0f * ( (byte)msg.ReadByte() / 255.0f );
  228. params.m_flDuration = (float)msg.ReadLong() / 1000.0f;
  229. params.m_flGain = ( (byte)msg.ReadByte() / 255.0f );
  230. params.m_nPriority = msg.ReadByte();
  231. params.m_bSolo = msg.ReadByte() == 0 ? false : true;
  232. if ( effectType >= 0 && effectType < NUM_FORCE_FEEDBACK_PRESETS )
  233. {
  234. Internal_StartEffect( effectType, params );
  235. }
  236. else
  237. {
  238. Warning( "Bad parse in MsgFunc_ForceFeedback, FFMSG_START (%i)!\n", effectType );
  239. }
  240. }
  241. break;
  242. case FFMSG_STOP:
  243. {
  244. FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
  245. Internal_StopEffect( effectType );
  246. }
  247. break;
  248. case FFMSG_PAUSE:
  249. {
  250. Internal_PauseAll();
  251. }
  252. break;
  253. case FFMSG_RESUME:
  254. {
  255. Internal_ResumeAll();
  256. }
  257. break;
  258. }
  259. }