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.

707 lines
25 KiB

  1. #ifndef I_NOVINT_HFX
  2. #define I_NOVINT_HFX
  3. #define HFX_VERSION_MAJOR 0
  4. #define HFX_VERSION_MAJOR_SZ "0"
  5. #define HFX_VERSION_MINOR 5
  6. #define HFX_VERSION_MINOR_SZ "5"
  7. #define HFX_VERSION_FLOAT 0.5
  8. #include "util/HFXInterfaceHelper.h"
  9. //( NovintHFX )
  10. #include "HFXConfig.h"
  11. //( HFXClasses )
  12. namespace std{
  13. template<class _Ty>
  14. class allocator;
  15. template <class _Ty,
  16. class _Ax > class vector;
  17. };
  18. #if _MSC_VER < 1400
  19. #define VECTOR_TYPE(type) std::vector<type>
  20. #endif
  21. #if _MSC_VER >= 1400
  22. #define VECTOR_TYPE(type) ::std::vector<type, ::std::allocator<type> >
  23. #endif
  24. #pragma warning( disable : 4251 )
  25. class EffectTag;
  26. //ensure these are not int he NovintHFX namespace.
  27. #include "IHFXParam.h"
  28. #include "IHFXEffect.h"
  29. typedef int _declspec(dllimport) (*LinkHFX_Fn)( const char * password, const char *cmdline, void **effects, void **system );
  30. //temporarily disable warning regarding to data classes
  31. // needing external classes
  32. #pragma warning(disable:4661)
  33. //forward decl.
  34. class IDevice;
  35. class IStack;
  36. struct IBaseEffectParams;
  37. class IBaseEffect;
  38. //( HapticsMath )
  39. #include "Types/hfxVec3.h"
  40. //( HapticsSystem )
  41. struct IHapticEffectParamGroup;
  42. typedef IHapticEffectParamGroup IHFXParamGroup;
  43. typedef int DeviceIndex;
  44. typedef unsigned long hfxPreciseTime;
  45. typedef bool (*EnableMouseFn)( void );
  46. enum eMouseMove
  47. {
  48. eHFXMM_Delta=0,
  49. eHFXMM_Absolute=0,
  50. };
  51. enum eMouseButton
  52. {
  53. eHFXMM_1232=0,//1=left 2=right 3=middle 4=right
  54. eHFXMM_1111,//1=left 2=left 3=left 4=left
  55. eHFXMM_1342,//1=left 2=middle 3=4th 4=right
  56. eHFXMM_None,
  57. };
  58. enum eMouseMethod
  59. {
  60. eHFXMouseMeth_OSInput=0,
  61. eHFXMouseMeth_fMouse,
  62. eHFXMouseMeth_useCallback,
  63. eHFXMouseMeth_smartDelta,
  64. eHFXMouseMeth_delta,
  65. eHFXMouseMeth_COUNT,
  66. };
  67. enum eMouseClick
  68. {
  69. eHFXMC_Left=0,
  70. eHFXMC_Right,
  71. eHFXMC_Middle,
  72. eHFXMC_Fourth,
  73. eHFXMC_COUNT,
  74. };
  75. typedef bool (*MouseEmulationFn)( const double &devicex_pos,
  76. const double &devicey_pos,
  77. const double &devicez_pos,
  78. const double &devicex_delta,
  79. const double &devicey_delta,
  80. const double &devicez_delta,
  81. const int &buttons_down,
  82. const int &buttons_pressed,
  83. const int &buttons_released,
  84. bool moved,
  85. /* adjust if you would liek to send a mouse button */
  86. bool buttonsDown[eHFXMC_COUNT]
  87. );
  88. struct ApplicationData
  89. {
  90. };
  91. typedef void (*RollCallIndexSetCallBack)(IDevice *pDevice, const int devices_left);
  92. class HFX_PURE_INTERFACE IHapticsSystem
  93. {
  94. public:
  95. // call this method prior to shutting down the game.
  96. virtual void ShutDown(bool hard=false) =0;
  97. // THIS FUNCTION MUST BE CALLED BY YOUR APPLICATION AND RETURN TRUE PRIOR TO CREATING A DEVICE!
  98. // window = the HWND of the program.
  99. // returns weather or not the applicationdata was sufficent.
  100. virtual bool AttachApplication(ApplicationData &app) =0;
  101. virtual bool AttachApplicationByProcessName(ApplicationData &app, const char *szProcessName) =0;
  102. // If you want to use more than 1 device set this before. NOTE: for multiple devices you must use device lock
  103. //HFX_VIRTUAL bool SetOptionalDeviceCount( unsigned int nDevices );
  104. // Use this function to create a device. (note: when making multiple devices they must be connected in numerical order.)
  105. virtual bool RunDevice(IDevice **ppDevice, const char *deviceName=0, const char *configDir=0) =0;
  106. // When using multiple devices you _MUST_ lock devices after device connection attempts are made.
  107. virtual void LockDevices() =0;
  108. // When using mutliple devices you _MUST_ unlock devices once they are locked to connect more devices and then lock again afterwards.
  109. virtual void UnlockDevices() =0;
  110. // Note: this will return the max number of devices specified in the constructor of HapticsSystem.
  111. virtual unsigned int GetTargetDeviceCount() const =0;
  112. // connects multiple devices at once. returns number of devices connected.
  113. // if targetNumber==-1 then all connected devices will be ran.
  114. virtual int RunMultipleDevices(const int targetNumber=-1) =0;
  115. // returns true if device was stopped.
  116. virtual bool StopRunningDevice(IDevice **ppDevice) =0;
  117. // returns true if all instances were stopped.
  118. virtual bool StopAllRunningDevices() =0;
  119. //this will ask the user to press a button on each device. the order in which they
  120. // press a button on each connected device will order their device id from zero to the number
  121. // of falcons the user has minus one.
  122. // note: without roll call devices are ordered by their serial number.
  123. // returns false if only one falcon is connected.
  124. virtual bool RollCallDevices(RollCallIndexSetCallBack CallBackFn=0,bool bCreateThread=false) =0;
  125. // will return true untill roll call is over.
  126. virtual bool IsInRollCall() const =0;
  127. // updates roll call data. only call this if your in a roll call and the roll call was not started
  128. // with bCreateThread set to true.
  129. // returns true if still in roll call.
  130. virtual bool RollCallUpdate() =0;
  131. // cancles roll call in progress. if ApplyMadeChanges is true the devices who responded
  132. // to the roll call will be set in and the unset will be moved to the end of the index list.
  133. virtual bool StopRollCall(bool ApplyMadeChanges=false) =0;
  134. //only call this ONCE per game input tick.
  135. // returns number of devices updated.
  136. virtual int InputUpdate();
  137. //void SetMouseMode(HWND window,eHFXMouseMove MoveMode=eHFXMM_Delta,eHFXMouseButton ButtonMode=eHFXMM_1232);
  138. virtual void SetMouseMode(eMouseMove MoveMode=eHFXMM_Delta,eMouseButton ButtonMode=eHFXMM_1232) =0;
  139. virtual void StartMouse(IDevice *pDev) =0;
  140. virtual void StartMouse(const DeviceIndex device) =0;
  141. virtual void StartMouse() =0;
  142. virtual void MouseUpdate() =0;
  143. virtual void StopMouse() =0;
  144. // returns if we are in cursor emulation. If pDevice is null it will return weather any device is in mouse emulation.
  145. virtual bool IsMouseMode(const IDevice *pDevice=0) =0;
  146. //returns true if forces are allowed.
  147. virtual bool ForcesAllowed() =0;
  148. //returns true if input is allowed.
  149. virtual bool InputAllowed() =0;
  150. //returns true if forces are enabled.
  151. // Note: this could be true and forces may not be allowed.
  152. // MouseMode RollCall window focus and possibly other things will not allow forces.
  153. virtual bool ForcesEnabled() =0;
  154. //HFX_VIRTUAL void DisableForces() HFX_PURE;
  155. //HFX_VIRTUAL void EnableForces() HFX_PURE;
  156. //returns device of index nDevice
  157. virtual IDevice *GetRunningDeviceByIndex(const DeviceIndex nDevice) const =0;
  158. //returns device on hardware index.
  159. virtual IDevice *GetRunningDeviceByHardwareIndex(const int nSerialOrder) const =0;
  160. //returns number of running devices.
  161. virtual int RunningDeviceCount() const =0;
  162. //returns number of devices connected to the users computer.
  163. virtual int ConnectedDeviceCount() const =0;
  164. // this will re count available devices.
  165. // use ConnectedDeviceCount() to get the count.
  166. virtual void RecountConnectedDevices() =0;
  167. virtual bool AllocateEffectParameter(IHFXParamGroup *&pIEffectParam, HFXEffectID associatedClass, const char *copyCachedSettings=0, const char *storageName=0) =0;
  168. HFX_INLINE bool AllocateEffectParameter(IHFXParamGroup *&pIEffectParam, const char *copyCachedSettings=(const char*)0, const char *storageName=0 ){return AllocateEffectParameter(pIEffectParam, 0, copyCachedSettings, storageName);}
  169. virtual bool DeallocateEffectParameter(IHFXParamGroup *&ppIEffectParam) =0;
  170. virtual unsigned int GetCachedParameterCount() const =0;
  171. virtual IHFXParamGroup *GetCachedParameter(const char *name) =0;
  172. virtual IHFXParamGroup *GetCachedParameter(const unsigned int name) =0;
  173. virtual const char *GetCachedParameterName(const unsigned int id) const =0;
  174. // Note: any format ( besides Bitfile ) where it cannot find the file specified will try to
  175. // load a encoded bitfile if it does not exist. A bit file will be generated when you load any
  176. // format. When release time comes around just delete the iniFile and include the bitfile output
  177. // each format has a way to turn this functionality off. if you
  178. virtual bool CacheEffectParametersINI( const char *iniFile ) =0;
  179. virtual bool CacheEffectParametersBitfile( const char *bitFile ) =0;
  180. // will add .nvnt extension
  181. virtual bool SaveCache( const char *file ) =0;
  182. //HFX_VIRTUAL bool LoadHFXModule( const char *moduleName, const char *modulePassword=0 ) HFX_PURE;
  183. virtual hfxPreciseTime GetBaseTime() const =0;
  184. virtual hfxPreciseTime GetRunTime() const =0;
  185. virtual double GetRunTimeSeconds() const =0;
  186. virtual double GetBaseTimeSeconds() const =0;
  187. virtual bool CreateNewEffectStack(const char *uniqueName, IStack**ppStack, unsigned int inputDevices=0) =0;
  188. virtual bool DeleteEffectStack(IStack**ppStack) =0;
  189. virtual IStack* FindEffectStack(const char *name) =0;
  190. //command support
  191. //HFX_VIRTUAL int RunCommand( const char *cmd ) HFX_PURE;
  192. //HFX_VIRTUAL bool InitFromXML(ApplicationData &appdata,unsigned int &devices, const char *xmlLoc) HFX_PURE;
  193. virtual int LogMessage(const int type, const char *fmt, ...);
  194. virtual int LogMessage(const char *fmt, ...);
  195. virtual bool SetMouseEmulation( eMouseMethod method ) =0;
  196. virtual bool SetMouseEmulationFunction( MouseEmulationFn method_function ) =0;
  197. #ifndef HFX_INTERNAL
  198. inline bool SetMouseEmulation( MouseEmulationFn method_function ){if(!method_function) return false; return ( SetMouseEmulation(eHFXMouseMeth_useCallback) && SetMouseEmulationFunction(method_function)); }
  199. #endif
  200. virtual bool ScaleDeviceCoordsForCursor( double &x, double &y, double width=-1, double height=-1, double offsetx=-1, double offsety=-1 ) =0;
  201. // try and put device to sleep. if null all devices will try to sleep. devices will sleep untill touched.
  202. virtual void AttemptSlumber(IDevice *device=0) =0;
  203. virtual void ActivateDynamicWindowHandler(const char *windowClassName, const char *windowText, unsigned int msHeartInterval=70) =0;
  204. virtual void DeactivateDynamicWindowHandler() =0;
  205. virtual bool IsDynamicWindowHandlerRunning() const =0;
  206. virtual HFXEffectID RegisterEffectClass(const char *tag, HFXCreate_t alloc, HFXDestroy_t dealloc, HFXNEED needs, IHFXParamGroup *defaults=0) =0;
  207. #define HFX_NON_ELEMENT 0xFFFFF0
  208. virtual bool SetParameterGroupVar(IHFXParamGroup &params, HFXParamID var, const char *string, unsigned int element=HFX_NON_ELEMENT) =0;
  209. virtual bool SetParameterGroupVar(IHFXParamGroup &params, const char *varString, const char *string, unsigned int element=HFX_NON_ELEMENT) =0;
  210. virtual HFXEffectID LookupEffectIDByName(const char *name) const =0;
  211. virtual const char *LookupEffectNameByID(HFXEffectID id) const =0;
  212. // only call if explicit stack syncs are enabled
  213. virtual void SyncEffectStacks() =0;
  214. virtual HFXParamID EnumerateEffectParameters( HFXEffectID id, HFXParamID LastParamID ) =0;
  215. virtual bool CacheEffectParameterGroupCopy(const char *cachename, IHFXParamGroup *params) =0;
  216. virtual bool SaveEffectParameterCache(const char *filename, const char *type = "ini") =0;
  217. virtual void DoReport() =0;
  218. };
  219. //( HapticsDevice )
  220. //HFX BUTTON DEFINES : Based on HDL Button Defines.
  221. #define HFX_BUTTON_1 0x00000001 /**< Mask for button 1 */
  222. #define HFX_BUTTON_2 0x00000002 /**< Mask for button 2 */
  223. #define HFX_BUTTON_3 0x00000004 /**< Mask for button 3 */
  224. #define HFX_BUTTON_4 0x00000008 /**< Mask for button 4 */
  225. #define HFX_BUTTON_ANY 0xffffffff /**< Mask for any button */
  226. //Internal class.
  227. struct HFX_PURE_INTERFACE IDeviceData
  228. {
  229. };
  230. namespace NovintHFX{
  231. class Device;
  232. class Stack;
  233. namespace Effects{
  234. struct command_info;
  235. int ProcessCommand( IBaseEffect *pEffect, const char *argv[], const unsigned int argc );
  236. }
  237. };
  238. // This function callback type will be used with SetServoLoopCallbackFunction.
  239. // The main difference between hdlServoOp and this is that you get the device.
  240. typedef int (*OldServoLoopFn) (void *pParam, class IDevice *pDevice, double outforces[3]);
  241. class HFX_PURE_INTERFACE IDevice
  242. {
  243. public:
  244. //Is this device able to output forces?
  245. virtual bool AcceptingForces() const =0;
  246. //The device is connected.
  247. virtual bool IsConnected() const =0;
  248. //Sets pos to the tool Position.
  249. virtual void GetToolPosition(double pos[3]) const =0;
  250. virtual void GetToolPositionWorkspace(double pos[3]) const =0;
  251. virtual void GetButtonData(int *down=0, int *pressed=0, int *released=0) const =0;
  252. virtual void GetCurrentForce(double force[3]) const =0;
  253. virtual bool IsButtonDown( int nButton ) const =0;
  254. virtual IStack *GetEffectStack() =0;
  255. virtual const DeviceIndex GetIndex() const =0;
  256. virtual int GetHardwareIndex() const =0;
  257. virtual void InputUpdate() =0;
  258. virtual bool ConnectStack( IStack *stack ) =0;
  259. virtual bool DisconnectStack( IStack *stack ) =0;
  260. // This function is here for quick integration into games which already have a few custom
  261. // effects of their own. Taking the old ServoOp function and adding in pDevice
  262. virtual void SetServoLoopCallbackFunction( OldServoLoopFn old_fn, void *pParam ) =0;
  263. // you should never call this unless your in a callback running on servo.
  264. virtual void _GetServoData(double toolpos[3], int &buttons) =0;
  265. virtual __int64 GetSerialNumber() const =0;
  266. virtual BoundingBox3 GetWorkspace() const =0;
  267. virtual void SetEngineData(void *data) =0;
  268. virtual void *GetEngineData() const =0;
  269. virtual bool HasRested( unsigned int msDur=1 ) const =0;
  270. virtual bool IsSleeping(bool justForces=false) const =0;
  271. virtual bool TriggerFade(unsigned int msMuteTime, unsigned int msDuration, bool forceOverride=false) =0;
  272. virtual void ForceSlumber() =0;
  273. virtual void SetForceScale(const double &scale) =0;
  274. virtual double GetForceScale() const =0;
  275. };
  276. //( HapticsStack )
  277. class Processor;
  278. //EFFECT STACK
  279. //note one stack per device handle only.
  280. class HFX_PURE_INTERFACE IStack
  281. {
  282. public:
  283. // Returns true if effect was created.
  284. // --
  285. // NOTE: NOT ALL EFFECTS ( SUCH AS SELF DELETING )
  286. // WILL ALLOW YOU TO HAVE A HANDLE TO IT.
  287. // CHECKING POINTER VALIDITY OF THE HANDLE IN THE
  288. // CREATE NEW EFFECT WILL ONLY LET YOU KNOW IF
  289. // ANYTHING WAS SET TO IT, NOT NECCISARILLY IF
  290. // THE EFFECT WAS CREATED.
  291. // --
  292. virtual bool CreateCachedEffect(IHFXEffect *&pHandle, const char *entry, const char *instancename=0 );
  293. template<typename T>
  294. HFX_INLINE bool CreateCachedEffect(T *&pTypedHandle, const char *entry, const char *instanceName=0)
  295. {
  296. return CreateCachedEffect((IHFXEffect*&)pTypedHandle, entry, instanceName);
  297. }
  298. HFX_INLINE bool CreateCachedEffect(const char *entry){ return CreateCachedEffect(hfxNoHandle, entry); }
  299. virtual bool CreateNewEffect(IHFXEffect *&ppHandle, HFXEffectID effectName, IHFXParamGroup *params, const char *instanceName=0);
  300. template<typename T>
  301. HFX_INLINE bool CreateNewEffect(T *&pTypedHandle, HFXEffectID effectName, IHFXParamGroup *params, const char *instanceName=0)
  302. {
  303. return CreateNewEffect((IHFXEffect*&)pTypedHandle, effectName, params, instanceName);
  304. }
  305. HFX_INLINE bool CreateNewEffect(HFXEffectID effectName, IHFXParamGroup *params){ return CreateNewEffect(hfxNoHandle, effectName, params, 0); };
  306. // Returns NULL if there was no effect using that name.
  307. // --
  308. // NOTE: YOU SHOULD ONLY HAVE ONE HANDLE OF A EFFECT
  309. // IN AS A MEMBER VARIABLE ( NON LOCAL ). OTHERWISE
  310. // YOU RISK INVALID POINTERS IF YOU DELETE THE EFFECT.
  311. // WITH A SECOND REFERENCE.
  312. virtual IHFXEffect *FindRunningEffect(const char *instanceName) const =0;
  313. // Returns true if effect was deleted
  314. // --
  315. // NOTE: THIS IS ONLY FOR EFFECTS WHICH NEED TO BE
  316. // DELETED MANUALLY. MANY EFFECTS WILL DELETE
  317. // THEMSELFS AND THOSE EFFECTS YOU SHOULD NOT
  318. // EVER RECEIVE HANDLES FOR.
  319. // --
  320. virtual bool DeleteRunningEffect(IHFXEffect *&effect) =0;
  321. template<typename T>
  322. HFX_INLINE bool DeleteRunningEffect(T *&pTypedEffect)
  323. {
  324. return DeleteRunningEffect((IHFXEffect*&)pTypedEffect);
  325. }
  326. virtual void GetLastForce(double force[3])const =0;
  327. virtual void SetDeviceLock(bool state) =0;
  328. virtual bool IsDeviceListLocked() const =0;
  329. // returns true if device was added or is already a member. if slot is -1 it will just enter the device
  330. // as the next available slot.
  331. virtual bool AddDevice(IDevice*pDevice, int slot=-1) =0;
  332. // returns the device in slot
  333. virtual IDevice *GetDeviceInSlot(unsigned int id=0) const =0;
  334. virtual void GetCalclatedForces(double force[3]) =0;
  335. virtual const char *Name() const =0;
  336. //command support
  337. //HFX_VIRTUAL int RunCommand( const char *cmd ) HFX_PURE;
  338. virtual void *GetUserData() const =0;
  339. virtual void SetUserData(void*data) =0;
  340. virtual void SetVolume( const double &scale ) =0;
  341. virtual double GetVolume() const =0;
  342. virtual unsigned int GetTargetDeviceCount() const =0;
  343. virtual void SetEngineData(void *data) =0;
  344. virtual void *GetEngineData() const =0;
  345. virtual void SetEffectUserData(IHFXEffect *pEffect, void *pData) =0;
  346. virtual void *GetEffectUserData(IHFXEffect *pEffect) =0;
  347. };
  348. //( HapticsEffect )
  349. struct HFX_PURE_INTERFACE IRegister
  350. {
  351. public:
  352. virtual void AllocateEffect(IHFXEffect *&pEffectPtr) =0;
  353. virtual void DeallocateEffect(IHFXEffect *&pEffectPtr) =0;
  354. virtual void AllocateParameterGroup(IHFXParamGroup *&pEffectPtr) =0;
  355. virtual void DeallocateParameterGroup(IHFXParamGroup *&pEffectPtr) =0;
  356. virtual const char *GetTagName() const =0;
  357. };
  358. #define HFX_PROCESSOR_PARAM_FORCESCALE 4294967293
  359. #define HFX_PROCESSOR_PARAM_TIMESCALE 4294967294
  360. class HFX_PURE_INTERFACE IProcessor
  361. {
  362. public:
  363. // call this to mute and unmute this effect. (note: effect will still be updated, just will not output force.)
  364. // note : this setting will not be applied untill the next sync op ( InputUpdate ) called by the application.
  365. virtual void SetMuted(bool mute) =0;
  366. virtual void SetPaused(bool pause) =0;
  367. // see if the effect is muted.
  368. HFX_INLINE bool IsMuted() const { return ((GetEffectState() & HFXSTATE_MUTE)!=0); }
  369. // see if the effect is explicitly paused.
  370. HFX_INLINE bool IsPaused() const { return ((GetEffectState() & HFXSTATE_PAUSE)!=0); }
  371. // scale this force (NOTE: THIS IS SEPERATE FROM PARAMETER SCALE!)
  372. virtual void SetForceScale( double scale ) =0;
  373. virtual double GetForceScale( ) const =0;
  374. virtual const char *GetEffectTypeName() const =0;
  375. // override this function to return the number of falcons this
  376. // effect requires.
  377. HFX_INLINE unsigned int RequiredDeviceCount() const
  378. {
  379. HFXNEED needs= GetEffectNeeds();
  380. return HFXNEED_UTIL_COUNT_DEVICES(needs);
  381. }
  382. // returns true if the effect is running.
  383. HFX_INLINE bool IsRunning() const {return ( (GetEffectState() & (HFXSTATE_RUNNING)) != 0 );}
  384. // if your effect is not self deleting and requires runtime data you should override this to true.
  385. HFX_INLINE bool CanBeHandled() const { return (GetEffectNeeds() & HFXNEED_ENCAPSULATED)==0; }
  386. // this lets the haptic effect stack know you are done with this effect and it is waiting to be deleted.
  387. // CANNOT BE OVERRIDDEN ( see OnFlaggedForRemoval() )
  388. virtual void FlagForRemoval() =0;
  389. //Stack functions!
  390. friend class NovintHFX::Stack;
  391. friend int NovintHFX::Effects::ProcessCommand( IBaseEffect *pEffect, const char *argv[], const unsigned int argc );
  392. // do not use.
  393. //HFX_VIRTUAL bool Stop() HFX_PURE;
  394. // DO NOT OVERRIDE!
  395. HFX_INLINE bool NeedsRemoval() const
  396. { return ( ( GetEffectNeeds() & HFXNEED_REMOVE ) ? ( ( ( GetEffectState() & HFXSTATE_RUNNING ) ) ? false : true ) : false ); }
  397. // DO NOT OVERRIDE!
  398. HFX_INLINE bool WantsSyncOp() const
  399. {
  400. return (((GetEffectNeeds() & HFXNEED_SYNC)!=0) && ((GetEffectState() & HFXSTATE_WANT_SYNC)!=0));
  401. }
  402. // DO NOT OVERRIDE!
  403. virtual bool WantsUpdate() const {return (((GetEffectNeeds() & HFXNEED_PROCESS)!=0) && ((GetEffectState() & HFXSTATE_WANT_UPDATE)!=0) && ((GetEffectState() & HFXSTATE_RUNNING)!=0));}
  404. virtual HFXSTATE GetEffectState() const =0;
  405. virtual const HFXNEED &GetEffectNeeds() const =0;
  406. virtual void *_output() const =0;
  407. virtual const double &Runtime() const =0;
  408. virtual const double &Frametime() const =0;
  409. virtual IStack *GetStack() =0;
  410. virtual IHFXSystem *GetSystem() =0;
  411. virtual void *GetUserData() =0;
  412. virtual void SetUserData(void *userData) =0;
  413. HFX_INLINE hfxVec3 &Output() { return *(reinterpret_cast<hfxVec3*>(_output())); }
  414. HFX_INLINE const hfxVec3 &Output() const{return *(reinterpret_cast<const hfxVec3*>(_output()));}
  415. HFX_INLINE double &operator[](int i){ return (Output().m[i]); };
  416. HFX_INLINE const double &operator[](int i)const{ return (Output()[i]); };
  417. HFX_INLINE bool IsOutputValid() const { return !IsOutputNaN();}
  418. HFX_INLINE bool IsOutputNaN() const { const double *o=Output(); return(o[0]!=o[0]||o[1]!=o[1]||o[2]!=o[2]);}
  419. HFX_INLINE hfxVec3 &operator =(const hfxVec3 &vect){hfxVec3 &out = Output(); out = vect; return out;}
  420. };
  421. typedef IProcessor IHFXProcessor;
  422. typedef char HFX_VarType;
  423. #define HFX_Double 'd'
  424. #define HFX_Float 'f'
  425. #define HFX_Int 'i'
  426. #define HFX_Bool 'b'
  427. #define HFX_Other 'o'
  428. #define HFX_Pointer 'p'
  429. #define HFX_Null 0
  430. #pragma warning( default : 4251 )
  431. #ifdef HFX_MODULE_LAYER
  432. #include HFX_MODULE_LAYER
  433. #endif
  434. #define ConnectNovintHFX YOU_MUST_INCLUDE_WINDOWS_PRIOR_TO_INCLUDING_INovintHFX_h
  435. #endif
  436. // to connect windows.h must be included
  437. #if ( !defined(I_NOVINT_HFX_WINDOWS) && ( defined(_INC_WINDOWS) || defined(LoadLibrary) && defined(HMODULE) ) ) && !defined(STATIC_IHFX)
  438. #define I_NOVINT_HFX_WINDOWS
  439. #ifdef ConnectNovintHFX
  440. #undef ConnectNovintHFX
  441. #endif
  442. extern HMODULE dllNovintHFX_;
  443. extern IHapticsSystem *_hfx;
  444. //quick helper class to ensure novint hfx unloads properly.
  445. struct NovintHFXCloseHelper
  446. {
  447. NovintHFXCloseHelper() : forceSkipQuit(false)
  448. {
  449. static bool ONE_INSTANCE_ONLY=true;
  450. if(!ONE_INSTANCE_ONLY)
  451. {
  452. #ifdef _DEBUG
  453. // look at the call stack and please remove whatever is calling this constructor.
  454. // there should be only one HFX_INIT_VARS.
  455. DebugBreak();
  456. #endif
  457. ExitProcess(100);
  458. }
  459. ONE_INSTANCE_ONLY = false;
  460. };
  461. bool forceSkipQuit;
  462. ~NovintHFXCloseHelper()
  463. {
  464. if(!forceSkipQuit&&_hfx)
  465. {
  466. _hfx->ShutDown(true);
  467. }
  468. };
  469. };
  470. extern NovintHFXCloseHelper _hfx_close;
  471. #define HFX_INIT_VARS() \
  472. HMODULE dllNovintHFX_=0; \
  473. IHapticsSystem *_hfx =0; \
  474. NovintHFXCloseHelper _hfx_close;
  475. // if windows is included heres a inline function to get the interface!
  476. inline bool ConnectNovintHFX( IHapticsSystem **ppSystem, void *window, const char *cmd, void*pCursorEnableFn=0, unsigned int TargetDevices=1)
  477. {
  478. if(ppSystem==0)
  479. return false;
  480. char szNovintDir[ MAX_PATH ];
  481. char szNovintDll[ MAX_PATH ];
  482. if ( GetEnvironmentVariableA( "NOVINT_DEVICE_SUPPORT", szNovintDir, sizeof( szNovintDir ) ) == 0 || !V_IsAbsolutePath( szNovintDir ) )
  483. {
  484. return false;
  485. }
  486. unsigned int tries = 0;
  487. while(dllNovintHFX_==0)
  488. {
  489. const char *dllName = HFX_DYNAMIC_LIBRARY_NAME(tries);
  490. if(!dllName)
  491. break;
  492. V_sprintf_safe( szNovintDll, "%s\\bin\\%s", szNovintDir, dllName );
  493. dllNovintHFX_ = LoadLibraryA( szNovintDll );
  494. if(!dllNovintHFX_)
  495. tries++;
  496. }
  497. NovintHFX_ExposeInterfaceFn connectFn = 0;
  498. if(dllNovintHFX_)
  499. {
  500. connectFn = (NovintHFX_ExposeInterfaceFn)GetProcAddress(dllNovintHFX_, HFX_CONNECT_FUNCTION_NAME());
  501. }
  502. if(!connectFn){
  503. // if direct load failed..
  504. if(dllNovintHFX_)
  505. {
  506. FreeLibrary(dllNovintHFX_);
  507. }
  508. V_sprintf_safe( szNovintDll, "%s\\bin\\%s", szNovintDir, "hfx.dll" );
  509. dllNovintHFX_ = LoadLibraryA( szNovintDll );
  510. if(dllNovintHFX_)
  511. {
  512. connectFn = (NovintHFX_ExposeInterfaceFn)GetProcAddress(dllNovintHFX_, "CreateHFX");
  513. }
  514. }
  515. if(connectFn&&connectFn((void **)ppSystem, window, cmd, HFX_VERSION_MAJOR, HFX_VERSION_MINOR, pCursorEnableFn, TargetDevices )==0)
  516. {
  517. _hfx = (*ppSystem);
  518. return true;
  519. }
  520. return false;
  521. }
  522. #ifndef HFX_STRIPPED
  523. inline bool ConnectNovintHFX_XML( IHapticsSystem **ppSystem, void *window, const char *xml, void*pCursorEnableFn=0, unsigned int TargetDevices=1)
  524. {
  525. if(ppSystem==0)
  526. return false;
  527. char szNovintDir[ MAX_PATH ];
  528. char szNovintDll[ MAX_PATH ];
  529. if ( GetEnvironmentVariable( "NOVINT_DEVICE_SUPPORT", szNovintDir, sizeof( szNovintDir ) ) == 0 || !V_IsAbsolutePath( szNovintDir ) )
  530. {
  531. return false;
  532. }
  533. unsigned int tries = 0;
  534. while(dllNovintHFX_==0)
  535. {
  536. const char *dllName = HFX_DYNAMIC_LIBRARY_NAME(tries);
  537. if(!dllName)
  538. break;
  539. V_sprintf_safe( szNovintDll, "%s\\bin\\%s", szNovintDir, dllName );
  540. dllNovintHFX_ = LoadLibraryA( szNovintDll );
  541. if(!dllNovintHFX_)
  542. tries++;
  543. }
  544. NovintHFX_ExposeInterfaceFn connectFn = 0;
  545. if(dllNovintHFX_)
  546. {
  547. connectFn = (NovintHFX_ExposeInterfaceFn)GetProcAddress(dllNovintHFX_, HFX_CONNECT_FUNCTION_NAME_XML());
  548. }
  549. if(!connectFn){
  550. if(dllNovintHFX_)
  551. {
  552. FreeLibrary(dllNovintHFX_);
  553. dllNovintHFX_=0;
  554. }
  555. V_sprintf_safe( szNovintDll, "%s\\bin\\%s", szNovintDir, "hfx.dll" );
  556. dllNovintHFX_ = LoadLibraryA( szNovintDll );
  557. if(dllNovintHFX_)
  558. {
  559. connectFn = (NovintHFX_ExposeInterfaceFn)GetProcAddress(dllNovintHFX_, "CreateHFX_XML");
  560. }
  561. }
  562. if(connectFn&&connectFn((void **)ppSystem, window, xml, HFX_VERSION_MAJOR, HFX_VERSION_MINOR, pCursorEnableFn, TargetDevices )==0)
  563. {
  564. _hfx = (*ppSystem);
  565. return true;
  566. }
  567. return false;
  568. }
  569. #endif
  570. inline bool ConnectNovintHFX( IHapticsSystem **ppSystem, HWND hwnd, const char *cmd, void*pCursorEnableFn=0, unsigned int TargetDevices=1 ){ return ConnectNovintHFX( ppSystem, (void*)hwnd, cmd, pCursorEnableFn, TargetDevices); }
  571. inline void DisconnectNovintHFX(IHapticsSystem **ppSystem=0)
  572. {
  573. if(dllNovintHFX_&&_hfx)
  574. {
  575. IHapticsSystem *pTemp = _hfx;
  576. _hfx = 0;
  577. _hfx_close.forceSkipQuit=true;
  578. if(ppSystem)
  579. {
  580. *ppSystem = 0;
  581. }
  582. pTemp->ShutDown();
  583. if(FreeLibrary(dllNovintHFX_))
  584. {
  585. dllNovintHFX_ = 0;
  586. }
  587. }
  588. }
  589. #endif