Counter Strike : Global Offensive Source Code
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.

305 lines
8.1 KiB

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