1 /****************************************************************************
3 Module name: SWFF_LIB.cpp
5 (C) Copyright Microsoft Corp. 1993. All rights reserved.
7 You have a royalty-free right to use, modify, reproduce and
8 distribute the Library Files (and/or any modified version) in
9 any way you find useful, provided that you agree that
10 Microsoft has no warranty obligations or liability for any
11 Sample Application Files which are modified.
14 Purpose: This module provides routines to simplify creating Effects
15 using the DirectInput Force Feedback subsystem.
19 Version Date Author Comments
20 ------- --------- ------ --------
22 15-Apr-97 MEA Moved prototype SWFF_SetDuration to sw_force.h
23 16-Apr-97 DMS Added SWFF_CreateEffectFromVFXEx
24 14-May-97 DMS Added SWFF_PutRawAxisForce
25 and SWFF_CreateRawAxisForceEffect
26 22-May-97 DMS Added SWFF_CreateEffectFromVFX2
27 and SWFF_CreateEffectFromVFX2Ex
28 and SWFF_CreateEffectFromVFXBuffer
31 ****************************************************************************/
37 #include "sw_force.h" // SideWinder Force Feedback Header File
39 #define INITGUIDS // Make GUID available
40 #include "sw_guid.hpp"
45 BOOL CALLBACK DIEnumAndDestroyCreatedEffectsProc(LPDIRECTINPUTEFFECT pDIEffect, LPVOID lpvRef);
46 BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID lpvContext);
49 // ----------------------------------------------------------------------------
51 // ***** FUNCTIONS ************************************************************
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
56 // Function: SWFF_OpenDefaultFFJoystick
57 // Parameters: HWND hWnd - Client Window Handle
58 // LPDIRECTINPUT* ppDI - Pointer to DIRECTINPUT
59 // LPDIRECTINPUTDEVICE2* ppDIDevice) - Pointer to IDIRECTINPUTDEVICE2
64 // ----------------------------------------------------------------------------
65 HRESULT SWFF_OpenDefaultFFJoystick(
68 LPDIRECTINPUTDEVICE2* ppDIDevice)
71 if(hWnd == NULL || ppDI == NULL || ppDIDevice == NULL)
73 return SFERR_INVALID_PARAM;
76 // create the DirectInput object
77 hResult = DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, ppDI, NULL);
81 // enumerate the first attached joystick
82 // instance goes in pDIDeviceInstance
83 DIDEVICEINSTANCE DIDeviceInstance;
84 DIDeviceInstance.dwDevType = 0;
85 hResult = (*ppDI)->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc, &DIDeviceInstance, DIEDFL_FORCEFEEDBACK);
92 if(DIDeviceInstance.dwDevType == 0)
96 return DIERR_DEVICENOTREG;
99 // create the DirectInput Device object
100 LPDIRECTINPUTDEVICE pDIDevice = NULL;
101 hResult = (*ppDI)->CreateDevice(DIDeviceInstance.guidInstance, &pDIDevice, NULL);
109 // get a pointer to its DirectInputDevice2 interface
110 hResult = pDIDevice->QueryInterface(IID_IDirectInputDevice2, (void**)ppDIDevice);
113 pDIDevice->Release();
119 pDIDevice->Release();
122 // set the data format to the pre-defined DirectInput joystick format
123 hResult = (*ppDIDevice)->SetDataFormat(&c_dfDIJoystick);
126 (*ppDIDevice)->Release();
133 // set the cooperative level
134 hResult = (*ppDIDevice)->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
137 (*ppDIDevice)->Release();
144 // turn auto-center off
145 /* DIPROPDWORD DIPropAutoCenter;
146 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
147 DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
148 DIPropAutoCenter.diph.dwObj = 0;
149 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
150 DIPropAutoCenter.dwData = 0;
152 hResult = (*ppDIDevice)->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
155 (*ppDIDevice)->Release();
162 // acquire the joystick
163 hResult = (*ppDIDevice)->Acquire();
166 (*ppDIDevice)->Release();
176 // ----------------------------------------------------------------------------
177 // Function: SWFF_OpenDefaultFFJoystickEx
178 // Parameters: HWND hWnd - Client Window Handle
179 // LPDIRECTINPUT* ppDI - Pointer to IDIRECTINPUT
180 // HINSTANCE hInstance - object instance handle
181 // LPDIRECTINPUTDEVICE2* ppDIDevice) - Pointer to IDIRECTINPUTDEVICE2
182 // DWORD dwFlags - DISCL_EXCLUSIVE | DISCL_FOREGROUND
187 // ----------------------------------------------------------------------------
188 HRESULT SWFF_OpenDefaultFFJoystickEx(
190 IN HINSTANCE hInstance,
191 OUT LPDIRECTINPUT* ppDI,
192 OUT LPDIRECTINPUTDEVICE2* ppDIDevice,
196 if(hWnd == NULL || hInstance == NULL || ppDI == NULL || ppDIDevice == NULL)
198 return SFERR_INVALID_PARAM;
201 // create the DirectInput object
202 hResult = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, ppDI, NULL);
206 // enumerate the first attached joystick
207 // instance goes in pDIDeviceInstance
208 DIDEVICEINSTANCE DIDeviceInstance;
209 DIDeviceInstance.dwDevType = 0;
210 hResult = (*ppDI)->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc, &DIDeviceInstance, DIEDFL_FORCEFEEDBACK);
217 if(DIDeviceInstance.dwDevType == 0)
221 return DIERR_DEVICENOTREG;
224 // create the DirectInput Device object
225 LPDIRECTINPUTDEVICE pDIDevice = NULL;
226 hResult = (*ppDI)->CreateDevice(DIDeviceInstance.guidInstance, &pDIDevice, NULL);
234 // get a pointer to its DirectInputDevice2 interface
235 hResult = pDIDevice->QueryInterface(IID_IDirectInputDevice2, (void**)ppDIDevice);
238 pDIDevice->Release();
244 pDIDevice->Release();
247 // set the data format to the pre-defined DirectInput joystick format
248 hResult = (*ppDIDevice)->SetDataFormat(&c_dfDIJoystick);
251 (*ppDIDevice)->Release();
258 // set the cooperative level
259 hResult = (*ppDIDevice)->SetCooperativeLevel(hWnd, dwFlags);
262 (*ppDIDevice)->Release();
269 // turn auto-center off
270 DIPROPDWORD DIPropAutoCenter;
271 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
272 DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
273 DIPropAutoCenter.diph.dwObj = 0;
274 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
275 DIPropAutoCenter.dwData = 0;
277 hResult = (*ppDIDevice)->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
280 (*ppDIDevice)->Release();
287 // acquire the joystick
288 hResult = (*ppDIDevice)->Acquire();
291 (*ppDIDevice)->Release();
301 BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID lpvContext)
303 LPDIDEVICEINSTANCE pDIDeviceInstance = (LPDIDEVICEINSTANCE)lpvContext;
304 if(pDIDeviceInstance == NULL)
309 if(GET_DIDEVICE_TYPE(lpddi->dwDevType) == DIDEVTYPE_JOYSTICK)
311 memcpy((LPVOID)pDIDeviceInstance, (LPVOID)lpddi, sizeof(*pDIDeviceInstance));
316 return DIENUM_CONTINUE;
319 // ----------------------------------------------------------------------------
320 // Function: SWFF_DestroyEffect
321 // Purpose: Destroys one effect or all effects
322 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
323 // LPDIRECTINPUTEFFECT pDIEffect - Effect to destroy
324 // - NULL destroys all effects
329 // ----------------------------------------------------------------------------
330 HRESULT SWFF_DestroyEffect(
331 IN LPDIRECTINPUTDEVICE2 pDIDevice,
332 IN LPDIRECTINPUTEFFECT pDIEffect)
334 HRESULT hResult = SUCCESS;
335 if(pDIEffect != NULL)
337 pDIEffect->Release();
340 hResult = SWFF_DestroyAllEffects(pDIDevice);
345 // ----------------------------------------------------------------------------
346 // Function: SWFF_DestroyAllEffects
347 // Purpose: Destroys all created effects
348 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
353 // ----------------------------------------------------------------------------
354 HRESULT SWFF_DestroyAllEffects(
355 IN LPDIRECTINPUTDEVICE2 pDIDevice)
359 if(pDIDevice == NULL)
360 return SFERR_INVALID_PARAM;
362 hResult = pDIDevice->EnumCreatedEffectObjects(DIEnumAndDestroyCreatedEffectsProc, NULL, 0);
367 BOOL CALLBACK DIEnumAndDestroyCreatedEffectsProc(LPDIRECTINPUTEFFECT pDIEffect, LPVOID lpvRef)
369 pDIEffect->Release();
371 return DIENUM_CONTINUE;
374 // ----------------------------------------------------------------------------
375 // Function: SWFF_SetGain
376 // Purpose: Sets Gain for the Effect
377 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the gain for
378 // DWORD dwGain - Gain in 1 to 10000
383 // ----------------------------------------------------------------------------
384 HRESULT SWFF_SetGain(
385 IN LPDIRECTINPUTEFFECT pDIEffect,
388 if(pDIEffect == NULL)
389 return SFERR_INVALID_PARAM;
391 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
392 thisEffect.dwGain = dwGain;
393 return pDIEffect->SetParameters(&thisEffect, DIEP_GAIN);
397 // ----------------------------------------------------------------------------
398 // Function: SWFF_SetDirection
399 // Purpose: Sets 2D Angle Direction for the Effect
400 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the direction for
401 // DWORD dwAngle - Direction in 0 to 35999
406 // ----------------------------------------------------------------------------
407 HRESULT SWFF_SetDirection(
408 IN LPDIRECTINPUTEFFECT pDIEffect,
411 if(pDIEffect == NULL)
412 return SFERR_INVALID_PARAM;
414 // set up a DIEFFECT structure so we can change direction
415 LONG rglDirection[2];
416 DIEFFECT thisEffect = {sizeof(DIEFFECT)};
417 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
418 thisEffect.cAxes = 2;
419 thisEffect.rgdwAxes = NULL;
420 thisEffect.rglDirection = rglDirection;
421 thisEffect.rglDirection[0] = dwAngle;
422 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION);
425 HRESULT SWFF_SetDirectionGain(
426 IN LPDIRECTINPUTEFFECT pDIEffect,
430 if(pDIEffect == NULL)
431 return SFERR_INVALID_PARAM;
433 // set up a DIEFFECT structure so we can change direction
434 LONG rglDirection[2];
435 DIEFFECT thisEffect = {sizeof(DIEFFECT)};
437 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
438 thisEffect.cAxes = 2;
439 thisEffect.rgdwAxes = NULL;
440 thisEffect.rglDirection = rglDirection;
441 thisEffect.rglDirection[0] = dwAngle;
442 thisEffect.dwGain = dwGain;
443 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION | DIEP_GAIN);
446 // ----------------------------------------------------------------------------
447 // Function: SWFF_SetDuration
448 // Purpose: Sets Duration for the Effect
449 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the duration for
450 // DWORD dwDuration - In uSecs, INFINITE is FOREVER
455 // ----------------------------------------------------------------------------
456 HRESULT SWFF_SetDuration(
457 IN LPDIRECTINPUTEFFECT pDIEffect,
460 if(pDIEffect == NULL)
461 return SFERR_INVALID_PARAM;
463 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
464 thisEffect.dwDuration = dwDuration;
465 return pDIEffect->SetParameters(&thisEffect, DIEP_DURATION);
469 // ----------------------------------------------------------------------------
470 // Function: SWFF_PutRawForce
471 // Purpose: Sends Force Value,Direction to ff Device
472 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to a two axis raw force object
473 // LONG lMagnitude - -10000 to +10000 force value
474 // DWORD dwDirection - 0 to 35999
477 // Comments: To use this, you need to create the effect using
478 // SWFF_CreateRawForceEffect() first
480 // ----------------------------------------------------------------------------
481 HRESULT SWFF_PutRawForce(
482 IN LPDIRECTINPUTEFFECT pDIEffect,
484 IN DWORD dwDirection)
486 if(pDIEffect == NULL)
487 return SFERR_INVALID_PARAM;
489 DICONSTANTFORCE DIConstantForceStruct;
490 DIConstantForceStruct.lMagnitude = lMagnitude;
493 rgdwAxes[0] = DIJOFS_X;
494 rgdwAxes[1] = DIJOFS_Y;
496 LONG rglDirection[2];
497 rglDirection[0] = dwDirection;
500 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
501 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
502 thisEffect.cAxes = 2;
503 thisEffect.rgdwAxes = rgdwAxes;
504 thisEffect.rglDirection = rglDirection;
506 thisEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
507 thisEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
508 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION|DIEP_TYPESPECIFICPARAMS);
511 // ----------------------------------------------------------------------------
512 // Function: SWFF_PutRawAxisForce
513 // Purpose: Sends Force Value,Direction to ff Device
514 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to a one axis raw force object
515 // LONG lMagnitude - -10000 to +10000 force value
518 // Comments: To use this, you need to create the effect using
519 // SWFF_CreateRawAxisForceEffect() first
521 // ----------------------------------------------------------------------------
522 HRESULT SWFF_PutRawAxisForce(
523 IN LPDIRECTINPUTEFFECT pDIEffect,
526 if(pDIEffect == NULL)
527 return SFERR_INVALID_PARAM;
529 DICONSTANTFORCE DIConstantForceStruct;
530 DIConstantForceStruct.lMagnitude = lMagnitude;
532 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
534 thisEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
535 thisEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
536 return pDIEffect->SetParameters(&thisEffect, DIEP_TYPESPECIFICPARAMS);
539 // ----------------------------------------------------------------------------
540 // Function: SWFF_CreateRawForceEffect
541 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
542 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
543 // LONG lMagnitude - -10000 to 10000
544 // DWORD dwDirection - 0 to 35999
549 // Comments: Create this Effect once, then use SetParameter(...) to play the
552 // ----------------------------------------------------------------------------
554 HRESULT SWFF_CreateRawForceEffect(
555 IN LPDIRECTINPUTDEVICE2 pDIDevice,
556 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
558 IN DWORD dwDirection)
560 if(pDIDevice == NULL || ppDIEffect == NULL)
561 return SFERR_INVALID_PARAM;
562 // Always clear return IPtr
565 LPDIRECTINPUTEFFECT pRawForce;
567 DICONSTANTFORCE DIConstantForceStruct;
568 DIConstantForceStruct.lMagnitude = lMagnitude;
571 rgdwAxes[0] = DIJOFS_X;
572 rgdwAxes[1] = DIJOFS_Y;
574 LONG rglDirection[2];
575 rglDirection[0] = dwDirection;
579 DIEffect.dwSize = sizeof(DIEFFECT);
580 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
581 DIEffect.dwDuration = INFINITE;
582 DIEffect.dwSamplePeriod = HZ_TO_uS(100);
583 DIEffect.dwGain = 10000;
584 DIEffect.dwTriggerButton = DIEB_NOTRIGGER;
585 DIEffect.dwTriggerRepeatInterval= 0;
587 DIEffect.rgdwAxes = rgdwAxes;
588 DIEffect.rglDirection = rglDirection;
589 DIEffect.lpEnvelope = NULL;
590 DIEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
591 DIEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
594 hRet = pDIDevice->CreateEffect(GUID_RawForce, &DIEffect, &pRawForce, NULL);
595 if(FAILED(hRet)) return hRet;
597 *ppDIEffect = pRawForce;
602 // ----------------------------------------------------------------------------
603 // Function: SWFF_CreateRawAxisForceEffect
604 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
605 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
606 // LONG lMagnitude - -10000 to 10000
607 // DWORD dwAxis - Either X_AXIS or Y_AXIS
612 // Comments: Create this Effect once, then use SetParameter(...) to play the
615 // ----------------------------------------------------------------------------
617 HRESULT SWFF_CreateRawAxisForceEffect(
618 IN LPDIRECTINPUTDEVICE2 pDIDevice,
619 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
623 if(pDIDevice == NULL || ppDIEffect == NULL)
624 return SFERR_INVALID_PARAM;
626 if(!(dwAxis == X_AXIS || dwAxis == Y_AXIS))
627 return SFERR_INVALID_PARAM;
629 // Always clear return IPtr
632 LPDIRECTINPUTEFFECT pRawForce;
634 DICONSTANTFORCE DIConstantForceStruct;
635 DIConstantForceStruct.lMagnitude = lMagnitude;
639 rgdwAxes[0] = DIJOFS_X;
641 rgdwAxes[0] = DIJOFS_Y;
643 LONG rglDirection[1];
647 DIEffect.dwSize = sizeof(DIEFFECT);
648 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
649 DIEffect.dwDuration = INFINITE;
650 DIEffect.dwSamplePeriod = HZ_TO_uS(100);
651 DIEffect.dwGain = 10000;
652 DIEffect.dwTriggerButton = DIEB_NOTRIGGER;
653 DIEffect.dwTriggerRepeatInterval= 0;
655 DIEffect.rgdwAxes = rgdwAxes;
656 DIEffect.rglDirection = rglDirection;
657 DIEffect.lpEnvelope = NULL;
658 DIEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
659 DIEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
662 hRet = pDIDevice->CreateEffect(GUID_RawForce, &DIEffect, &pRawForce, NULL);
663 if(FAILED(hRet)) return hRet;
665 *ppDIEffect = pRawForce;
670 // ----------------------------------------------------------------------------
671 // Function: SWFF_CreateROMEffect
672 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
673 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
674 // REFGUID refGUID - GUID for ROM Effect
675 // DWORD dwDuration - uS
676 // DWORD dwGain - 1 to 10000
677 // DWORD dwDirection - 0 to 35999
678 // LONG lButton - Index of playback button, -1 for none
682 // Comments: Assumes valid GUID for the ROM Effect
683 // Note: If unmodified ROM Effect, user has to pass
684 // DEFAULT_ROM_EFFECT_DURATION, DEFAULT_ROM_EFFECT_GAIN
685 // ----------------------------------------------------------------------------
686 HRESULT SWFF_CreateROMEffect(
687 IN LPDIRECTINPUTDEVICE2 pDIDevice,
688 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
692 IN DWORD dwDirection,
695 if(pDIDevice == NULL || ppDIEffect == NULL)
696 return SFERR_INVALID_PARAM;
697 // Always clear return IPtr
700 LPDIRECTINPUTEFFECT pROMEffect = NULL;
702 // Default NO Envelope
703 DIENVELOPE DIEnvelopeStruct;
704 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
705 DIEnvelopeStruct.dwAttackTime = 0;
706 DIEnvelopeStruct.dwAttackLevel = 10000;
707 DIEnvelopeStruct.dwFadeTime = 0;
708 DIEnvelopeStruct.dwFadeLevel = 10000;
712 rgdwAxes[0] = DIJOFS_X;
713 rgdwAxes[1] = DIJOFS_Y;
715 LONG rglDirection[2];
716 rglDirection[0] = dwDirection;
720 DIEffect.dwSize = sizeof(DIEFFECT);
721 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
722 // Set Duration and Gain to use Default ROM Effect params unless overridden
723 DIEffect.dwDuration = dwDuration; // can be DEFAULT_ROM_EFFECT_DURATION
724 DIEffect.dwSamplePeriod = DEFAULT_ROM_EFFECT_OUTPUTRATE;
725 DIEffect.dwGain = dwGain; // can be DEFAULT_ROM_EFFECT_GAIN;
727 DIEffect.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
728 DIEffect.dwTriggerRepeatInterval= 0;
730 DIEffect.rgdwAxes = rgdwAxes;
731 DIEffect.rglDirection = rglDirection;
732 DIEffect.lpEnvelope = &DIEnvelopeStruct;
733 DIEffect.cbTypeSpecificParams = 0;
734 DIEffect.lpvTypeSpecificParams = NULL;
736 HRESULT hRet = pDIDevice->CreateEffect(refGUID, &DIEffect, &pROMEffect, NULL);
737 if(FAILED(hRet)) return hRet;
739 *ppDIEffect = pROMEffect;
743 // ----------------------------------------------------------------------------
744 // Function: SWFF_WriteRegString
745 // Parameters: LPCTSTR pszKey - The key under HKCR to place the value
746 // LPCTSTR pszValue - The string value for pszKey
748 // Returns: TRUE if the registry entry was successfully made
750 // Comments: Helper function for SWFF_RegisterVFXObject to write registry entries
752 // ----------------------------------------------------------------------------
753 BOOL SWFF_WriteRegString(
761 if(pszKey == NULL || pszValue == NULL)
765 hKey = HKEY_CLASSES_ROOT;
766 lRet = RegCreateKey(hKey, pszKey, &hKey);
767 if(lRet != ERROR_SUCCESS)
770 // save the value into the key
771 nLen = strlen(pszValue);
772 lRet = RegSetValueEx(hKey, NULL, 0, REG_SZ, (PBYTE)pszValue, nLen + 1);
773 if(lRet != ERROR_SUCCESS)
781 if(lRet != ERROR_SUCCESS)
784 // if we have reached this point, then it was a success
788 // ----------------------------------------------------------------------------
789 // Function: SWFF_RegisterVFXObject
790 // Parameters: LPCTSTR - Pointer to the fully-qualified path name of VFX.DLL
792 // Returns: TRUE if the object was successfully registered
794 // Comments: Example of code to register the VFX com object.
795 // You supply lpszVFXPath depending on where you install VFX.DLL
797 // ----------------------------------------------------------------------------
798 #define GUID_VFX_Object "{04ace0a7-1fa8-11d0-aa22-00a0c911f471}"
799 BOOL SWFF_RegisterVFXObject(IN LPCTSTR pszVFXPath)
801 if(pszVFXPath == NULL)
804 return SWFF_WriteRegString("\\VFX1.0", "VFX Object")
805 && SWFF_WriteRegString("\\VFX1.0\\CLSID", GUID_VFX_Object)
806 && SWFF_WriteRegString("\\VFX", "VFX Object")
807 && SWFF_WriteRegString("\\VFX\\CurVer", "VFX1.0")
808 && SWFF_WriteRegString("\\VFX\\CLSID", GUID_VFX_Object)
809 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object, "VFX Object")
810 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\VersionIndependentProgID", "VFX")
811 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\InprocServer32", pszVFXPath)
812 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\NotInsertable", "");
815 // ----------------------------------------------------------------------------
816 // Function: SWFF_CreateVFXEffectFromFile
817 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
818 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
819 // TCHAR *pszFileName - Pointer to VFX File name
825 // ----------------------------------------------------------------------------
827 HRESULT SWFF_CreateVFXEffectFromFile(
828 IN LPDIRECTINPUTDEVICE2 pDIDevice,
829 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
830 IN const TCHAR *pszFileName)
832 if(pDIDevice == NULL || ppDIEffect == NULL || pszFileName == NULL)
833 return SFERR_INVALID_PARAM;
835 // Always clear return IPtr
838 LPDIRECTINPUTEFFECT pVFXEffect;
841 VFXParam.m_Bytes = sizeof(VFX_PARAM);
842 VFXParam.m_PointerType = VFX_FILENAME;
843 VFXParam.m_BufferSize = 0;
844 VFXParam.m_pFileNameOrBuffer = (PVOID) pszFileName;
847 rgdwAxes[0] = DIJOFS_X;
848 rgdwAxes[1] = DIJOFS_Y;
850 LONG rglDirection[2];
851 rglDirection[0] = DEFAULT_VFX_EFFECT_DIRECTION;
854 DIEFFECT DIEffectStruct;
855 DIEffectStruct.dwSize = sizeof(DIEFFECT);
856 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
857 DIEffectStruct.dwDuration = DEFAULT_VFX_EFFECT_DURATION;
858 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
859 DIEffectStruct.dwGain = DEFAULT_VFX_EFFECT_GAIN;
860 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
861 DIEffectStruct.dwTriggerRepeatInterval = 0;
862 DIEffectStruct.cAxes = 2;
863 DIEffectStruct.rgdwAxes = rgdwAxes;
864 DIEffectStruct.rglDirection = rglDirection;
865 DIEffectStruct.lpEnvelope = NULL;
866 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
867 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
870 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
871 if(FAILED(hResult)) return hResult;
873 *ppDIEffect = pVFXEffect;
878 // ----------------------------------------------------------------------------
879 // Function: SWFF_CreateVFXEffectFromFileEx
880 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
881 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
882 // TCHAR *pszFileName - Pointer to VFX File
883 // DWORD dwDuration - INFINITE or default
884 // DWORD dwGain - 1 to 10000
885 // DWORD dwDirection - 0 to 35999
891 // ----------------------------------------------------------------------------
893 HRESULT SWFF_CreateVFXEffectFromFileEx(
894 IN LPDIRECTINPUTDEVICE2 pDIDevice,
895 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
896 IN const TCHAR *pszFileName,
899 IN DWORD dwDirection)
901 if(pDIDevice == NULL || ppDIEffect == NULL || pszFileName == NULL)
902 return SFERR_INVALID_PARAM;
903 // Always clear return IPtr
906 LPDIRECTINPUTEFFECT pVFXEffect;
909 VFXParam.m_Bytes = sizeof(VFX_PARAM);
910 VFXParam.m_PointerType = VFX_FILENAME;
911 VFXParam.m_BufferSize = 0;
912 VFXParam.m_pFileNameOrBuffer = (PVOID) pszFileName;
915 rgdwAxes[0] = DIJOFS_X;
916 rgdwAxes[1] = DIJOFS_Y;
918 LONG rglDirection[2];
919 rglDirection[0] = dwDirection;
922 DIEFFECT DIEffectStruct;
923 DIEffectStruct.dwSize = sizeof(DIEFFECT);
924 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
925 DIEffectStruct.dwDuration = dwDuration;
926 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
927 DIEffectStruct.dwGain = dwGain;
928 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
929 DIEffectStruct.dwTriggerRepeatInterval = 0;
930 DIEffectStruct.cAxes = 2;
931 DIEffectStruct.rgdwAxes = rgdwAxes;
932 DIEffectStruct.rglDirection = rglDirection;
933 DIEffectStruct.lpEnvelope = NULL;
934 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
935 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
938 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
939 if(FAILED(hResult)) return hResult;
941 *ppDIEffect = pVFXEffect;
946 // ----------------------------------------------------------------------------
947 // Function: SWFF_CreateVFXEffectFromBuffer
948 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
949 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
950 // LPVOID pBuffer - Pointer to VFX Buffer
951 // DWORD dwBufferSize - Buffer size in bytes
957 // If you are compiling the FRC files as resources in your executable
958 // by putting #include "script.vfx" in your .rc file, you would use
959 // code similar to the following to create the effect (no error checking).
961 // HRSRC hResInfo = FindResource(NULL, "IDF_FOO", "FORCE");
962 // DWORD dwBytes = SizeofResource(NULL, hResInfo);
963 // HGLOBAL hRsrc = LoadResource(NULL, hResInfo);
964 // PVOID pBuffer = LockResource(hRsrc);
965 // SWFF_CreateEffectFromVFXBuffer(pDIDevice, pBuffer, dwBytes, &pDIEffect);
967 // ----------------------------------------------------------------------------
969 HRESULT SWFF_CreateVFXEffectFromBuffer(
970 IN LPDIRECTINPUTDEVICE2 pDIDevice,
971 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
972 IN const LPVOID pBuffer,
973 IN DWORD dwBufferSize)
975 if(pDIDevice == NULL || ppDIEffect == NULL || pBuffer == NULL)
976 return SFERR_INVALID_PARAM;
978 // Always clear return IPtr
981 LPDIRECTINPUTEFFECT pVFXEffect;
984 VFXParam.m_Bytes = sizeof(VFX_PARAM);
985 VFXParam.m_PointerType = VFX_BUFFER;
986 VFXParam.m_BufferSize = dwBufferSize;
987 VFXParam.m_pFileNameOrBuffer = pBuffer;
990 rgdwAxes[0] = DIJOFS_X;
991 rgdwAxes[1] = DIJOFS_Y;
993 LONG rglDirection[2];
994 rglDirection[0] = DEFAULT_VFX_EFFECT_DIRECTION;
997 DIEFFECT DIEffectStruct;
998 DIEffectStruct.dwSize = sizeof(DIEFFECT);
999 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1000 DIEffectStruct.dwDuration = DEFAULT_VFX_EFFECT_DURATION;
1001 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1002 DIEffectStruct.dwGain = DEFAULT_VFX_EFFECT_GAIN;
1003 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
1004 DIEffectStruct.dwTriggerRepeatInterval = 0;
1005 DIEffectStruct.cAxes = 2;
1006 DIEffectStruct.rgdwAxes = rgdwAxes;
1007 DIEffectStruct.rglDirection = rglDirection;
1008 DIEffectStruct.lpEnvelope = NULL;
1009 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
1010 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
1013 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
1014 if(FAILED(hResult)) return hResult;
1016 *ppDIEffect = pVFXEffect;
1021 // ----------------------------------------------------------------------------
1022 // Function: SWFF_CreateVFXEffectFromBufferEx
1023 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1024 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1025 // LPVOID pBuffer - Pointer to VFX Buffer
1026 // DWORD dwBufferSize - Buffer size in bytes
1027 // DWORD dwDuration - INFINITE or default
1028 // DWORD dwGain - 1 to 10000
1029 // DWORD dwDirection - 0 to 35999
1035 // See note for SWFF_CreateVFXEffectFromBuffer(...)
1036 // ----------------------------------------------------------------------------
1038 HRESULT SWFF_CreateVFXEffectFromBufferEx(
1039 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1040 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1041 IN const LPVOID pBuffer,
1042 IN DWORD dwBufferSize,
1043 IN DWORD dwDuration,
1045 IN DWORD dwDirection)
1047 if(pDIDevice == NULL || ppDIEffect == NULL || pBuffer == NULL)
1048 return SFERR_INVALID_PARAM;
1049 // Always clear return IPtr
1052 LPDIRECTINPUTEFFECT pVFXEffect;
1055 VFXParam.m_Bytes = sizeof(VFX_PARAM);
1056 VFXParam.m_PointerType = VFX_BUFFER;
1057 VFXParam.m_BufferSize = dwBufferSize;
1058 VFXParam.m_pFileNameOrBuffer = pBuffer;
1061 rgdwAxes[0] = DIJOFS_X;
1062 rgdwAxes[1] = DIJOFS_Y;
1064 LONG rglDirection[2];
1065 rglDirection[0] = dwDirection;
1066 rglDirection[1] = 0;
1068 DIEFFECT DIEffectStruct;
1069 DIEffectStruct.dwSize = sizeof(DIEFFECT);
1070 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1071 DIEffectStruct.dwDuration = dwDuration;
1072 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1073 DIEffectStruct.dwGain = dwGain;
1074 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
1075 DIEffectStruct.dwTriggerRepeatInterval = 0;
1076 DIEffectStruct.cAxes = 2;
1077 DIEffectStruct.rgdwAxes = rgdwAxes;
1078 DIEffectStruct.rglDirection = rglDirection;
1079 DIEffectStruct.lpEnvelope = NULL;
1080 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
1081 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
1084 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
1085 if(FAILED(hResult)) return hResult;
1087 *ppDIEffect = pVFXEffect;
1092 // ----------------------------------------------------------------------------
1093 // Function: SWFF_CreateDIEffectFromFile
1094 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1095 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1096 // TCHAR *pszFileName - Pointer to VFX File name
1101 // Note: If the file contains multiple effects or a custom effect this
1102 // function will fail. Use SWFF_CreateDIEffectFromFileEx.
1103 // ----------------------------------------------------------------------------
1105 HRESULT SWFF_CreateDIEffectFromFile(
1106 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1107 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1108 IN const TCHAR *pszFileName)
1113 if(pDIDevice == NULL || pszFileName == NULL || ppDIEffect == NULL)
1114 return SFERR_INVALID_PARAM;
1118 hResult = CoInitialize(NULL);
1122 hResult = CoCreateInstance(CLSID_VFX,
1124 CLSCTX_INPROC_SERVER,
1130 return SFERR_SYSTEM_INIT;
1139 // Create the Effect from a *.frc file
1140 DWORD dwInFlags = VFXCE_CREATE_SINGLE;
1141 hResult = pIVFX->CreateEffectFromFile(pDIDevice, ppDIEffect,
1142 0, pszFileName, NULL, NULL, dwInFlags, NULL);
1148 if(FAILED(hResult)) return hResult;
1154 // ----------------------------------------------------------------------------
1155 // Function: SWFF_CreateDIEffectFromFileEx
1156 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1157 // LPDIRECTINPUTEFFECT** pppDIEffect - Pointer to an array of
1158 // LPDIRECTINPUTEFFECT's.
1159 // This array is allocated
1160 // by the function. Caller is
1161 // responsible for deleting.
1162 // PDWORD pdwEffectCount - Gets the number of effects in array
1163 // TCHAR *pszFileName - Pointer to VFX File name
1164 // PPVOID ppUDBuffer - Gets an array containing custom force
1165 // samples. This array is allocated by
1166 // the function. Caller is
1167 // responsible for deleting.
1168 // PDWORD pdwOutFlags - Receives 0 if the file contains
1169 // a single effect. Otherwise
1170 // it receives VFXCE_CONCATENATE
1171 // or VFXCE_SUPERIMPOSE.
1176 // Note: call delete [] pppDIEffect and delete [] ppUDBuffer after
1177 // releasing the effects
1178 // ----------------------------------------------------------------------------
1180 HRESULT SWFF_CreateDIEffectFromFileEx(
1181 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1182 IN OUT LPDIRECTINPUTEFFECT** pppDIEffect,
1183 IN OUT PDWORD pdwEffectCount,
1184 IN const TCHAR *pszFileName,
1185 IN OUT void** ppUDBuffer,
1186 IN OUT PDWORD pdwOutFlags)
1189 if(pDIDevice == NULL || pszFileName == NULL || pppDIEffect == NULL ||
1190 pdwEffectCount == NULL || ppUDBuffer == NULL || pdwOutFlags == NULL)
1192 return SFERR_INVALID_PARAM;
1195 // zero out the return values
1196 *pppDIEffect = NULL;
1197 *pdwEffectCount = 0;
1204 hResult = CoInitialize(NULL);
1208 hResult = CoCreateInstance(CLSID_VFX,
1210 CLSCTX_INPROC_SERVER,
1216 return SFERR_SYSTEM_INIT;
1225 // see how big a DIEffect array we have to allocate, and see how much memory, if any,
1226 // we need to allocate for UD sample caching
1227 DWORD dwInFlags = VFXCE_CALC_BUFFER_SIZE | VFXCE_CALC_EFFECT_COUNT;
1228 DWORD dwEffectCount;
1230 hResult = pIVFX->CreateEffectFromFile(NULL, NULL,
1231 &dwEffectCount, pszFileName, NULL, &dwBufferSize, dwInFlags, NULL);
1239 // allocate memory for the effects
1240 LPDIRECTINPUTEFFECT* ppDIEffect = new LPDIRECTINPUTEFFECT[dwEffectCount];
1241 if(ppDIEffect == NULL)
1245 return DIERR_OUTOFMEMORY;
1248 // allocate memory for the custom force samples
1249 PVOID pUDBuffer = NULL;
1250 if(dwBufferSize > 0)
1252 pUDBuffer = new BYTE[dwBufferSize];
1253 if(pUDBuffer == NULL)
1255 delete [] ppDIEffect;
1259 return DIERR_OUTOFMEMORY;
1263 // Create the Effect from a *.frc file
1265 dwInFlags = VFXCE_CREATE_MULTIPLE;
1266 hResult = pIVFX->CreateEffectFromFile(pDIDevice, ppDIEffect,
1267 &dwEffectCount, pszFileName, pUDBuffer, &dwBufferSize, dwInFlags, &dwOutFlags);
1271 delete [] ppDIEffect;
1273 delete [] pUDBuffer;
1284 if(FAILED(hResult)) return hResult;
1286 // assign the results
1287 *pppDIEffect = ppDIEffect;
1288 *pdwEffectCount = dwEffectCount;
1289 *ppUDBuffer = pUDBuffer;
1290 *pdwOutFlags = dwOutFlags;
1296 // ----------------------------------------------------------------------------
1297 // Function: SWFF_CreateDIEffectFromBuffer
1298 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1299 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1300 // LPVOID pBuffer - Pointer to VFX Buffer
1301 // DWORD dwBufferSize - Buffer size in bytes
1306 // Note: If the file contains multiple effects or a custom effect this
1307 // function will fail. Use SWFF_CreateDIEffectFromBufferEx.
1308 // ----------------------------------------------------------------------------
1310 HRESULT SWFF_CreateDIEffectFromBuffer(
1311 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1312 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1313 IN const LPVOID pBuffer,
1314 IN DWORD dwBufferSize)
1319 if(pDIDevice == NULL || pBuffer == NULL || ppDIEffect == NULL)
1320 return SFERR_INVALID_PARAM;
1324 hResult = CoInitialize(NULL);
1328 hResult = CoCreateInstance(CLSID_VFX,
1330 CLSCTX_INPROC_SERVER,
1336 return SFERR_SYSTEM_INIT;
1345 // Create the Effect from a *.frc file
1346 DWORD dwInFlags = VFXCE_CREATE_SINGLE;
1347 hResult = pIVFX->CreateEffectFromBuffer(pDIDevice, ppDIEffect,
1348 0, pBuffer, dwBufferSize, NULL, NULL, dwInFlags, NULL);
1354 if(FAILED(hResult)) return hResult;
1360 // ----------------------------------------------------------------------------
1361 // Function: SWFF_CreateDIEffectFromBufferEx
1362 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - Pointer to DirectInputDevice
1363 // LPDIRECTINPUTEFFECT** pppDIEffect - Pointer to an array of
1364 // LPDIRECTINPUTEFFECT's.
1365 // This array is allocated
1366 // by the function. Caller is
1367 // responsible for deleting.
1368 // PDWORD pdwEffectCount - Gets the number of effects in array
1369 // LPVOID pBuffer - Pointer to VFX Buffer
1370 // DWORD dwBufferSize - Buffer size in bytes
1371 // PPVOID ppUDBuffer - Gets an array containing custom force
1372 // samples. This array is allocated by
1373 // the function. Caller is
1374 // responsible for deleting.
1375 // PDWORD pdwOutFlags - Receives 0 if the file contains
1376 // a single effect. Otherwise
1377 // it receives VFXCE_CONCATENATE
1378 // or VFXCE_SUPERIMPOSE.
1383 // Note: call delete [] pppDIEffect and delete [] ppUDBuffer after
1384 // releasing the effects
1385 // ----------------------------------------------------------------------------
1387 HRESULT SWFF_CreateDIEffectFromBufferEx(
1388 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1389 IN OUT LPDIRECTINPUTEFFECT** pppDIEffect,
1390 IN OUT PDWORD pdwEffectCount,
1391 IN const LPVOID pBuffer,
1392 IN DWORD dwBufferSize,
1393 IN OUT void** ppUDBuffer,
1394 IN OUT PDWORD pdwOutFlags)
1397 if(pDIDevice == NULL || pBuffer == NULL || pppDIEffect == NULL||
1398 pdwEffectCount == NULL || ppUDBuffer == NULL || pdwOutFlags == NULL)
1400 return SFERR_INVALID_PARAM;
1403 // zero out the return values
1404 *pppDIEffect = NULL;
1405 *pdwEffectCount = 0;
1414 hResult = CoInitialize(NULL);
1418 hResult = CoCreateInstance(CLSID_VFX,
1420 CLSCTX_INPROC_SERVER,
1426 return SFERR_SYSTEM_INIT;
1435 // see how big a DIEffect array we have to allocate, and see how much memory, if any,
1436 // we need to allocate for UD sample caching
1437 DWORD dwInFlags = VFXCE_CALC_BUFFER_SIZE | VFXCE_CALC_EFFECT_COUNT;
1438 DWORD dwEffectCount;
1439 DWORD dwUDBufferSize;
1440 hResult = pIVFX->CreateEffectFromBuffer(NULL, NULL,
1441 &dwEffectCount, pBuffer, dwBufferSize, NULL, &dwUDBufferSize, dwInFlags, NULL);
1449 // allocate memory for the effects
1450 LPDIRECTINPUTEFFECT* ppDIEffect = new LPDIRECTINPUTEFFECT[dwEffectCount];
1451 if(ppDIEffect == NULL)
1455 return DIERR_OUTOFMEMORY;
1458 // allocate memory for the custom force samples
1459 PVOID pUDBuffer = NULL;
1460 if(dwUDBufferSize > 0)
1462 pUDBuffer = new BYTE[dwUDBufferSize];
1463 if(pUDBuffer == NULL)
1465 delete [] ppDIEffect;
1469 return DIERR_OUTOFMEMORY;
1473 // Create the Effect from a *.frc file
1475 dwInFlags = VFXCE_CREATE_MULTIPLE;
1476 hResult = pIVFX->CreateEffectFromBuffer(pDIDevice, ppDIEffect,
1477 &dwEffectCount, pBuffer, dwBufferSize, pUDBuffer, &dwUDBufferSize, dwInFlags, &dwOutFlags);
1481 delete [] ppDIEffect;
1483 delete [] pUDBuffer;
1494 if(FAILED(hResult)) return hResult;
1496 // assign the results
1497 *pppDIEffect = ppDIEffect;
1498 *pdwEffectCount = dwEffectCount;
1499 *ppUDBuffer = pUDBuffer;
1500 *pdwOutFlags = dwOutFlags;
1506 // ----------------------------------------------------------------------------
1507 // Function: SWFF_CreatePeriodicEffect
1508 // Purpose: Creates a Periodic type Effect with specified params
1509 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1510 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1511 // DWORD dwType - Type of PERIODIC Effect (SINE | COSINE | ...)
1512 // DWORD dwDuration - uS
1513 // DWORD dwPeriod - uS
1514 // DWORD dwDirection - 0 to 35999
1515 // DWORD dwMagnitude - 0 to 10000
1516 // LONG lOffset - Offset in -10000 to 10000
1517 // DWORD dwAttackTime - Envelope Attack Time in uS
1518 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
1519 // DWORD dwFadeTime - Envelope Fade time in uS
1520 // DWORD dwFadeLevel - Envelope Fade Level
1521 // LONG lButton - Index of playback button, -1 for none
1527 // ----------------------------------------------------------------------------
1528 HRESULT SWFF_CreatePeriodicEffect( IN LPDIRECTINPUTDEVICE2 pDIDevice,
1529 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1531 IN DWORD dwDuration,
1533 IN DWORD dwDirection,
1534 IN DWORD dwMagnitude,
1536 IN DWORD dwAttackTime,
1537 IN DWORD dwAttackLevel,
1538 IN DWORD dwFadeTime,
1539 IN DWORD dwFadeLevel,
1542 if(pDIDevice == NULL || ppDIEffect == NULL)
1543 return SFERR_INVALID_PARAM;
1544 // Always clear return IPtr
1547 // type-specific stuff
1567 guid = GUID_Triangle;
1570 guid = GUID_Triangle;
1574 guid = GUID_SawtoothUp;
1577 guid = GUID_SawtoothDown;
1584 DIPERIODIC DIPeriodicStruct;
1585 DIPeriodicStruct.dwMagnitude = dwMagnitude;
1586 DIPeriodicStruct.lOffset = lOffset;
1587 DIPeriodicStruct.dwPhase = dwPhase;
1588 DIPeriodicStruct.dwPeriod = dwPeriod;
1590 DIENVELOPE DIEnvelopeStruct;
1591 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
1592 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
1593 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
1594 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
1595 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
1598 rgdwAxes[0] = DIJOFS_X;
1599 rgdwAxes[1] = DIJOFS_Y;
1601 LONG rglDirection[2];
1602 rglDirection[0] = dwDirection;
1603 rglDirection[1] = 0;
1605 DIEFFECT DIEffectStruct;
1606 DIEffectStruct.dwSize = sizeof(DIEFFECT);
1607 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1608 DIEffectStruct.dwDuration = dwDuration;
1609 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1610 DIEffectStruct.dwGain = 10000;
1611 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
1612 DIEffectStruct.dwTriggerRepeatInterval = 0;
1613 DIEffectStruct.cAxes = 2;
1614 DIEffectStruct.rgdwAxes = rgdwAxes;
1615 DIEffectStruct.rglDirection = rglDirection;
1616 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
1617 DIEffectStruct.cbTypeSpecificParams = sizeof(DIPeriodicStruct);
1618 DIEffectStruct.lpvTypeSpecificParams = &DIPeriodicStruct;
1621 hResult = pDIDevice->CreateEffect(guid, &DIEffectStruct, ppDIEffect, NULL);
1626 // ----------------------------------------------------------------------------
1627 // Function: SWFF_CreateSpringEffect
1628 // Purpose: Creates a Spring type Effect with specified params
1629 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1630 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1631 // DWORD dwDuration - Duration in uS
1632 // LONG lKx - X-Axis K Coefficient in -10000 to 10000
1633 // LONG lCenterx - X-Axis Center in -10000 to 10000
1634 // LONG lKy - Y-Axis K Coefficient in -10000 to 10000
1635 // LONG lCentery - Y-Axis Center in -10000 to 10000
1636 // LONG lButton - Index of playback button, -1 for none
1641 // To create a 1D spring, set the lKx or lKy parameter to 0
1642 // To create a 2D spring, set both lKx and lKy parameter to non-zero
1643 // or set both lFx and lFy to zero
1645 // ----------------------------------------------------------------------------
1646 HRESULT SWFF_CreateSpringEffect( IN LPDIRECTINPUTDEVICE2 pDIDevice,
1647 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1648 IN DWORD dwDuration,
1655 if(pDIDevice == NULL || ppDIEffect == NULL)
1656 return SFERR_INVALID_PARAM;
1658 // Always clear return IPtr
1661 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1672 // ----------------------------------------------------------------------------
1673 // Function: SWFF_CreateDamperEffect
1674 // Purpose: Creates a Damper type Effect with specified params
1675 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1676 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1677 // DWORD dwDuration - Duration in uS
1678 // LONG lBx - X-Axis B Coefficient +/-10000
1679 // LONG lV0x - X-Axis Initial Velocity +/-10000
1680 // LONG lBy - Y-Axis B Coefficient +/-10000
1681 // LONG lV0y - Y-Axis Initial Velocity +/-10000
1682 // LONG lButton - Index of playback button, -1 for none
1686 // To create a 1D Damper, set the lBx or lBy parameter to 0
1687 // To create a 2D Damper, set both lBx and lBy parameter to non-zero
1688 // or set both lFx and lFy to zero
1690 // ----------------------------------------------------------------------------
1691 HRESULT SWFF_CreateDamperEffect(
1692 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1693 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1694 IN DWORD dwDuration,
1701 if(pDIDevice == NULL || ppDIEffect == NULL)
1702 return SFERR_INVALID_PARAM;
1704 // Always clear return IPtr
1707 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1719 // ----------------------------------------------------------------------------
1720 // Function: SWFF_CreateInertiaEffect
1721 // Purpose: Creates an Inertia type Effect with specified params
1722 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1723 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1724 // DWORD dwDuration - Duration in uS
1725 // LONG lMx - X-Axis M Coefficient +/-10000
1726 // LONG lA0x - X-Axis Initial Acceleration +/-10000
1727 // LONG lMy - Y-Axis N Coefficient +/-10000
1728 // LONG lA0y - Y-Axis Initial Acceleration +/-10000
1729 // LONG lButton - Index of playback button, -1 for none
1733 // To create a 1D Inertia, set the lMx or lMy parameter to 0
1734 // To create a 2D Inertia, set both lMx and lMy parameter to non-zero
1735 // or set both lFx and lFy to zero
1737 // ----------------------------------------------------------------------------
1738 HRESULT SWFF_CreateInertiaEffect(
1739 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1740 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1741 IN DWORD dwDuration,
1748 if(pDIDevice == NULL || ppDIEffect == NULL)
1749 return SFERR_INVALID_PARAM;
1751 // Always clear return IPtr
1754 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1765 // ----------------------------------------------------------------------------
1766 // Function: SWFF_CreateFrictionEffect
1767 // Purpose: Creates a Friction type Effect with specified params
1768 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1769 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1770 // DWORD dwDuration - Duration in uS
1771 // LONG lFx - X-Axis F Coefficient +/-10000
1772 // LONG lFy - Y-Axis F Coefficient +/-10000
1773 // LONG lButton - Index of playback button, -1 for none
1777 // To create a 1D Friction, set the lFx or lFy parameter to 0
1778 // To create a 2D Friction, set both lFx and lFy parameter to non-zero
1779 // or set both lFx and lFy to zero
1781 // ----------------------------------------------------------------------------
1782 HRESULT SWFF_CreateFrictionEffect(
1783 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1784 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1785 IN DWORD dwDuration,
1790 if(pDIDevice == NULL || ppDIEffect == NULL)
1791 return SFERR_INVALID_PARAM;
1793 // Always clear return IPtr
1796 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1807 HRESULT SWFF_CreateConditionEffectStruct(
1808 di_condition_effect_struct *ptr,
1809 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1810 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1812 IN DWORD dwDuration,
1813 IN LONG lXCoefficient,
1815 IN LONG lYCoefficient,
1819 if(pDIDevice == NULL || ppDIEffect == NULL)
1820 return SFERR_INVALID_PARAM;
1822 // Always clear return IPtr
1832 guid = GUID_Inertia;
1838 guid = GUID_Friction;
1844 ptr->DIConditionStruct[0].lOffset = lXOffset;
1845 ptr->DIConditionStruct[0].lPositiveCoefficient = lXCoefficient;
1846 ptr->DIConditionStruct[0].lNegativeCoefficient = lXCoefficient;
1847 ptr->DIConditionStruct[0].dwPositiveSaturation = 10000;
1848 ptr->DIConditionStruct[0].dwNegativeSaturation = 10000;
1849 ptr->DIConditionStruct[0].lDeadBand = 0;
1850 ptr->DIConditionStruct[1].lOffset = lYOffset;
1851 ptr->DIConditionStruct[1].lPositiveCoefficient = lYCoefficient;
1852 ptr->DIConditionStruct[1].lNegativeCoefficient = lYCoefficient;
1853 ptr->DIConditionStruct[1].dwPositiveSaturation = 10000;
1854 ptr->DIConditionStruct[1].dwNegativeSaturation = 10000;
1855 ptr->DIConditionStruct[1].lDeadBand = 0;
1859 if(lXCoefficient != 0)
1861 rgdwAxes[nAxisCount] = DIJOFS_X;
1865 if(lYCoefficient != 0)
1867 rgdwAxes[nAxisCount] = DIJOFS_Y;
1871 if(lXCoefficient == 0 && lYCoefficient == 0)
1874 rgdwAxes[0] = DIJOFS_X;
1875 rgdwAxes[1] = DIJOFS_Y;
1878 DWORD cbTypeSpecificParams;
1879 PVOID pvTypeSpecificParams;
1881 if (nAxisCount == 1) {
1882 cbTypeSpecificParams = sizeof(DICONDITION[1]);
1884 pvTypeSpecificParams = &ptr->DIConditionStruct[0];
1886 pvTypeSpecificParams = &ptr->DIConditionStruct[1];
1889 cbTypeSpecificParams = sizeof(DICONDITION[2]);
1890 pvTypeSpecificParams = &ptr->DIConditionStruct[0];
1893 ptr->rglDirection[0] = 0;
1894 ptr->rglDirection[1] = 0;
1896 ptr->DIEffectStruct.dwSize = sizeof(DIEFFECT);
1897 ptr->DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
1898 ptr->DIEffectStruct.dwDuration = dwDuration;
1899 ptr->DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1900 ptr->DIEffectStruct.dwGain = 10000;
1901 ptr->DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
1902 ptr->DIEffectStruct.dwTriggerRepeatInterval = 0;
1903 ptr->DIEffectStruct.cAxes = nAxisCount;
1904 ptr->DIEffectStruct.rgdwAxes = rgdwAxes;
1905 ptr->DIEffectStruct.rglDirection = ptr->rglDirection;
1906 ptr->DIEffectStruct.lpEnvelope = NULL;
1907 ptr->DIEffectStruct.cbTypeSpecificParams = cbTypeSpecificParams;
1908 ptr->DIEffectStruct.lpvTypeSpecificParams = pvTypeSpecificParams;
1911 hResult = pDIDevice->CreateEffect(guid, &ptr->DIEffectStruct, ppDIEffect, NULL);
1916 // ----------------------------------------------------------------------------
1917 // Function: SWFF_CreateConditionEffect
1918 // Purpose: Creates a Condition type Effect with specified params
1919 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1920 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1921 // DWORD dwType - SPRING | INERTIA | DAMPER | FRICTION
1922 // DWORD dwDuration - Duration in uS
1923 // LONG lXCoefficient - Coefficient in -10000 to 10000
1924 // LONG lXOffset - Offset in -10000 to 10000
1925 // LONG lYCoefficient - Coefficient in -10000 to 10000
1926 // LONG lYOffset - Offset in -10000 to 10000
1927 // LONG lButton - Index of playback button, -1 for none
1931 // To create a 1D Friction, set the lFx or lFy parameter to 0
1932 // To create a 2D Friction, set both lFx and lFy parameter to non-zero
1933 // or set both lFx and lFy to zero
1935 // ----------------------------------------------------------------------------
1936 HRESULT SWFF_CreateConditionEffect(
1937 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1938 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1940 IN DWORD dwDuration,
1941 IN LONG lXCoefficient,
1943 IN LONG lYCoefficient,
1947 if(pDIDevice == NULL || ppDIEffect == NULL)
1948 return SFERR_INVALID_PARAM;
1950 // Always clear return IPtr
1960 guid = GUID_Inertia;
1966 guid = GUID_Friction;
1972 DICONDITION DIConditionStruct[2];
1973 DIConditionStruct[0].lOffset = lXOffset;
1974 DIConditionStruct[0].lPositiveCoefficient = lXCoefficient;
1975 DIConditionStruct[0].lNegativeCoefficient = lXCoefficient;
1976 DIConditionStruct[0].dwPositiveSaturation = 10000;
1977 DIConditionStruct[0].dwNegativeSaturation = 10000;
1978 DIConditionStruct[0].lDeadBand = 0;
1979 DIConditionStruct[1].lOffset = lYOffset;
1980 DIConditionStruct[1].lPositiveCoefficient = lYCoefficient;
1981 DIConditionStruct[1].lNegativeCoefficient = lYCoefficient;
1982 DIConditionStruct[1].dwPositiveSaturation = 10000;
1983 DIConditionStruct[1].dwNegativeSaturation = 10000;
1984 DIConditionStruct[1].lDeadBand = 0;
1988 if(lXCoefficient != 0)
1990 rgdwAxes[nAxisCount] = DIJOFS_X;
1993 if(lYCoefficient != 0)
1995 rgdwAxes[nAxisCount] = DIJOFS_Y;
1998 if(lXCoefficient == 0 && lYCoefficient == 0)
2001 rgdwAxes[0] = DIJOFS_X;
2002 rgdwAxes[1] = DIJOFS_Y;
2005 DWORD cbTypeSpecificParams;
2006 PVOID pvTypeSpecificParams;
2009 cbTypeSpecificParams = sizeof(DICONDITION[1]);
2010 if(lXCoefficient != 0)
2011 pvTypeSpecificParams = &DIConditionStruct[0];
2013 pvTypeSpecificParams = &DIConditionStruct[1];
2017 cbTypeSpecificParams = sizeof(DICONDITION[2]);
2018 pvTypeSpecificParams = &DIConditionStruct[0];
2021 LONG rglDirection[2];
2022 rglDirection[0] = 0;
2023 rglDirection[1] = 0;
2025 DIEFFECT DIEffectStruct;
2026 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2027 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
2028 DIEffectStruct.dwDuration = dwDuration;
2029 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2030 DIEffectStruct.dwGain = 10000;
2031 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2032 DIEffectStruct.dwTriggerRepeatInterval = 0;
2033 DIEffectStruct.cAxes = nAxisCount;
2034 DIEffectStruct.rgdwAxes = rgdwAxes;
2035 DIEffectStruct.rglDirection = rglDirection;
2036 DIEffectStruct.lpEnvelope = NULL;
2037 DIEffectStruct.cbTypeSpecificParams = cbTypeSpecificParams;
2038 DIEffectStruct.lpvTypeSpecificParams = pvTypeSpecificParams;
2041 hResult = pDIDevice->CreateEffect(guid, &DIEffectStruct, ppDIEffect, NULL);
2046 // ----------------------------------------------------------------------------
2047 // Function: SWFF_CreateRampEffect
2048 // Purpose: Creates a Ramp type Effect with specified params
2049 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2050 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2051 // DWORD dwDuration - uS
2052 // DWORD dwDirection - 0 to 35999
2053 // LONG lStart - -10000 to 10000
2054 // LONG lEnd - -10000 to 10000
2055 // DWORD dwAttackTime - Envelope Attack Time in uS
2056 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
2057 // DWORD dwFadeTime - Envelope Fade time in uS
2058 // DWORD dwFadeLevel - Envelope Fade Level
2059 // LONG lButton - Index of playback button, -1 for none
2064 // ----------------------------------------------------------------------------
2065 HRESULT SWFF_CreateRampEffect(
2066 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2067 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2068 IN DWORD dwDuration,
2069 IN DWORD dwDirection,
2072 IN DWORD dwAttackTime,
2073 IN DWORD dwAttackLevel,
2074 IN DWORD dwFadeTime,
2075 IN DWORD dwFadeLevel,
2078 if(pDIDevice == NULL || ppDIEffect == NULL)
2079 return SFERR_INVALID_PARAM;
2081 // Always clear return IPtr
2084 DIRAMPFORCE DIRampStruct;
2085 DIRampStruct.lStart = lStart;
2086 DIRampStruct.lEnd = lEnd;
2088 DIENVELOPE DIEnvelopeStruct;
2089 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
2090 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
2091 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
2092 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
2093 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
2096 rgdwAxes[0] = DIJOFS_X;
2097 rgdwAxes[1] = DIJOFS_Y;
2099 LONG rglDirection[2];
2100 rglDirection[0] = dwDirection;
2101 rglDirection[1] = 0;
2103 DIEFFECT DIEffectStruct;
2104 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2105 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2106 DIEffectStruct.dwDuration = dwDuration;
2107 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2108 DIEffectStruct.dwGain = 10000;
2109 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2110 DIEffectStruct.dwTriggerRepeatInterval = 0;
2111 DIEffectStruct.cAxes = 2;
2112 DIEffectStruct.rgdwAxes = rgdwAxes;
2113 DIEffectStruct.rglDirection = rglDirection;
2114 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
2115 DIEffectStruct.cbTypeSpecificParams = sizeof(DIRampStruct);
2116 DIEffectStruct.lpvTypeSpecificParams = &DIRampStruct;
2119 hResult = pDIDevice->CreateEffect(GUID_RampForce, &DIEffectStruct, ppDIEffect, NULL);
2124 // ----------------------------------------------------------------------------
2125 // Function: SWFF_CreateConstantForceEffect
2126 // Purpose: Creates a ConstantForce type Effect with specified params
2127 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2128 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2129 // DWORD dwDuration - in uS
2130 // DWORD dwDirection - in 0 to 35999
2131 // LONG lMagnitude - in -10000 to 10000
2132 // DWORD dwAttackTime - Envelope Attack Time in uS
2133 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
2134 // DWORD dwFadeTime - Envelope Fade time in uS
2135 // DWORD dwFadeLevel - Envelope Fade Level
2136 // LONG lButton - Index of playback button, -1 for none
2141 // ----------------------------------------------------------------------------
2142 HRESULT SWFF_CreateConstantForceEffect(
2143 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2144 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2145 IN DWORD dwDuration,
2146 IN DWORD dwDirection,
2148 IN DWORD dwAttackTime,
2149 IN DWORD dwAttackLevel,
2150 IN DWORD dwFadeTime,
2151 IN DWORD dwFadeLevel,
2154 if(pDIDevice == NULL || ppDIEffect == NULL)
2155 return SFERR_INVALID_PARAM;
2157 // Always clear return IPtr
2160 DICONSTANTFORCE DIConstantForceStruct;
2161 DIConstantForceStruct.lMagnitude = lMagnitude;
2163 DIENVELOPE DIEnvelopeStruct;
2164 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
2165 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
2166 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
2167 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
2168 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
2171 rgdwAxes[0] = DIJOFS_X;
2172 rgdwAxes[1] = DIJOFS_Y;
2174 LONG rglDirection[2];
2175 rglDirection[0] = dwDirection;
2176 rglDirection[1] = 0;
2178 DIEFFECT DIEffectStruct;
2179 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2180 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2181 DIEffectStruct.dwDuration = dwDuration;
2182 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2183 DIEffectStruct.dwGain = 10000;
2184 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2185 DIEffectStruct.dwTriggerRepeatInterval = 0;
2186 DIEffectStruct.cAxes = 2;
2187 DIEffectStruct.rgdwAxes = rgdwAxes;
2188 DIEffectStruct.rglDirection = rglDirection;
2189 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
2190 DIEffectStruct.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
2191 DIEffectStruct.lpvTypeSpecificParams = &DIConstantForceStruct;
2194 hResult = pDIDevice->CreateEffect(GUID_ConstantForce, &DIEffectStruct, ppDIEffect, NULL);
2200 // ----------------------------------------------------------------------------
2201 // Function: SWFF_CreateWallEffect
2202 // Purpose: Creates a Wall Effect
2203 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2204 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2205 // DWORD dwDuration - in uS
2206 // DWORD dwDirection - 0 | 9000 | 18000 | 27000
2207 // DWORD dwDistance - Distance from centerin 0 to 10000
2208 // BOOL bInner - T/F = Inner/Outer
2209 // LONG lCoefficient - Wall Constant in 0 to 10000
2210 // LONG lButton - Index of playback button, -1 for none
2215 // ----------------------------------------------------------------------------
2217 HRESULT SWFF_CreateWallEffect(
2218 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2219 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2220 IN DWORD dwDuration,
2221 IN DWORD dwDirection,
2222 IN DWORD dwDistance,
2224 IN LONG lWallCoefficient,
2227 if(pDIDevice == NULL || ppDIEffect == NULL)
2228 return SFERR_INVALID_PARAM;
2230 // Always clear return IPtr
2233 BE_WALL_PARAM WallStruct;
2234 WallStruct.m_Bytes = sizeof(WallStruct);
2235 WallStruct.m_WallType = bInner ? WALL_INNER : WALL_OUTER;
2236 WallStruct.m_WallConstant = lWallCoefficient;
2237 WallStruct.m_WallAngle = dwDirection;
2238 WallStruct.m_WallDistance = dwDistance;
2242 rgdwAxes[0] = DIJOFS_X;
2243 rgdwAxes[1] = DIJOFS_Y;
2245 LONG rglDirection[2];
2246 rglDirection[0] = 0;
2247 rglDirection[1] = 0;
2249 DIEFFECT DIEffectStruct;
2250 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2251 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2252 DIEffectStruct.dwDuration = dwDuration;
2253 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2254 DIEffectStruct.dwGain = 10000;
2255 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2256 DIEffectStruct.dwTriggerRepeatInterval = 0;
2257 DIEffectStruct.cAxes = 2;
2258 DIEffectStruct.rgdwAxes = rgdwAxes;
2259 DIEffectStruct.rglDirection = rglDirection;
2260 DIEffectStruct.lpEnvelope = NULL;
2261 DIEffectStruct.cbTypeSpecificParams = sizeof(WallStruct);
2262 DIEffectStruct.lpvTypeSpecificParams = &WallStruct;
2265 hResult = pDIDevice->CreateEffect(GUID_Wall, &DIEffectStruct, ppDIEffect, NULL);
2272 // ----------------------------------------------------------------------------
2273 // FUNCTION: SWFF_GetJoyData
2274 // PURPOSE: Retrieves Joystick data
2275 // PARAMETERS: int nJoyID - JOYSTICKID1-16
2276 // JOYINFOEX *pjix - PTR to a JOYYINFOEX structure
2277 // char *pszErr - Ptr to Error code string
2278 // RETURNS: JOYINFOEX filled in
2280 // The axis and buttons info:
2281 // All axis are in the range 0 to 65535.
2282 // jix.dwXpos - X position.
2283 // jix.dwYpos - Y position.
2284 // jix.dwZpos - Throttle slider control
2285 // jix.dwRpos - Z Rotation position.
2287 // To see if button 1 is pressed:
2288 // (jix.dwButtons & JOY_BUTTON1) ? PRESSED : NOT_PRESSED;
2289 // likewise for the other buttons JOY_BUTTON2, JOY_BUTTON3
\85
2292 // Hat Switch (POV) is in jix.dwPOV
2293 // The range is 0 to 35900 and the value is -1 if the
2294 // Hat Switch is not pressed.
2296 // TRUE if successful, else FALSE
2298 // ----------------------------------------------------------------------------
2299 BOOL SWFF_GetJoyData(int nJoyID, JOYINFOEX * pjix, char *pszErr)
2301 if(pjix == NULL || pszErr == NULL)
2304 memset(pjix, 0x00, sizeof(JOYINFOEX)); // for good measure
2305 pjix->dwSize = sizeof(JOYINFOEX);
2307 // NOTE: With SideWinder Digital OverDrive, it takes no more time to return all
2308 // information from the joystick than it does to just get
2309 // the button states or axis.
2311 pjix->dwFlags = JOY_RETURNALL;
2314 // joyGetPoxEx will fill in the joyinfoex struct with all the
2315 // joystick information
2318 switch(joyGetPosEx(nJoyID, pjix))
2320 case JOYERR_NOERROR: // no problem
2321 strcpy(pszErr,"SUCCESS");
2324 case MMSYSERR_NODRIVER:
2325 strcpy(pszErr,"The joystick driver is not present.");
2328 case MMSYSERR_INVALPARAM:
2329 strcpy(pszErr,"An invalid parameter was passed.");
2332 case MMSYSERR_BADDEVICEID:
2333 strcpy(pszErr,"The specified joystick identifier is invalid.");
2336 case JOYERR_UNPLUGGED:
2337 strcpy(pszErr,"Your joystick is unplugged.");
2341 strcpy(pszErr,"Unknown joystick error.");
2349 // ----------------------------------------------------------------------------
2350 // FUNCTION: SWFF_GetJoyData2
2351 // PURPOSE: Retrieves Joystick data using DInput calls
2352 // PARAMETERS: LPDIRECTINPUTDEVICE2 pDIDevice - Pointer to DirectInputDevice
2353 // LPDIJOYSTATE pjs - PTR to a DIJOYSTATE structure
2354 // RETURNS: DIJOYSTATE filled in
2357 // all axes have range from 0 to 65535
2358 // pjs->lX - X position
2359 // pjs->lY - Y position
2360 // pjs->lZ - Throttle position
2362 // To see if button 0 is pressed:
2363 // (pjs->rgbButtons[0] & 0x80) ? PRESSED : NOT_PRESSED;
2364 // likewise for the other buttons pjs->rgbButtons[1],
2365 // pjs->rgbButtons[2]
2367 // Hat Switch (POV) is in pjs->rgdwPov[0]
2368 // The range is 0 to 35999 and the value is -1 if the
2369 // Hat Switch is not pressed.
2372 // ----------------------------------------------------------------------------
2373 /*HRESULT SWFF_GetJoyData2(
2374 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2375 IN OUT LPDIJOYSTATE pjs)
2379 if(pDIDevice == NULL || pjs == NULL)
2380 return SFERR_INVALID_PARAM;
2382 memset(pjs, 0x00, sizeof(DIJOYSTATE)); // for good measure
2384 // NOTE: With SideWinder Digital OverDrive, it takes no more time to return all
2385 // information from the joystick than it does to just get
2386 // the button states or axis.
2389 // must poll before using GetDeviceState(...)
2390 hResult = pDIDevice->Poll();
2394 // retrieve the values cached during Poll()
2395 hResult = pDIDevice->GetDeviceState(sizeof(DIJOYSTATE), pjs);
2401 // ----------------------------------------------------------------------------
2402 // Function: SWFF_ErrorCodeToString
2403 // Parameters: HRESULT hResult - Error Code
2404 // TCHAR * pszString - Ptr to string to fill with code
2409 // ----------------------------------------------------------------------------
2410 void SWFF_ErrorCodeToString(HRESULT hResult, TCHAR * pszCodeString)
2412 if(pszCodeString == NULL)
2419 case S_FALSE: strcpy(pszCodeString, "S_FALSE"); break;
2420 case DI_POLLEDDEVICE: strcpy(pszCodeString, "DI_POLLEDDEVICE"); break;
2421 // case DI_DOWNLOADSKIPPED: strcpy(pszCodeString, "DI_DOWNLOADSKIPPED"); break;
2422 // case DI_EFFECTRESTARTED: strcpy(pszCodeString, "DI_EFFECTRESTARTED"); break;
2423 case DIERR_OLDDIRECTINPUTVERSION: strcpy(pszCodeString, "DIERR_OLDDIRECTINPUTVERSION" ); break;
2424 case DIERR_BETADIRECTINPUTVERSION: strcpy(pszCodeString, "DIERR_BETADIRECTINPUTVERSION" ); break;
2425 case DIERR_BADDRIVERVER: strcpy(pszCodeString, "DIERR_BADDRIVERVER" ); break;
2426 case DIERR_DEVICENOTREG: strcpy(pszCodeString, "DIERR_DEVICENOTREG" ); break;
2427 case DIERR_NOTFOUND: strcpy(pszCodeString, "DIERR_NOTFOUND" ); break;
2428 case DIERR_INVALIDPARAM: strcpy(pszCodeString, "DIERR_INVALIDPARAM" ); break;
2429 case DIERR_NOINTERFACE: strcpy(pszCodeString, "DIERR_NOINTERFACE" ); break;
2430 case DIERR_GENERIC: strcpy(pszCodeString, "DIERR_GENERIC" ); break;
2431 case DIERR_OUTOFMEMORY: strcpy(pszCodeString, "DIERR_OUTOFMEMORY" ); break;
2432 case DIERR_UNSUPPORTED: strcpy(pszCodeString, "DIERR_UNSUPPORTED" ); break;
2433 case DIERR_NOTINITIALIZED: strcpy(pszCodeString, "DIERR_NOTINITIALIZED" ); break;
2434 case DIERR_ALREADYINITIALIZED: strcpy(pszCodeString, "DIERR_ALREADYINITIALIZED" ); break;
2435 case DIERR_NOAGGREGATION: strcpy(pszCodeString, "DIERR_NOAGGREGATION" ); break;
2436 case DIERR_INPUTLOST: strcpy(pszCodeString, "DIERR_INPUTLOST" ); break;
2437 case DIERR_ACQUIRED: strcpy(pszCodeString, "DIERR_ACQUIRED" ); break;
2438 case DIERR_NOTACQUIRED: strcpy(pszCodeString, "DIERR_NOTACQUIRED" ); break;
2439 case E_ACCESSDENIED: strcpy(pszCodeString, "E_ACCESSDENIED: DIERR_OTHERAPPHASPRIO, DIERR_READONLY, DIERR_HANDLEEXISTS"); break;
2440 case E_PENDING: strcpy(pszCodeString, "E_PENDING" ); break;
2441 case DIERR_INSUFFICIENTPRIVS: strcpy(pszCodeString, "DIERR_INSUFFICIENTPRIVS" ); break;
2442 case DIERR_DEVICEFULL: strcpy(pszCodeString, "DIERR_DEVICEFULL" ); break;
2443 case DIERR_MOREDATA: strcpy(pszCodeString, "DIERR_MOREDATA" ); break;
2444 case DIERR_NOTDOWNLOADED: strcpy(pszCodeString, "DIERR_NOTDOWNLOADED" ); break;
2445 case DIERR_HASEFFECTS: strcpy(pszCodeString, "DIERR_HASEFFECTS" ); break;
2446 case DIERR_NOTEXCLUSIVEACQUIRED: strcpy(pszCodeString, "DIERR_NOTEXCLUSIVEACQUIRED"); break;
2447 case DIERR_INCOMPLETEEFFECT: strcpy(pszCodeString, "DIERR_INCOMPLETEEFFECT" ); break;
2448 case DIERR_NOTBUFFERED: strcpy(pszCodeString, "DIERR_NOTBUFFERED" ); break;
2449 case DIERR_EFFECTPLAYING: strcpy(pszCodeString, "DIERR_EFFECTPLAYING"); break;
2450 case SFERR_INVALID_OBJECT: strcpy(pszCodeString, "SFERR_INVALID_OBJECT" ); break;
2451 case SFERR_END_OF_LIST: strcpy(pszCodeString, "SFERR_END_OF_LIST" ); break;
2452 case SFERR_DEVICE_NACK: strcpy(pszCodeString, "SFERR_DEVICE_NACK" ); break;
2453 case SFERR_RAW_OUT_DATAEVENT_CREATION: strcpy(pszCodeString, "SFERR_RAW_OUT_DATAEVENT_CREATION" ); break;
2454 case SFERR_RAW_OUT_THREAD_CREATION: strcpy(pszCodeString, "SFERR_RAW_OUT_THREAD_CREATION" ); break;
2455 case SFERR_SYSTEM_INIT: strcpy(pszCodeString, "SFERR_SYSTEM_INIT" ); break;
2456 case SFERR_DRIVER_ERROR: strcpy(pszCodeString, "SFERR_DRIVER_ERROR" ); break;
2457 case SFERR_NON_FF_DEVICE: strcpy(pszCodeString, "SFERR_NON_FF_DEVICE" ); break;
2458 case SFERR_INVALID_HAL_OBJECT: strcpy(pszCodeString, "SFERR_INVALID_HAL_OBJECT" ); break;
2459 case VFX_ERR_FILE_NOT_FOUND: strcpy(pszCodeString, "VFX_ERR_FILE_NOT_FOUND" ); break;
2460 case VFX_ERR_FILE_CANNOT_OPEN: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_OPEN" ); break;
2461 case VFX_ERR_FILE_CANNOT_CLOSE: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_CLOSE" ); break;
2462 case VFX_ERR_FILE_CANNOT_READ: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_READ" ); break;
2463 case VFX_ERR_FILE_CANNOT_WRITE: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_WRITE" ); break;
2464 case VFX_ERR_FILE_CANNOT_SEEK: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_SEEK" ); break;
2465 case VFX_ERR_FILE_UNKNOWN_ERROR: strcpy(pszCodeString, "VFX_ERR_FILE_UNKNOWN_ERROR" ); break;
2466 case VFX_ERR_FILE_BAD_FORMAT: strcpy(pszCodeString, "VFX_ERR_FILE_BAD_FORMAT" ); break;
2467 case VFX_ERR_FILE_ACCESS_DENIED: strcpy(pszCodeString, "VFX_ERR_FILE_ACCESS_DENIED" ); break;
2468 case VFX_ERR_FILE_SHARING_VIOLATION: strcpy(pszCodeString, "VFX_ERR_FILE_SHARING_VIOLATION" ); break;
2469 case VFX_ERR_FILE_NETWORK_ERROR: strcpy(pszCodeString, "VFX_ERR_FILE_NETWORK_ERROR" ); break;
2470 case VFX_ERR_FILE_TOO_MANY_OPEN_FILES: strcpy(pszCodeString, "VFX_ERR_FILE_TOO_MANY_OPEN_FILES" ); break;
2471 case VFX_ERR_FILE_INVALID: strcpy(pszCodeString, "VFX_ERR_FILE_INVALID" ); break;
2472 case VFX_ERR_FILE_END_OF_FILE: strcpy(pszCodeString, "VFX_ERR_FILE_END_OF_FILE" ); break;
2473 case SWDEV_ERR_INVALID_ID : strcpy(pszCodeString, "SWDEV_ERR_INVALID_ID" ); break;
2474 case SWDEV_ERR_INVALID_PARAM : strcpy(pszCodeString, "SWDEV_ERR_INVALID_PARAM" ); break;
2475 case SWDEV_ERR_CHECKSUM : strcpy(pszCodeString, "SWDEV_ERR_CHECKSUM" ); break;
2476 case SWDEV_ERR_TYPE_FULL : strcpy(pszCodeString, "SWDEV_ERR_TYPE_FULL" ); break;
2477 case SWDEV_ERR_UNKNOWN_CMD : strcpy(pszCodeString, "SWDEV_ERR_UNKNOWN_CMD" ); break;
2478 case SWDEV_ERR_PLAYLIST_FULL : strcpy(pszCodeString, "SWDEV_ERR_PLAYLIST_FULL" ); break;
2479 case SWDEV_ERR_PROCESSLIST_FULL : strcpy(pszCodeString, "SWDEV_ERR_PROCESSLIST_FULL" ); break;
2480 default: sprintf(pszCodeString, "%x", hResult); break;