diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /common/ihfx/ihfxeffect.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'common/ihfx/ihfxeffect.h')
| -rw-r--r-- | common/ihfx/ihfxeffect.h | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/common/ihfx/ihfxeffect.h b/common/ihfx/ihfxeffect.h new file mode 100644 index 0000000..002b2ca --- /dev/null +++ b/common/ihfx/ihfxeffect.h @@ -0,0 +1,327 @@ + +#ifndef IHFXEFFECT_H_ +#define IHFXEFFECT_H_ +#include ".\\HFXConfig.h" +#include ".\\IHFXParam.h" + +struct IHapticEffectParamGroup; +typedef IHapticEffectParamGroup IHFXParamGroup; +class IProcessor; +typedef IProcessor IHFXProcessor; +class IStack; +typedef IStack IHFXStack; +enum HFXStateBits +{ + // when a state variable is made it uses the below value + HFXSTATE_INITIAL =0, + // explicite pause + HFXSTATE_PAUSE =(1<<0), + // explicite mute + HFXSTATE_MUTE =(1<<1), + // the effect has gone into its exit phase. + HFXSTATE_EXITING =(1<<2), + HFXSTATE_WANT_SYNC =(1<<3), + HFXSTATE_CLIENT_ONLY =4, + //everything below will be uncontrolled by servo + HFXSTATE_WANT_UPDATE =(1<<HFXSTATE_CLIENT_ONLY), + HFXSTATE_RUNNING =(1<<(HFXSTATE_CLIENT_ONLY+1)), + HFXSTATE_HAULT =(1<<(HFXSTATE_CLIENT_ONLY+2)), + HFXSTATE_HOLDING_EFFECT =(1<<(HFXSTATE_CLIENT_ONLY+3)), + HFXSTATE_COUNT =8, + // number of state bits before non servo controlled bits +}; +typedef unsigned __int8 HFXSTATE; +typedef HFXSTATE HFXStateStorage; + +#if WIN64 +typedef const HFXStateStorage &HFXStateTransfer; +#else +typedef const HFXStateStorage HFXStateTransfer; +#endif + +// utility union, takes up same memory as a flagset but gives you +// inline operators and helper functions for state flags +union HFX_ALIGN(8) HFXStateFlags +{ +public: + //default constructor + HFX_INLINE HFXStateFlags(){}; + + //copy constructor + HFX_INLINE HFXStateFlags(const HFXStateFlags ©) : Storage(copy.Storage){}; + + HFX_INLINE HFXStateFlags(HFXStateStorage flags) : Storage(flags){}; + + HFX_INLINE HFXStateFlags( + bool bRunning, bool bPaused, bool bMuted, bool bHaulted, bool bExiting + ) : Storage((bRunning ? HFXSTATE_RUNNING : 0)| + (bPaused ? HFXSTATE_PAUSE : 0)| + (bMuted ? HFXSTATE_MUTE : 0)| + (bHaulted ? HFXSTATE_HAULT : 0)| + (bExiting ? HFXSTATE_EXITING : 0) ) + {}; + // actual flags. (shared memory) + HFXStateStorage Storage; + // flags in boolean form. (shared memory) + struct { + bool Running:1; + bool Paused:1; + bool Muted:1; + bool Haulted:1; + bool Exiting:1; + }; + // flags in bool group ( for -> operator ) + struct HFXStateFlagGroup{ + bool Running:1; + bool Paused:1; + bool Muted:1; + bool Haulted:1; + bool Exiting:1; + }Flags; + + // type cast operators to flagstorage type + HFX_INLINE operator HFXStateStorage &(){return Storage;} + HFX_INLINE operator const HFXStateStorage &()const{return Storage;} + HFX_INLINE operator HFXStateStorage (){return Storage;} + HFX_INLINE operator const HFXStateStorage ()const{return Storage;} + + // at operator to get reference of storage. + HFX_INLINE HFXStateStorage &operator *(){return Storage;}; + HFX_INLINE const HFXStateStorage &operator *()const{return Storage;}; + + // bool operator, to see if there are any flags set. + HFX_INLINE bool operator()(int bit){return (Storage & bit)!=0;}; + + // -> operator to get boolean access flags quickly. + HFX_INLINE HFXStateFlagGroup *operator ->(){return &Flags;}; + HFX_INLINE const HFXStateFlagGroup *operator ->()const{return &Flags;}; + + HFX_INLINE HFXStateStorage *operator &(){return &Storage;}; + HFX_INLINE const HFXStateStorage *operator &()const{return &Storage;}; + + HFX_INLINE HFXStateStorage &operator =(HFXStateTransfer state){Storage = state; return Storage;} + HFX_INLINE HFXStateStorage &operator |=(HFXStateTransfer state){Storage |= state; return Storage;} + HFX_INLINE HFXStateStorage &operator &=(HFXStateTransfer state){Storage &= state; return Storage;} + HFX_INLINE HFXStateStorage &operator ^=(HFXStateTransfer state){Storage |= state; return Storage;} + HFX_INLINE HFXStateStorage operator ~()const{return ~Storage;} + HFX_INLINE HFXStateStorage operator |(HFXStateTransfer state){return (Storage|state);} + HFX_INLINE HFXStateStorage operator &(HFXStateTransfer state){return (Storage&state);} + HFX_INLINE HFXStateStorage operator ^(HFXStateTransfer state){return (Storage^state);} + HFX_INLINE bool operator ==(HFXStateTransfer state){return (Storage==state);} + HFX_INLINE bool operator !=(HFXStateTransfer state){return (Storage!=state);} + HFX_INLINE bool operator !(){return (Storage==0);} + HFX_INLINE operator bool(){return (Storage!=0);} + HFX_INLINE HFXStateFlags *UtilPointer(){return this;}; + HFX_INLINE const HFXStateFlags *UtilPointer()const{return this;}; + HFX_INLINE HFXStateFlags &Util(){return *this;}; + HFX_INLINE const HFXStateFlags &Util()const{return *this;}; +}; + +enum HFXNeeds +{ + //effect has a application thread time sync + HFXNEED_SYNC =(1 << 0), + //effect has a servo thread time update + HFXNEED_PROCESS =(1 << 1), + //effect takes parameters + HFXNEED_SET =(1 << 2), + //effect needs stack access + HFXNEED_STACK =(1 << 3), + //device slots. if you need a device you need a stack. + HFXNEED_DEVICE1 =(1 << 4), + HFXNEED_DEVICE2 =(1 << 5), + HFXNEED_DEVICE3 =(1 << 6), + HFXNEED_DEVICE4 =(1 << 7), + HFXNEED_DEVICE5 =(1 << 8), + HFXNEED_DEVICE6 =(1 << 9), + HFXNEED_DEVICE7 =(1 << 10), + HFXNEED_DEVICE8 =(1 << 11), + //ability to create/destroy sub effects + HFXNEED_MANAGE =(1 << 12), + //effect needs to know how long its been running. + HFXNEED_RUNTIME =(1 << 13), + //effect needs to know how long its been since the last time its processed a function. + HFXNEED_FRAMETIME =(1 << 14), + //effect needs a fixed time sent to its framtime + HFXNEED_FIXEDTIME =(1 << 15), + //effect has a init function + HFXNEED_INSTANCE =(1 << 16), + //effect needs owning stack's parent access + HFXNEED_PARENT =(1 << 17), + //effect is self deleting + HFXNEED_REMOVE =(1 << 18), + //effect does not give handles. these effects need to be self deleting + HFXNEED_ENCAPSULATED =(1 << 19), + + HFXNEED_EXIT =(1 << 20), + + //state change inform flags + HFXNEED_STATE_INFORM =(1 << 21), + HFXNEED_RUNNING_INFORM =(1 << 22), + HFXNEED_PAUSE_INFORM =(1 << 23), + HFXNEED_HAULT_INFORM =(1 << 24), + HFXNEED_MUTE_INFORM =(1 << 25), + HFXNEED_EXITING_INFORM =(1 << 26), + + // USE THE BELOW FLAGS TO DECLARE FEATURES TO A EFFECT CLASS WHEN REGISTERING + HFXNEED_DECL_SYNC =(HFXNEED_SYNC), + HFXNEED_DECL_PROCESS =(HFXNEED_PROCESS), + HFXNEED_DECL_STACK =(HFXNEED_STACK), + HFXNEED_DECL_DEVICE1 =(HFXNEED_DEVICE1|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE2 =(HFXNEED_DEVICE2|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE3 =(HFXNEED_DEVICE3|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE4 =(HFXNEED_DEVICE4|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE5 =(HFXNEED_DEVICE5|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE6 =(HFXNEED_DEVICE6|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE7 =(HFXNEED_DEVICE7|HFXNEED_DECL_STACK), + HFXNEED_DECL_DEVICE8 =(HFXNEED_DEVICE8|HFXNEED_DECL_STACK), + HFXNEED_DECL_RUNTIME =(HFXNEED_RUNTIME), + HFXNEED_DECL_FRAMETIME =(HFXNEED_FRAMETIME), + // there is no decl for HFXNEED_FIXEDTIME as it is pointless without + // a runtime or frametime decl. + HFXNEED_DECL_FIXEDFRAME =(HFXNEED_FRAMETIME|HFXNEED_FIXEDTIME), + HFXNEED_DECL_FIXEDRUNTIME =(HFXNEED_DECL_RUNTIME|HFXNEED_FIXEDTIME), + HFXNEED_DECL_MANAGE =(HFXNEED_DECL_FRAMETIME|HFXNEED_DECL_STACK), + HFXNEED_DECL_REMOVE =(HFXNEED_REMOVE), + HFXNEED_DECL_ENCAPSULATED =(HFXNEED_ENCAPSULATED|HFXNEED_DECL_REMOVE), + HFXNEED_DECL_PARENT =(HFXNEED_PARENT), + HFXNEED_DECL_INSTANCE =(HFXNEED_INSTANCE), + HFXNEED_DECL_SET =(HFXNEED_SET), + // there is no HFXNEED_STATE_INFORM declare as it would be pointless without a + // declaration of specific informs + HFXNEED_DECL_RUNNING_INFORM =(HFXNEED_RUNNING_INFORM|HFXNEED_STATE_INFORM), + HFXNEED_DECL_PAUSE_INFORM =(HFXNEED_PAUSE_INFORM|HFXNEED_STATE_INFORM), + HFXNEED_DECL_MUTE_INFORM =(HFXNEED_MUTE_INFORM|HFXNEED_STATE_INFORM), + HFXNEED_DECL_EXITING_INFORM =(HFXNEED_EXITING_INFORM|HFXNEED_STATE_INFORM), + HFXNEED_DECL_HAULT_INFORM =(HFXNEED_HAULT_INFORM|HFXNEED_STATE_INFORM), + // only use this if you will actually be using all informs! + HFXNEED_DECL_TOTAL_INFORM =( HFXNEED_RUNNING_INFORM|HFXNEED_PAUSE_INFORM| + HFXNEED_MUTE_INFORM|HFXNEED_EXITING_INFORM| + HFXNEED_STATE_INFORM), + // INFORMATION FLAGS + HFXNEED_INFO_DEVICE =( HFXNEED_DEVICE1|HFXNEED_DEVICE2| + HFXNEED_DEVICE3|HFXNEED_DEVICE4| + HFXNEED_DEVICE5|HFXNEED_DEVICE6| + HFXNEED_DEVICE7|HFXNEED_DEVICE8), +}; + +#define HFXNEED_UTIL_COUNT_DEVICES(flags) \ + ( ( ( (flags) & HFXNEED_INFO_DEVICE ) != 0) ? ( \ + ( ( ( (flags) & HFXNEED_DEVICE1 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE2 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE3 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE4 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE5 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE6 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE7 ) != 0) ? 1 : 0 ) + \ + ( ( ( (flags) & HFXNEED_DEVICE8 ) != 0) ? 1 : 0 ) ) \ + : 0 ) + +typedef unsigned __int32 HFXNEED; + +#define HFX_XCHANGE 16 +#define HFX_YCHANGE 17 +#define HFX_ZCHANGE 18 + +enum HFXResult +{ + HFXRESULT_ERROR =-2, + HFXRESULT_FINISHED =-1, + HFXRESULT_CONTINUE =0, + // x axis was set + HFXRESULT_XCHANGED =(1 << HFX_XCHANGE), + // y axis was set + HFXRESULT_YCHANGED =(1 << HFX_YCHANGE), + // z axis was set + HFXRESULT_ZCHANGED =(1 << HFX_ZCHANGE), + // x and y axis was set + HFXRESULT_XYCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_YCHANGED), + // x and z axis was set + HFXRESULT_XZCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_ZCHANGED), + // y and z axis was set + HFXRESULT_YZCHANGED =(HFXRESULT_YCHANGED|HFXRESULT_ZCHANGED), + // x and y axis was set + HFXRESULT_YXCHANGED =HFXRESULT_XYCHANGED, + // x and z axis was set + HFXRESULT_ZXCHANGED =HFXRESULT_XZCHANGED, + // y and z axis was set + HFXRESULT_ZYCHANGED =HFXRESULT_YZCHANGED, + // x, y and z axis set + HFXRESULT_XYZCHANGED =(HFXRESULT_XCHANGED|HFXRESULT_YCHANGED|HFXRESULT_ZCHANGED), + HFXRESULT_CHANGED =HFXRESULT_XYZCHANGED, +}; + +typedef int HFXRESULT; + + +class HFX_PURE_INTERFACE IHapticEffect +{ +public: + // return false if you decide the processor given to you is not sufficient + // or any other reason the effect should not be made. + // !called one time only. before any other funciton calls. + // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_INSTANCE + virtual bool Initialize(IHFXProcessor &processor)=0; + // called by the game thread and blocks the haptics thread so the game and haptics loop are safe inside. + // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_SYNC + virtual HFXRESULT SyncOp(IHFXProcessor &processor)=0; + //called at haptic rate. should set the output parameter to the target output force. + // calculation should optimized and precise in here. + // IF YOU WANT THIS TO BE CALLED YOU MUST REGISTER YOUR EFFECT WITH HFXNEED_DECL_PROCESS + virtual HFXRESULT Update(IHFXProcessor &processor)=0; + //return true if parameters sent to you are sufficient. + virtual bool Set(IHFXProcessor &processor, IHFXParamGroup *parameter)=0; + //notification of state change. + // WILL ONLY BE CALLED IF YOU DECLARE YOUR EFFECT REGISTER WITH A _INFORM decl and will ONLY be called with those. + // note: state will be only one bit. for every bit changed on sync this function will be called. + virtual void OnStateChange(IHFXProcessor &processor, HFXSTATE state, bool flagged)=0; +}; +typedef IHapticEffect IHFXEffect; + +typedef void (*hfxFilterFunction)(double outvect[3]); +typedef void (*HFXCreate_t)(IHFXEffect*&ptr); +typedef void (*HFXDestroy_t)(IHFXEffect*&ptr); + +template<typename T> +void HFXDefaultAllocateEffect(IHFXEffect *&ptr){ptr = new T;}; + +template<typename T> +void HFXDefaultDeallocateEffect(IHFXEffect *&ptr){if(!ptr)return; delete ((T*)ptr); ptr=0;}; + +class IHapticsSystem; +typedef IHapticsSystem IHFXSystem; +class IDevice; +typedef IDevice IHFXDevice; +class IStack; +typedef IStack IHFXStack; + +// T == effect class +template<typename T> +inline HFXEffectID HFXDefaultRegisterEffect(IHFXSystem &hfxSystem, const char *tag, HFXNEED needs, IHFXParamGroup *defaults, HFXCreate_t specialCreate = HFXDefaultAllocateEffect<T>, HFXDestroy_t specialDestroy = HFXDefaultDeallocateEffect<T> ) +{ + hfxSystem.LogMessage((const int)1,"EFFECT REGISTERING! %s Size = %i \n", tag, sizeof(T)); + return hfxSystem.RegisterEffectClass( + tag, + specialCreate, + specialDestroy, + needs, + defaults); +}; + +// T == effect class +// P == parametergroup class +template<typename T, typename P> +inline HFXEffectID HFXDefaultRegisterEffect(IHFXSystem &hfxSystem, const char *tag, HFXNEED needs, HFXCreate_t specialCreate = 0, HFXDestroy_t specialDestroy = 0) +{ + P *pGroup = new P; + HFXEffectID retval=0; + if(pGroup->CopyDefaults(pGroup)) + { + retval = HFXDefaultRegisterEffect<T>(hfxSystem, tag, needs, pGroup, specialCreate, specialDestroy); + } + delete pGroup; + return retval; +}; + +#endif +
\ No newline at end of file |