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.

326 lines
12 KiB

  1. #ifndef IHFXEFFECT_H_
  2. #define IHFXEFFECT_H_
  3. #include ".\\HFXConfig.h"
  4. #include ".\\IHFXParam.h"
  5. struct IHapticEffectParamGroup;
  6. typedef IHapticEffectParamGroup IHFXParamGroup;
  7. class IProcessor;
  8. typedef IProcessor IHFXProcessor;
  9. class IStack;
  10. typedef IStack IHFXStack;
  11. enum HFXStateBits
  12. {
  13. // when a state variable is made it uses the below value
  14. HFXSTATE_INITIAL =0,
  15. // explicite pause
  16. HFXSTATE_PAUSE =(1<<0),
  17. // explicite mute
  18. HFXSTATE_MUTE =(1<<1),
  19. // the effect has gone into its exit phase.
  20. HFXSTATE_EXITING =(1<<2),
  21. HFXSTATE_WANT_SYNC =(1<<3),
  22. HFXSTATE_CLIENT_ONLY =4,
  23. //everything below will be uncontrolled by servo
  24. HFXSTATE_WANT_UPDATE =(1<<HFXSTATE_CLIENT_ONLY),
  25. HFXSTATE_RUNNING =(1<<(HFXSTATE_CLIENT_ONLY+1)),
  26. HFXSTATE_HAULT =(1<<(HFXSTATE_CLIENT_ONLY+2)),
  27. HFXSTATE_HOLDING_EFFECT =(1<<(HFXSTATE_CLIENT_ONLY+3)),
  28. HFXSTATE_COUNT =8,
  29. // number of state bits before non servo controlled bits
  30. };
  31. typedef unsigned __int8 HFXSTATE;
  32. typedef HFXSTATE HFXStateStorage;
  33. #if WIN64
  34. typedef const HFXStateStorage &HFXStateTransfer;
  35. #else
  36. typedef const HFXStateStorage HFXStateTransfer;
  37. #endif
  38. // utility union, takes up same memory as a flagset but gives you
  39. // inline operators and helper functions for state flags
  40. union HFX_ALIGN(8) HFXStateFlags
  41. {
  42. public:
  43. //default constructor
  44. HFX_INLINE HFXStateFlags(){};
  45. //copy constructor
  46. HFX_INLINE HFXStateFlags(const HFXStateFlags &copy) : Storage(copy.Storage){};
  47. HFX_INLINE HFXStateFlags(HFXStateStorage flags) : Storage(flags){};
  48. HFX_INLINE HFXStateFlags(
  49. bool bRunning, bool bPaused, bool bMuted, bool bHaulted, bool bExiting
  50. ) : Storage((bRunning ? HFXSTATE_RUNNING : 0)|
  51. (bPaused ? HFXSTATE_PAUSE : 0)|
  52. (bMuted ? HFXSTATE_MUTE : 0)|
  53. (bHaulted ? HFXSTATE_HAULT : 0)|
  54. (bExiting ? HFXSTATE_EXITING : 0) )
  55. {};
  56. // actual flags. (shared memory)
  57. HFXStateStorage Storage;
  58. // flags in boolean form. (shared memory)
  59. struct {
  60. bool Running:1;
  61. bool Paused:1;
  62. bool Muted:1;
  63. bool Haulted:1;
  64. bool Exiting:1;
  65. };
  66. // flags in bool group ( for -> operator )
  67. struct HFXStateFlagGroup{
  68. bool Running:1;
  69. bool Paused:1;
  70. bool Muted:1;
  71. bool Haulted:1;
  72. bool Exiting:1;
  73. }Flags;
  74. // type cast operators to flagstorage type
  75. HFX_INLINE operator HFXStateStorage &(){return Storage;}
  76. HFX_INLINE operator const HFXStateStorage &()const{return Storage;}
  77. HFX_INLINE operator HFXStateStorage (){return Storage;}
  78. HFX_INLINE operator const HFXStateStorage ()const{return Storage;}
  79. // at operator to get reference of storage.
  80. HFX_INLINE HFXStateStorage &operator *(){return Storage;};
  81. HFX_INLINE const HFXStateStorage &operator *()const{return Storage;};
  82. // bool operator, to see if there are any flags set.
  83. HFX_INLINE bool operator()(int bit){return (Storage & bit)!=0;};
  84. // -> operator to get boolean access flags quickly.
  85. HFX_INLINE HFXStateFlagGroup *operator ->(){return &Flags;};
  86. HFX_INLINE const HFXStateFlagGroup *operator ->()const{return &Flags;};
  87. HFX_INLINE HFXStateStorage *operator &(){return &Storage;};
  88. HFX_INLINE const HFXStateStorage *operator &()const{return &Storage;};
  89. HFX_INLINE HFXStateStorage &operator =(HFXStateTransfer state){Storage = state; return Storage;}
  90. HFX_INLINE HFXStateStorage &operator |=(HFXStateTransfer state){Storage |= state; return Storage;}
  91. HFX_INLINE HFXStateStorage &operator &=(HFXStateTransfer state){Storage &= state; return Storage;}
  92. HFX_INLINE HFXStateStorage &operator ^=(HFXStateTransfer state){Storage |= state; return Storage;}
  93. HFX_INLINE HFXStateStorage operator ~()const{return ~Storage;}
  94. HFX_INLINE HFXStateStorage operator |(HFXStateTransfer state){return (Storage|state);}
  95. HFX_INLINE HFXStateStorage operator &(HFXStateTransfer state){return (Storage&state);}
  96. HFX_INLINE HFXStateStorage operator ^(HFXStateTransfer state){return (Storage^state);}
  97. HFX_INLINE bool operator ==(HFXStateTransfer state){return (Storage==state);}
  98. HFX_INLINE bool operator !=(HFXStateTransfer state){return (Storage!=state);}
  99. HFX_INLINE bool operator !(){return (Storage==0);}
  100. HFX_INLINE operator bool(){return (Storage!=0);}
  101. HFX_INLINE HFXStateFlags *UtilPointer(){return this;};
  102. HFX_INLINE const HFXStateFlags *UtilPointer()const{return this;};
  103. HFX_INLINE HFXStateFlags &Util(){return *this;};
  104. HFX_INLINE const HFXStateFlags &Util()const{return *this;};
  105. };
  106. enum HFXNeeds
  107. {
  108. //effect has a application thread time sync
  109. HFXNEED_SYNC =(1 << 0),
  110. //effect has a servo thread time update
  111. HFXNEED_PROCESS =(1 << 1),
  112. //effect takes parameters
  113. HFXNEED_SET =(1 << 2),
  114. //effect needs stack access
  115. HFXNEED_STACK =(1 << 3),
  116. //device slots. if you need a device you need a stack.
  117. HFXNEED_DEVICE1 =(1 << 4),
  118. HFXNEED_DEVICE2 =(1 << 5),
  119. HFXNEED_DEVICE3 =(1 << 6),
  120. HFXNEED_DEVICE4 =(1 << 7),
  121. HFXNEED_DEVICE5 =(1 << 8),
  122. HFXNEED_DEVICE6 =(1 << 9),
  123. HFXNEED_DEVICE7 =(1 << 10),
  124. HFXNEED_DEVICE8 =(1 << 11),
  125. //ability to create/destroy sub effects
  126. HFXNEED_MANAGE =(1 << 12),
  127. //effect needs to know how long its been running.
  128. HFXNEED_RUNTIME =(1 << 13),
  129. //effect needs to know how long its been since the last time its processed a function.
  130. HFXNEED_FRAMETIME =(1 << 14),
  131. //effect needs a fixed time sent to its framtime
  132. HFXNEED_FIXEDTIME =(1 << 15),
  133. //effect has a init function
  134. HFXNEED_INSTANCE =(1 << 16),
  135. //effect needs owning stack's parent access
  136. HFXNEED_PARENT =(1 << 17),
  137. //effect is self deleting
  138. HFXNEED_REMOVE =(1 << 18),
  139. //effect does not give handles. these effects need to be self deleting
  140. HFXNEED_ENCAPSULATED =(1 << 19),
  141. HFXNEED_EXIT =(1 << 20),
  142. //state change inform flags
  143. HFXNEED_STATE_INFORM =(1 << 21),
  144. HFXNEED_RUNNING_INFORM =(1 << 22),
  145. HFXNEED_PAUSE_INFORM =(1 << 23),
  146. HFXNEED_HAULT_INFORM =(1 << 24),
  147. HFXNEED_MUTE_INFORM =(1 << 25),
  148. HFXNEED_EXITING_INFORM =(1 << 26),
  149. // USE THE BELOW FLAGS TO DECLARE FEATURES TO A EFFECT CLASS WHEN REGISTERING
  150. HFXNEED_DECL_SYNC =(HFXNEED_SYNC),
  151. HFXNEED_DECL_PROCESS =(HFXNEED_PROCESS),
  152. HFXNEED_DECL_STACK =(HFXNEED_STACK),
  153. HFXNEED_DECL_DEVICE1 =(HFXNEED_DEVICE1|HFXNEED_DECL_STACK),
  154. HFXNEED_DECL_DEVICE2 =(HFXNEED_DEVICE2|HFXNEED_DECL_STACK),
  155. HFXNEED_DECL_DEVICE3 =(HFXNEED_DEVICE3|HFXNEED_DECL_STACK),
  156. HFXNEED_DECL_DEVICE4 =(HFXNEED_DEVICE4|HFXNEED_DECL_STACK),
  157. HFXNEED_DECL_DEVICE5 =(HFXNEED_DEVICE5|HFXNEED_DECL_STACK),
  158. HFXNEED_DECL_DEVICE6 =(HFXNEED_DEVICE6|HFXNEED_DECL_STACK),
  159. HFXNEED_DECL_DEVICE7 =(HFXNEED_DEVICE7|HFXNEED_DECL_STACK),
  160. HFXNEED_DECL_DEVICE8 =(HFXNEED_DEVICE8|HFXNEED_DECL_STACK),
  161. HFXNEED_DECL_RUNTIME =(HFXNEED_RUNTIME),
  162. HFXNEED_DECL_FRAMETIME =(HFXNEED_FRAMETIME),
  163. // there is no decl for HFXNEED_FIXEDTIME as it is pointless without
  164. // a runtime or frametime decl.
  165. HFXNEED_DECL_FIXEDFRAME =(HFXNEED_FRAMETIME|HFXNEED_FIXEDTIME),
  166. HFXNEED_DECL_FIXEDRUNTIME =(HFXNEED_DECL_RUNTIME|HFXNEED_FIXEDTIME),
  167. HFXNEED_DECL_MANAGE =(HFXNEED_DECL_FRAMETIME|HFXNEED_DECL_STACK),
  168. HFXNEED_DECL_REMOVE =(HFXNEED_REMOVE),
  169. HFXNEED_DECL_ENCAPSULATED =(HFXNEED_ENCAPSULATED|HFXNEED_DECL_REMOVE),
  170. HFXNEED_DECL_PARENT =(HFXNEED_PARENT),
  171. HFXNEED_DECL_INSTANCE =(HFXNEED_INSTANCE),
  172. HFXNEED_DECL_SET =(HFXNEED_SET),
  173. // there is no HFXNEED_STATE_INFORM declare as it would be pointless without a
  174. // declaration of specific informs
  175. HFXNEED_DECL_RUNNING_INFORM =(HFXNEED_RUNNING_INFORM|HFXNEED_STATE_INFORM),
  176. HFXNEED_DECL_PAUSE_INFORM =(HFXNEED_PAUSE_INFORM|HFXNEED_STATE_INFORM),
  177. HFXNEED_DECL_MUTE_INFORM =(HFXNEED_MUTE_INFORM|HFXNEED_STATE_INFORM),
  178. HFXNEED_DECL_EXITING_INFORM =(HFXNEED_EXITING_INFORM|HFXNEED_STATE_INFORM),
  179. HFXNEED_DECL_HAULT_INFORM =(HFXNEED_HAULT_INFORM|HFXNEED_STATE_INFORM),
  180. // only use this if you will actually be using all informs!
  181. HFXNEED_DECL_TOTAL_INFORM =( HFXNEED_RUNNING_INFORM|HFXNEED_PAUSE_INFORM|
  182. HFXNEED_MUTE_INFORM|HFXNEED_EXITING_INFORM|
  183. HFXNEED_STATE_INFORM),
  184. // INFORMATION FLAGS
  185. HFXNEED_INFO_DEVICE =( HFXNEED_DEVICE1|HFXNEED_DEVICE2|
  186. HFXNEED_DEVICE3|HFXNEED_DEVICE4|
  187. HFXNEED_DEVICE5|HFXNEED_DEVICE6|
  188. HFXNEED_DEVICE7|HFXNEED_DEVICE8),
  189. };
  190. #define HFXNEED_UTIL_COUNT_DEVICES(flags) \
  191. ( ( ( (flags) & HFXNEED_INFO_DEVICE ) != 0) ? ( \
  192. ( ( ( (flags) & HFXNEED_DEVICE1 ) != 0) ? 1 : 0 ) + \
  193. ( ( ( (flags) & HFXNEED_DEVICE2 ) != 0) ? 1 : 0 ) + \
  194. ( ( ( (flags) & HFXNEED_DEVICE3 ) != 0) ? 1 : 0 ) + \
  195. ( ( ( (flags) & HFXNEED_DEVICE4 ) != 0) ? 1 : 0 ) + \
  196. ( ( ( (flags) & HFXNEED_DEVICE5 ) != 0) ? 1 : 0 ) + \
  197. ( ( ( (flags) & HFXNEED_DEVICE6 ) != 0) ? 1 : 0 ) + \
  198. ( ( ( (flags) & HFXNEED_DEVICE7 ) != 0) ? 1 : 0 ) + \
  199. ( ( ( (flags) & HFXNEED_DEVICE8 ) != 0) ? 1 : 0 ) ) \
  200. : 0 )
  201. typedef unsigned __int32 HFXNEED;
  202. #define HFX_XCHANGE 16
  203. #define HFX_YCHANGE 17
  204. #define HFX_ZCHANGE 18
  205. enum HFXResult
  206. {
  207. HFXRESULT_ERROR =-2,
  208. HFXRESULT_FINISHED =-1,
  209. HFXRESULT_CONTINUE =0,
  210. // x axis was set
  211. HFXRESULT_XCHANGED =(1 << HFX_XCHANGE),
  212. // y axis was set
  213. HFXRESULT_YCHANGED =(1 << HFX_YCHANGE),
  214. // z axis was set
  215. HFXRESULT_ZCHANGED =(1 << HFX_ZCHANGE),
  216. // x and y axis was set
  217. HFXRESULT_XYCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_YCHANGED),
  218. // x and z axis was set
  219. HFXRESULT_XZCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_ZCHANGED),
  220. // y and z axis was set
  221. HFXRESULT_YZCHANGED =(HFXRESULT_YCHANGED|HFXRESULT_ZCHANGED),
  222. // x and y axis was set
  223. HFXRESULT_YXCHANGED =HFXRESULT_XYCHANGED,
  224. // x and z axis was set
  225. HFXRESULT_ZXCHANGED =HFXRESULT_XZCHANGED,
  226. // y and z axis was set
  227. HFXRESULT_ZYCHANGED =HFXRESULT_YZCHANGED,
  228. // x, y and z axis set
  229. HFXRESULT_XYZCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_YCHANGED|HFXRESULT_ZCHANGED),
  230. HFXRESULT_CHANGED =HFXRESULT_XYZCHANGED,
  231. };
  232. typedef int HFXRESULT;
  233. class HFX_PURE_INTERFACE IHapticEffect
  234. {
  235. public:
  236. // return false if you decide the processor given to you is not sufficient
  237. // or any other reason the effect should not be made.
  238. // !called one time only. before any other funciton calls.
  239. // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_INSTANCE
  240. virtual bool Initialize(IHFXProcessor &processor)=0;
  241. // called by the game thread and blocks the haptics thread so the game and haptics loop are safe inside.
  242. // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_SYNC
  243. virtual HFXRESULT SyncOp(IHFXProcessor &processor)=0;
  244. //called at haptic rate. should set the output parameter to the target output force.
  245. // calculation should optimized and precise in here.
  246. // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_PROCESS
  247. virtual HFXRESULT Update(IHFXProcessor &processor)=0;
  248. //return true if parameters sent to you are sufficient.
  249. virtual bool Set(IHFXProcessor &processor, IHFXParamGroup *parameter)=0;
  250. //notification of state change.
  251. // WILL ONLY BE CALLED IF YOU DECLARE YOUR EFFECT REGISTER WITH A _INFORM decl and will ONLY be called with those.
  252. // note: state will be only one bit. for every bit changed on sync this function will be called.
  253. virtual void OnStateChange(IHFXProcessor &processor, HFXSTATE state, bool flagged)=0;
  254. };
  255. typedef IHapticEffect IHFXEffect;
  256. typedef void (*hfxFilterFunction)(double outvect[3]);
  257. typedef void (*HFXCreate_t)(IHFXEffect*&ptr);
  258. typedef void (*HFXDestroy_t)(IHFXEffect*&ptr);
  259. template<typename T>
  260. void HFXDefaultAllocateEffect(IHFXEffect *&ptr){ptr = new T;};
  261. template<typename T>
  262. void HFXDefaultDeallocateEffect(IHFXEffect *&ptr){if(!ptr)return; delete ((T*)ptr); ptr=0;};
  263. class IHapticsSystem;
  264. typedef IHapticsSystem IHFXSystem;
  265. class IDevice;
  266. typedef IDevice IHFXDevice;
  267. class IStack;
  268. typedef IStack IHFXStack;
  269. // T == effect class
  270. template<typename T>
  271. inline HFXEffectID HFXDefaultRegisterEffect(IHFXSystem &hfxSystem, const char *tag, HFXNEED needs, IHFXParamGroup *defaults, HFXCreate_t specialCreate = HFXDefaultAllocateEffect<T>, HFXDestroy_t specialDestroy = HFXDefaultDeallocateEffect<T> )
  272. {
  273. hfxSystem.LogMessage((const int)1,"EFFECT REGISTERING! %s Size = %i \n", tag, sizeof(T));
  274. return hfxSystem.RegisterEffectClass(
  275. tag,
  276. specialCreate,
  277. specialDestroy,
  278. needs,
  279. defaults);
  280. };
  281. // T == effect class
  282. // P == parametergroup class
  283. template<typename T, typename P>
  284. inline HFXEffectID HFXDefaultRegisterEffect(IHFXSystem &hfxSystem, const char *tag, HFXNEED needs, HFXCreate_t specialCreate = 0, HFXDestroy_t specialDestroy = 0)
  285. {
  286. P *pGroup = new P;
  287. HFXEffectID retval=0;
  288. if(pGroup->CopyDefaults(pGroup))
  289. {
  290. retval = HFXDefaultRegisterEffect<T>(hfxSystem, tag, needs, pGroup, specialCreate, specialDestroy);
  291. }
  292. delete pGroup;
  293. return retval;
  294. };
  295. #endif