1 /****************************************************************************
2
3 Module name: SWFF_LIB.cpp
4
5 (C) Copyright Microsoft Corp. 1993. All rights reserved.
6
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.
12
13
14 Purpose: This module provides routines to simplify creating Effects
15 using the DirectInput Force Feedback subsystem.
16
17 Algorithm:
18
19 Version Date Author Comments
20 ------- --------- ------ --------
21 1.1 01-Apr-97 MEA/DJS
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
29
30
31 ****************************************************************************/
32
33
34 #include "globalincs/pstypes.h"
35
36 #include <windows.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include "mmsystem.h"
40 #include "io/sw_force.h" // SideWinder Force Feedback Header File
41
42 #define INITGUIDS // Make GUID available
43 #include "sw_guid.hpp"
44 #include "directx/vdinput.h"
45 #undef INITGUIDS
46
47
48 BOOL CALLBACK DIEnumAndDestroyCreatedEffectsProc(LPDIRECTINPUTEFFECT pDIEffect, LPVOID lpvRef);
49 BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID lpvContext);
50
51
52 // ----------------------------------------------------------------------------
53 //
54 // ***** FUNCTIONS ************************************************************
55 //
56 // ----------------------------------------------------------------------------
57
58 // ----------------------------------------------------------------------------
59 // Function: SWFF_OpenDefaultFFJoystick
60 // Parameters: HWND hWnd - Client Window Handle
61 // LPDIRECTINPUT* ppDI - Pointer to DIRECTINPUT
62 // LPDIRECTINPUTDEVICE2* ppDIDevice) - Pointer to IDIRECTINPUTDEVICE2
63 //
64 // Returns:
65 // Algorithm:
66 // Comments:
67 // ----------------------------------------------------------------------------
SWFF_OpenDefaultFFJoystick(IN HWND hWnd,LPDIRECTINPUT * ppDI,LPDIRECTINPUTDEVICE2 * ppDIDevice)68 HRESULT SWFF_OpenDefaultFFJoystick(
69 IN HWND hWnd,
70 LPDIRECTINPUT* ppDI,
71 LPDIRECTINPUTDEVICE2* ppDIDevice)
72 {
73 HRESULT hResult;
74 if(hWnd == NULL || ppDI == NULL || ppDIDevice == NULL)
75 {
76 return SFERR_INVALID_PARAM;
77 }
78
79 // create the DirectInput object
80 hResult = DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, ppDI, NULL);
81 if(FAILED(hResult))
82 return hResult;
83
84 // enumerate the first attached joystick
85 // instance goes in pDIDeviceInstance
86 DIDEVICEINSTANCE DIDeviceInstance;
87 DIDeviceInstance.dwDevType = 0;
88 hResult = (*ppDI)->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc, &DIDeviceInstance, DIEDFL_FORCEFEEDBACK);
89 if(FAILED(hResult))
90 {
91 (*ppDI)->Release();
92 *ppDI = NULL;
93 return hResult;
94 }
95 if(DIDeviceInstance.dwDevType == 0)
96 {
97 (*ppDI)->Release();
98 *ppDI = NULL;
99 return DIERR_DEVICENOTREG;
100 }
101
102 // create the DirectInput Device object
103 LPDIRECTINPUTDEVICE pDIDevice = NULL;
104 hResult = (*ppDI)->CreateDevice(DIDeviceInstance.guidInstance, &pDIDevice, NULL);
105 if(FAILED(hResult))
106 {
107 (*ppDI)->Release();
108 *ppDI = NULL;
109 return hResult;
110 }
111
112 // get a pointer to its DirectInputDevice2 interface
113 hResult = pDIDevice->QueryInterface(IID_IDirectInputDevice2, (void**)ppDIDevice);
114 if(FAILED(hResult))
115 {
116 pDIDevice->Release();
117 pDIDevice = NULL;
118 (*ppDI)->Release();
119 *ppDI = NULL;
120 return hResult;
121 }
122 pDIDevice->Release();
123 pDIDevice = NULL;
124
125 // set the data format to the pre-defined DirectInput joystick format
126 hResult = (*ppDIDevice)->SetDataFormat(&c_dfDIJoystick);
127 if(FAILED(hResult))
128 {
129 (*ppDIDevice)->Release();
130 *ppDIDevice = NULL;
131 (*ppDI)->Release();
132 *ppDI = NULL;
133 return hResult;
134 }
135
136 // set the cooperative level
137 hResult = (*ppDIDevice)->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
138 if(FAILED(hResult))
139 {
140 (*ppDIDevice)->Release();
141 *ppDIDevice = NULL;
142 (*ppDI)->Release();
143 *ppDI = NULL;
144 return hResult;
145 }
146
147 // turn auto-center off
148 /* DIPROPDWORD DIPropAutoCenter;
149 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
150 DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
151 DIPropAutoCenter.diph.dwObj = 0;
152 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
153 DIPropAutoCenter.dwData = 0;
154
155 hResult = (*ppDIDevice)->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
156 if(FAILED(hResult))
157 {
158 (*ppDIDevice)->Release();
159 *ppDIDevice = NULL;
160 (*ppDI)->Release();
161 *ppDI = NULL;
162 return hResult;
163 }
164 */
165 // acquire the joystick
166 hResult = (*ppDIDevice)->Acquire();
167 if(FAILED(hResult))
168 {
169 (*ppDIDevice)->Release();
170 *ppDIDevice = NULL;
171 (*ppDI)->Release();
172 *ppDI = NULL;
173 return hResult;
174 }
175 return SUCCESS;
176 }
177
178
179 // ----------------------------------------------------------------------------
180 // Function: SWFF_OpenDefaultFFJoystickEx
181 // Parameters: HWND hWnd - Client Window Handle
182 // LPDIRECTINPUT* ppDI - Pointer to IDIRECTINPUT
183 // HINSTANCE hInstance - object instance handle
184 // LPDIRECTINPUTDEVICE2* ppDIDevice) - Pointer to IDIRECTINPUTDEVICE2
185 // DWORD dwFlags - DISCL_EXCLUSIVE | DISCL_FOREGROUND
186 //
187 // Returns:
188 // Algorithm:
189 // Comments:
190 // ----------------------------------------------------------------------------
SWFF_OpenDefaultFFJoystickEx(IN HWND hWnd,IN HINSTANCE hInstance,OUT LPDIRECTINPUT * ppDI,OUT LPDIRECTINPUTDEVICE2 * ppDIDevice,IN DWORD dwFlags)191 HRESULT SWFF_OpenDefaultFFJoystickEx(
192 IN HWND hWnd,
193 IN HINSTANCE hInstance,
194 OUT LPDIRECTINPUT* ppDI,
195 OUT LPDIRECTINPUTDEVICE2* ppDIDevice,
196 IN DWORD dwFlags)
197 {
198 HRESULT hResult;
199 if(hWnd == NULL || hInstance == NULL || ppDI == NULL || ppDIDevice == NULL)
200 {
201 return SFERR_INVALID_PARAM;
202 }
203
204 // create the DirectInput object
205 hResult = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, ppDI, NULL);
206 if(FAILED(hResult))
207 return hResult;
208
209 // enumerate the first attached joystick
210 // instance goes in pDIDeviceInstance
211 DIDEVICEINSTANCE DIDeviceInstance;
212 DIDeviceInstance.dwDevType = 0;
213 hResult = (*ppDI)->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc, &DIDeviceInstance, DIEDFL_FORCEFEEDBACK);
214 if(FAILED(hResult))
215 {
216 (*ppDI)->Release();
217 *ppDI = NULL;
218 return hResult;
219 }
220 if(DIDeviceInstance.dwDevType == 0)
221 {
222 (*ppDI)->Release();
223 *ppDI = NULL;
224 return DIERR_DEVICENOTREG;
225 }
226
227 // create the DirectInput Device object
228 LPDIRECTINPUTDEVICE pDIDevice = NULL;
229 hResult = (*ppDI)->CreateDevice(DIDeviceInstance.guidInstance, &pDIDevice, NULL);
230 if(FAILED(hResult))
231 {
232 (*ppDI)->Release();
233 *ppDI = NULL;
234 return hResult;
235 }
236
237 // get a pointer to its DirectInputDevice2 interface
238 hResult = pDIDevice->QueryInterface(IID_IDirectInputDevice2, (void**)ppDIDevice);
239 if(FAILED(hResult))
240 {
241 pDIDevice->Release();
242 pDIDevice = NULL;
243 (*ppDI)->Release();
244 *ppDI = NULL;
245 return hResult;
246 }
247 pDIDevice->Release();
248 pDIDevice = NULL;
249
250 // set the data format to the pre-defined DirectInput joystick format
251 hResult = (*ppDIDevice)->SetDataFormat(&c_dfDIJoystick);
252 if(FAILED(hResult))
253 {
254 (*ppDIDevice)->Release();
255 *ppDIDevice = NULL;
256 (*ppDI)->Release();
257 *ppDI = NULL;
258 return hResult;
259 }
260
261 // set the cooperative level
262 hResult = (*ppDIDevice)->SetCooperativeLevel(hWnd, dwFlags);
263 if(FAILED(hResult))
264 {
265 (*ppDIDevice)->Release();
266 *ppDIDevice = NULL;
267 (*ppDI)->Release();
268 *ppDI = NULL;
269 return hResult;
270 }
271
272 // turn auto-center off
273 DIPROPDWORD DIPropAutoCenter;
274 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
275 DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
276 DIPropAutoCenter.diph.dwObj = 0;
277 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
278 DIPropAutoCenter.dwData = 0;
279
280 hResult = (*ppDIDevice)->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
281 if(FAILED(hResult))
282 {
283 (*ppDIDevice)->Release();
284 *ppDIDevice = NULL;
285 (*ppDI)->Release();
286 *ppDI = NULL;
287 return hResult;
288 }
289
290 // acquire the joystick
291 hResult = (*ppDIDevice)->Acquire();
292 if(FAILED(hResult))
293 {
294 (*ppDIDevice)->Release();
295 *ppDIDevice = NULL;
296 (*ppDI)->Release();
297 *ppDI = NULL;
298 return hResult;
299 }
300 return SUCCESS;
301 }
302
303
DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi,LPVOID lpvContext)304 BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID lpvContext)
305 {
306 LPDIDEVICEINSTANCE pDIDeviceInstance = (LPDIDEVICEINSTANCE)lpvContext;
307 if(pDIDeviceInstance == NULL)
308 {
309 return DIENUM_STOP;
310 }
311
312 if(GET_DIDEVICE_TYPE(lpddi->dwDevType) == DIDEVTYPE_JOYSTICK)
313 {
314 memcpy((LPVOID)pDIDeviceInstance, (LPVOID)lpddi, sizeof(*pDIDeviceInstance));
315
316 return DIENUM_STOP;
317 }
318
319 return DIENUM_CONTINUE;
320 }
321
322 // ----------------------------------------------------------------------------
323 // Function: SWFF_DestroyEffect
324 // Purpose: Destroys one effect or all effects
325 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
326 // LPDIRECTINPUTEFFECT pDIEffect - Effect to destroy
327 // - NULL destroys all effects
328 // Returns:
329 // Algorithm:
330 // Comments:
331 //
332 // ----------------------------------------------------------------------------
SWFF_DestroyEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN LPDIRECTINPUTEFFECT pDIEffect)333 HRESULT SWFF_DestroyEffect(
334 IN LPDIRECTINPUTDEVICE2 pDIDevice,
335 IN LPDIRECTINPUTEFFECT pDIEffect)
336 {
337 HRESULT hResult = SUCCESS;
338 if(pDIEffect != NULL)
339 {
340 pDIEffect->Release();
341 }
342 else
343 hResult = SWFF_DestroyAllEffects(pDIDevice);
344
345 return hResult;
346 }
347
348 // ----------------------------------------------------------------------------
349 // Function: SWFF_DestroyAllEffects
350 // Purpose: Destroys all created effects
351 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
352 // Returns:
353 // Algorithm:
354 // Comments:
355 //
356 // ----------------------------------------------------------------------------
SWFF_DestroyAllEffects(IN LPDIRECTINPUTDEVICE2 pDIDevice)357 HRESULT SWFF_DestroyAllEffects(
358 IN LPDIRECTINPUTDEVICE2 pDIDevice)
359 {
360 HRESULT hResult;
361
362 if(pDIDevice == NULL)
363 return SFERR_INVALID_PARAM;
364
365 hResult = pDIDevice->EnumCreatedEffectObjects(DIEnumAndDestroyCreatedEffectsProc, NULL, 0);
366
367 return hResult;
368 }
369
370 #pragma warning(disable:4100) // unreferenced formal parameter
DIEnumAndDestroyCreatedEffectsProc(LPDIRECTINPUTEFFECT pDIEffect,LPVOID lpvRef)371 BOOL CALLBACK DIEnumAndDestroyCreatedEffectsProc(LPDIRECTINPUTEFFECT pDIEffect, LPVOID lpvRef)
372 {
373 pDIEffect->Release();
374
375 return DIENUM_CONTINUE;
376 }
377 #pragma warning(default:4100) // unreferenced formal parameter
378
379 // ----------------------------------------------------------------------------
380 // Function: SWFF_SetGain
381 // Purpose: Sets Gain for the Effect
382 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the gain for
383 // DWORD dwGain - Gain in 1 to 10000
384 // Returns:
385 // Algorithm:
386 // Comments:
387 //
388 // ----------------------------------------------------------------------------
SWFF_SetGain(IN LPDIRECTINPUTEFFECT pDIEffect,IN DWORD dwGain)389 HRESULT SWFF_SetGain(
390 IN LPDIRECTINPUTEFFECT pDIEffect,
391 IN DWORD dwGain)
392 {
393 if(pDIEffect == NULL)
394 return SFERR_INVALID_PARAM;
395
396 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
397 thisEffect.dwGain = dwGain;
398 return pDIEffect->SetParameters(&thisEffect, DIEP_GAIN);
399 }
400
401
402 // ----------------------------------------------------------------------------
403 // Function: SWFF_SetDirection
404 // Purpose: Sets 2D Angle Direction for the Effect
405 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the direction for
406 // DWORD dwAngle - Direction in 0 to 35999
407 // Returns:
408 // Algorithm:
409 // Comments:
410 //
411 // ----------------------------------------------------------------------------
SWFF_SetDirection(IN LPDIRECTINPUTEFFECT pDIEffect,IN DWORD dwAngle)412 HRESULT SWFF_SetDirection(
413 IN LPDIRECTINPUTEFFECT pDIEffect,
414 IN DWORD dwAngle)
415 {
416 if(pDIEffect == NULL)
417 return SFERR_INVALID_PARAM;
418
419 // set up a DIEFFECT structure so we can change direction
420 LONG rglDirection[2];
421 DIEFFECT thisEffect = {sizeof(DIEFFECT)};
422 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
423 thisEffect.cAxes = 2;
424 thisEffect.rgdwAxes = NULL;
425 thisEffect.rglDirection = rglDirection;
426 thisEffect.rglDirection[0] = dwAngle;
427 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION);
428 }
429
SWFF_SetDirectionGain(IN LPDIRECTINPUTEFFECT pDIEffect,IN DWORD dwAngle,IN DWORD dwGain)430 HRESULT SWFF_SetDirectionGain(
431 IN LPDIRECTINPUTEFFECT pDIEffect,
432 IN DWORD dwAngle,
433 IN DWORD dwGain)
434 {
435 if(pDIEffect == NULL)
436 return SFERR_INVALID_PARAM;
437
438 // set up a DIEFFECT structure so we can change direction
439 LONG rglDirection[2];
440 DIEFFECT thisEffect = {sizeof(DIEFFECT)};
441
442 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
443 thisEffect.cAxes = 2;
444 thisEffect.rgdwAxes = NULL;
445 thisEffect.rglDirection = rglDirection;
446 thisEffect.rglDirection[0] = dwAngle;
447 thisEffect.dwGain = dwGain;
448 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION | DIEP_GAIN);
449 }
450
451 // ----------------------------------------------------------------------------
452 // Function: SWFF_SetDuration
453 // Purpose: Sets Duration for the Effect
454 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to effect to set the duration for
455 // DWORD dwDuration - In uSecs, INFINITE is FOREVER
456 // Returns:
457 // Algorithm:
458 // Comments:
459 //
460 // ----------------------------------------------------------------------------
SWFF_SetDuration(IN LPDIRECTINPUTEFFECT pDIEffect,IN DWORD dwDuration)461 HRESULT SWFF_SetDuration(
462 IN LPDIRECTINPUTEFFECT pDIEffect,
463 IN DWORD dwDuration)
464 {
465 if(pDIEffect == NULL)
466 return SFERR_INVALID_PARAM;
467
468 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
469 thisEffect.dwDuration = dwDuration;
470 return pDIEffect->SetParameters(&thisEffect, DIEP_DURATION);
471 }
472
473
474 // ----------------------------------------------------------------------------
475 // Function: SWFF_PutRawForce
476 // Purpose: Sends Force Value,Direction to ff Device
477 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to a two axis raw force object
478 // LONG lMagnitude - -10000 to +10000 force value
479 // DWORD dwDirection - 0 to 35999
480 // Returns:
481 // Algorithm:
482 // Comments: To use this, you need to create the effect using
483 // SWFF_CreateRawForceEffect() first
484 //
485 // ----------------------------------------------------------------------------
SWFF_PutRawForce(IN LPDIRECTINPUTEFFECT pDIEffect,IN LONG lMagnitude,IN DWORD dwDirection)486 HRESULT SWFF_PutRawForce(
487 IN LPDIRECTINPUTEFFECT pDIEffect,
488 IN LONG lMagnitude,
489 IN DWORD dwDirection)
490 {
491 if(pDIEffect == NULL)
492 return SFERR_INVALID_PARAM;
493
494 DICONSTANTFORCE DIConstantForceStruct;
495 DIConstantForceStruct.lMagnitude = lMagnitude;
496
497 DWORD rgdwAxes[2];
498 rgdwAxes[0] = DIJOFS_X;
499 rgdwAxes[1] = DIJOFS_Y;
500
501 LONG rglDirection[2];
502 rglDirection[0] = dwDirection;
503 rglDirection[1] = 0;
504
505 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
506 thisEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
507 thisEffect.cAxes = 2;
508 thisEffect.rgdwAxes = rgdwAxes;
509 thisEffect.rglDirection = rglDirection;
510
511 thisEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
512 thisEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
513 return pDIEffect->SetParameters(&thisEffect, DIEP_DIRECTION|DIEP_TYPESPECIFICPARAMS);
514 }
515
516 // ----------------------------------------------------------------------------
517 // Function: SWFF_PutRawAxisForce
518 // Purpose: Sends Force Value,Direction to ff Device
519 // Parameters: LPDIRECTINPUTEFFECT pDIEffect - Pointer to a one axis raw force object
520 // LONG lMagnitude - -10000 to +10000 force value
521 // Returns:
522 // Algorithm:
523 // Comments: To use this, you need to create the effect using
524 // SWFF_CreateRawAxisForceEffect() first
525 //
526 // ----------------------------------------------------------------------------
SWFF_PutRawAxisForce(IN LPDIRECTINPUTEFFECT pDIEffect,IN LONG lMagnitude)527 HRESULT SWFF_PutRawAxisForce(
528 IN LPDIRECTINPUTEFFECT pDIEffect,
529 IN LONG lMagnitude)
530 {
531 if(pDIEffect == NULL)
532 return SFERR_INVALID_PARAM;
533
534 DICONSTANTFORCE DIConstantForceStruct;
535 DIConstantForceStruct.lMagnitude = lMagnitude;
536
537 DIEFFECT thisEffect = { sizeof(DIEFFECT) };
538
539 thisEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
540 thisEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
541 return pDIEffect->SetParameters(&thisEffect, DIEP_TYPESPECIFICPARAMS);
542 }
543
544 // ----------------------------------------------------------------------------
545 // Function: SWFF_CreateRawForceEffect
546 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
547 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
548 // LONG lMagnitude - -10000 to 10000
549 // DWORD dwDirection - 0 to 35999
550 //
551 //
552 // Returns:
553 // Algorithm:
554 // Comments: Create this Effect once, then use SetParameter(...) to play the
555 // force value
556 //
557 // ----------------------------------------------------------------------------
558 #if 0
559 HRESULT SWFF_CreateRawForceEffect(
560 IN LPDIRECTINPUTDEVICE2 pDIDevice,
561 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
562 IN LONG lMagnitude,
563 IN DWORD dwDirection)
564 {
565 if(pDIDevice == NULL || ppDIEffect == NULL)
566 return SFERR_INVALID_PARAM;
567 // Always clear return IPtr
568 *ppDIEffect = NULL;
569
570 LPDIRECTINPUTEFFECT pRawForce;
571
572 DICONSTANTFORCE DIConstantForceStruct;
573 DIConstantForceStruct.lMagnitude = lMagnitude;
574
575 DWORD rgdwAxes[2];
576 rgdwAxes[0] = DIJOFS_X;
577 rgdwAxes[1] = DIJOFS_Y;
578
579 LONG rglDirection[2];
580 rglDirection[0] = dwDirection;
581 rglDirection[1] = 0;
582
583 DIEFFECT DIEffect;
584 DIEffect.dwSize = sizeof(DIEFFECT);
585 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
586 DIEffect.dwDuration = INFINITE;
587 DIEffect.dwSamplePeriod = HZ_TO_uS(100);
588 DIEffect.dwGain = 10000;
589 DIEffect.dwTriggerButton = DIEB_NOTRIGGER;
590 DIEffect.dwTriggerRepeatInterval= 0;
591 DIEffect.cAxes = 2;
592 DIEffect.rgdwAxes = rgdwAxes;
593 DIEffect.rglDirection = rglDirection;
594 DIEffect.lpEnvelope = NULL;
595 DIEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
596 DIEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
597
598 HRESULT hRet;
599 hRet = pDIDevice->CreateEffect(GUID_RawForce, &DIEffect, &pRawForce, NULL);
600 if(FAILED(hRet)) return hRet;
601
602 *ppDIEffect = pRawForce;
603 return SUCCESS;
604 }
605 #endif
606
607 // ----------------------------------------------------------------------------
608 // Function: SWFF_CreateRawAxisForceEffect
609 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
610 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
611 // LONG lMagnitude - -10000 to 10000
612 // DWORD dwAxis - Either X_AXIS or Y_AXIS
613 //
614 //
615 // Returns:
616 // Algorithm:
617 // Comments: Create this Effect once, then use SetParameter(...) to play the
618 // force value
619 //
620 // ----------------------------------------------------------------------------
621 #if 0
622 HRESULT SWFF_CreateRawAxisForceEffect(
623 IN LPDIRECTINPUTDEVICE2 pDIDevice,
624 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
625 IN LONG lMagnitude,
626 IN DWORD dwAxis)
627 {
628 if(pDIDevice == NULL || ppDIEffect == NULL)
629 return SFERR_INVALID_PARAM;
630
631 if(!(dwAxis == X_AXIS || dwAxis == Y_AXIS))
632 return SFERR_INVALID_PARAM;
633
634 // Always clear return IPtr
635 *ppDIEffect = NULL;
636
637 LPDIRECTINPUTEFFECT pRawForce;
638
639 DICONSTANTFORCE DIConstantForceStruct;
640 DIConstantForceStruct.lMagnitude = lMagnitude;
641
642 DWORD rgdwAxes[1];
643 if(dwAxis == X_AXIS)
644 rgdwAxes[0] = DIJOFS_X;
645 else
646 rgdwAxes[0] = DIJOFS_Y;
647
648 LONG rglDirection[1];
649 rglDirection[0] = 0;
650
651 DIEFFECT DIEffect;
652 DIEffect.dwSize = sizeof(DIEFFECT);
653 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
654 DIEffect.dwDuration = INFINITE;
655 DIEffect.dwSamplePeriod = HZ_TO_uS(100);
656 DIEffect.dwGain = 10000;
657 DIEffect.dwTriggerButton = DIEB_NOTRIGGER;
658 DIEffect.dwTriggerRepeatInterval= 0;
659 DIEffect.cAxes = 1;
660 DIEffect.rgdwAxes = rgdwAxes;
661 DIEffect.rglDirection = rglDirection;
662 DIEffect.lpEnvelope = NULL;
663 DIEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
664 DIEffect.lpvTypeSpecificParams = &DIConstantForceStruct;
665
666 HRESULT hRet;
667 hRet = pDIDevice->CreateEffect(GUID_RawForce, &DIEffect, &pRawForce, NULL);
668 if(FAILED(hRet)) return hRet;
669
670 *ppDIEffect = pRawForce;
671 return SUCCESS;
672 }
673 #endif
674
675 // ----------------------------------------------------------------------------
676 // Function: SWFF_CreateROMEffect
677 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
678 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
679 // REFGUID refGUID - GUID for ROM Effect
680 // DWORD dwDuration - uS
681 // DWORD dwGain - 1 to 10000
682 // DWORD dwDirection - 0 to 35999
683 // LONG lButton - Index of playback button, -1 for none
684 //
685 // Returns:
686 // Algorithm:
687 // Comments: Assumes valid GUID for the ROM Effect
688 // Note: If unmodified ROM Effect, user has to pass
689 // DEFAULT_ROM_EFFECT_DURATION, DEFAULT_ROM_EFFECT_GAIN
690 // ----------------------------------------------------------------------------
SWFF_CreateROMEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN REFGUID refGUID,IN DWORD dwDuration,IN DWORD dwGain,IN DWORD dwDirection,IN LONG lButton)691 HRESULT SWFF_CreateROMEffect(
692 IN LPDIRECTINPUTDEVICE2 pDIDevice,
693 IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,
694 IN REFGUID refGUID,
695 IN DWORD dwDuration,
696 IN DWORD dwGain,
697 IN DWORD dwDirection,
698 IN LONG lButton)
699 {
700 if(pDIDevice == NULL || ppDIEffect == NULL)
701 return SFERR_INVALID_PARAM;
702 // Always clear return IPtr
703 *ppDIEffect = NULL;
704
705 LPDIRECTINPUTEFFECT pROMEffect = NULL;
706
707 // Default NO Envelope
708 DIENVELOPE DIEnvelopeStruct;
709 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
710 DIEnvelopeStruct.dwAttackTime = 0;
711 DIEnvelopeStruct.dwAttackLevel = 10000;
712 DIEnvelopeStruct.dwFadeTime = 0;
713 DIEnvelopeStruct.dwFadeLevel = 10000;
714
715 // 2DOF
716 DWORD rgdwAxes[2];
717 rgdwAxes[0] = DIJOFS_X;
718 rgdwAxes[1] = DIJOFS_Y;
719
720 LONG rglDirection[2];
721 rglDirection[0] = dwDirection;
722 rglDirection[1] = 0;
723
724 DIEFFECT DIEffect;
725 DIEffect.dwSize = sizeof(DIEFFECT);
726 DIEffect.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
727 // Set Duration and Gain to use Default ROM Effect params unless overridden
728 DIEffect.dwDuration = dwDuration; // can be DEFAULT_ROM_EFFECT_DURATION
729 DIEffect.dwSamplePeriod = DEFAULT_ROM_EFFECT_OUTPUTRATE;
730 DIEffect.dwGain = dwGain; // can be DEFAULT_ROM_EFFECT_GAIN;
731 //
732 DIEffect.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
733 DIEffect.dwTriggerRepeatInterval= 0;
734 DIEffect.cAxes = 2;
735 DIEffect.rgdwAxes = rgdwAxes;
736 DIEffect.rglDirection = rglDirection;
737 DIEffect.lpEnvelope = &DIEnvelopeStruct;
738 DIEffect.cbTypeSpecificParams = 0;
739 DIEffect.lpvTypeSpecificParams = NULL;
740
741 HRESULT hRet = pDIDevice->CreateEffect(refGUID, &DIEffect, &pROMEffect, NULL);
742 if(FAILED(hRet)) return hRet;
743
744 *ppDIEffect = pROMEffect;
745 return SUCCESS;
746 }
747
748 // ----------------------------------------------------------------------------
749 // Function: SWFF_WriteRegString
750 // Parameters: LPCTSTR pszKey - The key under HKCR to place the value
751 // LPCTSTR pszValue - The string value for pszKey
752 //
753 // Returns: TRUE if the registry entry was successfully made
754 // Algorithm:
755 // Comments: Helper function for SWFF_RegisterVFXObject to write registry entries
756 // Note:
757 // ----------------------------------------------------------------------------
SWFF_WriteRegString(IN LPCTSTR pszKey,IN LPCTSTR pszValue)758 BOOL SWFF_WriteRegString(
759 IN LPCTSTR pszKey,
760 IN LPCTSTR pszValue)
761 {
762 HKEY hKey;
763 LONG lRet;
764 int nLen;
765
766 if(pszKey == NULL || pszValue == NULL)
767 return FALSE;
768
769 // create it
770 hKey = HKEY_CLASSES_ROOT;
771 lRet = RegCreateKey(hKey, pszKey, &hKey);
772 if(lRet != ERROR_SUCCESS)
773 return FALSE;
774
775 // save the value into the key
776 nLen = strlen(pszValue);
777 lRet = RegSetValueEx(hKey, NULL, 0, REG_SZ, (PBYTE)pszValue, nLen + 1);
778 if(lRet != ERROR_SUCCESS)
779 {
780 RegCloseKey(hKey);
781 return FALSE;
782 }
783
784 // close the key
785 RegCloseKey(hKey);
786 /* if(lRet != ERROR_SUCCESS) // eh, this is unreachable code
787 return FALSE;*/
788
789 // if we have reached this point, then it was a success
790 return TRUE;
791 }
792
793 // ----------------------------------------------------------------------------
794 // Function: SWFF_RegisterVFXObject
795 // Parameters: LPCTSTR - Pointer to the fully-qualified path name of VFX.DLL
796 //
797 // Returns: TRUE if the object was successfully registered
798 // Algorithm:
799 // Comments: Example of code to register the VFX com object.
800 // You supply lpszVFXPath depending on where you install VFX.DLL
801 // Note:
802 // ----------------------------------------------------------------------------
803 #define GUID_VFX_Object "{04ace0a7-1fa8-11d0-aa22-00a0c911f471}"
SWFF_RegisterVFXObject(IN LPCTSTR pszVFXPath)804 BOOL SWFF_RegisterVFXObject(IN LPCTSTR pszVFXPath)
805 {
806 if(pszVFXPath == NULL)
807 return FALSE;
808
809 return SWFF_WriteRegString("\\VFX1.0", "VFX Object")
810 && SWFF_WriteRegString("\\VFX1.0\\CLSID", GUID_VFX_Object)
811 && SWFF_WriteRegString("\\VFX", "VFX Object")
812 && SWFF_WriteRegString("\\VFX\\CurVer", "VFX1.0")
813 && SWFF_WriteRegString("\\VFX\\CLSID", GUID_VFX_Object)
814 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object, "VFX Object")
815 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\VersionIndependentProgID", "VFX")
816 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\InprocServer32", pszVFXPath)
817 && SWFF_WriteRegString("\\CLSID\\"GUID_VFX_Object"\\NotInsertable", "");
818 }
819
820 // ----------------------------------------------------------------------------
821 // Function: SWFF_CreateVFXEffectFromFile
822 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
823 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
824 // TCHAR *pszFileName - Pointer to VFX File name
825 //
826 // Returns:
827 // Algorithm:
828 // Comments:
829 // Note:
830 // ----------------------------------------------------------------------------
831 #if 0
832 HRESULT SWFF_CreateVFXEffectFromFile(
833 IN LPDIRECTINPUTDEVICE2 pDIDevice,
834 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
835 IN const TCHAR *pszFileName)
836 {
837 if(pDIDevice == NULL || ppDIEffect == NULL || pszFileName == NULL)
838 return SFERR_INVALID_PARAM;
839
840 // Always clear return IPtr
841 *ppDIEffect = NULL;
842
843 LPDIRECTINPUTEFFECT pVFXEffect;
844
845 VFX_PARAM VFXParam;
846 VFXParam.m_Bytes = sizeof(VFX_PARAM);
847 VFXParam.m_PointerType = VFX_FILENAME;
848 VFXParam.m_BufferSize = 0;
849 VFXParam.m_pFileNameOrBuffer = (PVOID) pszFileName;
850
851 DWORD rgdwAxes[2];
852 rgdwAxes[0] = DIJOFS_X;
853 rgdwAxes[1] = DIJOFS_Y;
854
855 LONG rglDirection[2];
856 rglDirection[0] = DEFAULT_VFX_EFFECT_DIRECTION;
857 rglDirection[1] = 0;
858
859 DIEFFECT DIEffectStruct;
860 DIEffectStruct.dwSize = sizeof(DIEFFECT);
861 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
862 DIEffectStruct.dwDuration = DEFAULT_VFX_EFFECT_DURATION;
863 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
864 DIEffectStruct.dwGain = DEFAULT_VFX_EFFECT_GAIN;
865 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
866 DIEffectStruct.dwTriggerRepeatInterval = 0;
867 DIEffectStruct.cAxes = 2;
868 DIEffectStruct.rgdwAxes = rgdwAxes;
869 DIEffectStruct.rglDirection = rglDirection;
870 DIEffectStruct.lpEnvelope = NULL;
871 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
872 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
873
874 HRESULT hResult;
875 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
876 if(FAILED(hResult)) return hResult;
877
878 *ppDIEffect = pVFXEffect;
879 return hResult;
880 }
881 #endif
882
883 // ----------------------------------------------------------------------------
884 // Function: SWFF_CreateVFXEffectFromFileEx
885 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
886 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
887 // TCHAR *pszFileName - Pointer to VFX File
888 // DWORD dwDuration - INFINITE or default
889 // DWORD dwGain - 1 to 10000
890 // DWORD dwDirection - 0 to 35999
891 //
892 // Returns:
893 // Algorithm:
894 // Comments:
895 // Note:
896 // ----------------------------------------------------------------------------
897 #if 0
898 HRESULT SWFF_CreateVFXEffectFromFileEx(
899 IN LPDIRECTINPUTDEVICE2 pDIDevice,
900 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
901 IN const TCHAR *pszFileName,
902 IN DWORD dwDuration,
903 IN DWORD dwGain,
904 IN DWORD dwDirection)
905 {
906 if(pDIDevice == NULL || ppDIEffect == NULL || pszFileName == NULL)
907 return SFERR_INVALID_PARAM;
908 // Always clear return IPtr
909 *ppDIEffect = NULL;
910
911 LPDIRECTINPUTEFFECT pVFXEffect;
912
913 VFX_PARAM VFXParam;
914 VFXParam.m_Bytes = sizeof(VFX_PARAM);
915 VFXParam.m_PointerType = VFX_FILENAME;
916 VFXParam.m_BufferSize = 0;
917 VFXParam.m_pFileNameOrBuffer = (PVOID) pszFileName;
918
919 DWORD rgdwAxes[2];
920 rgdwAxes[0] = DIJOFS_X;
921 rgdwAxes[1] = DIJOFS_Y;
922
923 LONG rglDirection[2];
924 rglDirection[0] = dwDirection;
925 rglDirection[1] = 0;
926
927 DIEFFECT DIEffectStruct;
928 DIEffectStruct.dwSize = sizeof(DIEFFECT);
929 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
930 DIEffectStruct.dwDuration = dwDuration;
931 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
932 DIEffectStruct.dwGain = dwGain;
933 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
934 DIEffectStruct.dwTriggerRepeatInterval = 0;
935 DIEffectStruct.cAxes = 2;
936 DIEffectStruct.rgdwAxes = rgdwAxes;
937 DIEffectStruct.rglDirection = rglDirection;
938 DIEffectStruct.lpEnvelope = NULL;
939 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
940 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
941
942 HRESULT hResult;
943 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
944 if(FAILED(hResult)) return hResult;
945
946 *ppDIEffect = pVFXEffect;
947 return hResult;
948 }
949 #endif
950
951 // ----------------------------------------------------------------------------
952 // Function: SWFF_CreateVFXEffectFromBuffer
953 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
954 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
955 // LPVOID pBuffer - Pointer to VFX Buffer
956 // DWORD dwBufferSize - Buffer size in bytes
957 //
958 // Returns:
959 // Algorithm:
960 // Comments:
961 // Note:
962 // If you are compiling the FRC files as resources in your executable
963 // by putting #include "script.vfx" in your .rc file, you would use
964 // code similar to the following to create the effect (no error checking).
965 //
966 // HRSRC hResInfo = FindResource(NULL, "IDF_FOO", "FORCE");
967 // DWORD dwBytes = SizeofResource(NULL, hResInfo);
968 // HGLOBAL hRsrc = LoadResource(NULL, hResInfo);
969 // PVOID pBuffer = LockResource(hRsrc);
970 // SWFF_CreateEffectFromVFXBuffer(pDIDevice, pBuffer, dwBytes, &pDIEffect);
971 //
972 // ----------------------------------------------------------------------------
973 #if 0
974 HRESULT SWFF_CreateVFXEffectFromBuffer(
975 IN LPDIRECTINPUTDEVICE2 pDIDevice,
976 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
977 IN const LPVOID pBuffer,
978 IN DWORD dwBufferSize)
979 {
980 if(pDIDevice == NULL || ppDIEffect == NULL || pBuffer == NULL)
981 return SFERR_INVALID_PARAM;
982
983 // Always clear return IPtr
984 *ppDIEffect = NULL;
985
986 LPDIRECTINPUTEFFECT pVFXEffect;
987
988 VFX_PARAM VFXParam;
989 VFXParam.m_Bytes = sizeof(VFX_PARAM);
990 VFXParam.m_PointerType = VFX_BUFFER;
991 VFXParam.m_BufferSize = dwBufferSize;
992 VFXParam.m_pFileNameOrBuffer = pBuffer;
993
994 DWORD rgdwAxes[2];
995 rgdwAxes[0] = DIJOFS_X;
996 rgdwAxes[1] = DIJOFS_Y;
997
998 LONG rglDirection[2];
999 rglDirection[0] = DEFAULT_VFX_EFFECT_DIRECTION;
1000 rglDirection[1] = 0;
1001
1002 DIEFFECT DIEffectStruct;
1003 DIEffectStruct.dwSize = sizeof(DIEFFECT);
1004 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1005 DIEffectStruct.dwDuration = DEFAULT_VFX_EFFECT_DURATION;
1006 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1007 DIEffectStruct.dwGain = DEFAULT_VFX_EFFECT_GAIN;
1008 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
1009 DIEffectStruct.dwTriggerRepeatInterval = 0;
1010 DIEffectStruct.cAxes = 2;
1011 DIEffectStruct.rgdwAxes = rgdwAxes;
1012 DIEffectStruct.rglDirection = rglDirection;
1013 DIEffectStruct.lpEnvelope = NULL;
1014 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
1015 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
1016
1017 HRESULT hResult;
1018 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
1019 if(FAILED(hResult)) return hResult;
1020
1021 *ppDIEffect = pVFXEffect;
1022 return hResult;
1023 }
1024 #endif
1025
1026 // ----------------------------------------------------------------------------
1027 // Function: SWFF_CreateVFXEffectFromBufferEx
1028 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1029 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1030 // LPVOID pBuffer - Pointer to VFX Buffer
1031 // DWORD dwBufferSize - Buffer size in bytes
1032 // DWORD dwDuration - INFINITE or default
1033 // DWORD dwGain - 1 to 10000
1034 // DWORD dwDirection - 0 to 35999
1035 //
1036 // Returns:
1037 // Algorithm:
1038 // Comments:
1039 // Note:
1040 // See note for SWFF_CreateVFXEffectFromBuffer(...)
1041 // ----------------------------------------------------------------------------
1042 #if 0
1043 HRESULT SWFF_CreateVFXEffectFromBufferEx(
1044 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1045 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1046 IN const LPVOID pBuffer,
1047 IN DWORD dwBufferSize,
1048 IN DWORD dwDuration,
1049 IN DWORD dwGain,
1050 IN DWORD dwDirection)
1051 {
1052 if(pDIDevice == NULL || ppDIEffect == NULL || pBuffer == NULL)
1053 return SFERR_INVALID_PARAM;
1054 // Always clear return IPtr
1055 *ppDIEffect = NULL;
1056
1057 LPDIRECTINPUTEFFECT pVFXEffect;
1058
1059 VFX_PARAM VFXParam;
1060 VFXParam.m_Bytes = sizeof(VFX_PARAM);
1061 VFXParam.m_PointerType = VFX_BUFFER;
1062 VFXParam.m_BufferSize = dwBufferSize;
1063 VFXParam.m_pFileNameOrBuffer = pBuffer;
1064
1065 DWORD rgdwAxes[2];
1066 rgdwAxes[0] = DIJOFS_X;
1067 rgdwAxes[1] = DIJOFS_Y;
1068
1069 LONG rglDirection[2];
1070 rglDirection[0] = dwDirection;
1071 rglDirection[1] = 0;
1072
1073 DIEFFECT DIEffectStruct;
1074 DIEffectStruct.dwSize = sizeof(DIEFFECT);
1075 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1076 DIEffectStruct.dwDuration = dwDuration;
1077 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1078 DIEffectStruct.dwGain = dwGain;
1079 DIEffectStruct.dwTriggerButton = DIEB_NOTRIGGER;
1080 DIEffectStruct.dwTriggerRepeatInterval = 0;
1081 DIEffectStruct.cAxes = 2;
1082 DIEffectStruct.rgdwAxes = rgdwAxes;
1083 DIEffectStruct.rglDirection = rglDirection;
1084 DIEffectStruct.lpEnvelope = NULL;
1085 DIEffectStruct.cbTypeSpecificParams = sizeof(VFX_PARAM);
1086 DIEffectStruct.lpvTypeSpecificParams = &VFXParam;
1087
1088 HRESULT hResult;
1089 hResult = pDIDevice->CreateEffect(GUID_VFXEffect, &DIEffectStruct, &pVFXEffect, NULL);
1090 if(FAILED(hResult)) return hResult;
1091
1092 *ppDIEffect = pVFXEffect;
1093 return hResult;
1094 }
1095 #endif
1096
1097 // ----------------------------------------------------------------------------
1098 // Function: SWFF_CreateDIEffectFromFile
1099 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1100 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1101 // TCHAR *pszFileName - Pointer to VFX File name
1102 //
1103 // Returns:
1104 // Algorithm:
1105 // Comments:
1106 // Note: If the file contains multiple effects or a custom effect this
1107 // function will fail. Use SWFF_CreateDIEffectFromFileEx.
1108 // ----------------------------------------------------------------------------
1109 #if 0
1110 HRESULT SWFF_CreateDIEffectFromFile(
1111 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1112 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1113 IN const TCHAR *pszFileName)
1114 {
1115 HRESULT hResult;
1116 PVFX pIVFX;
1117
1118 if(pDIDevice == NULL || pszFileName == NULL || ppDIEffect == NULL)
1119 return SFERR_INVALID_PARAM;
1120
1121 *ppDIEffect = NULL;
1122
1123 hResult = CoInitialize(NULL);
1124 if(FAILED(hResult))
1125 return hResult;
1126
1127 hResult = CoCreateInstance(CLSID_VFX,
1128 NULL,
1129 CLSCTX_INPROC_SERVER,
1130 IID_IVFX,
1131 (void**)&pIVFX);
1132 if(pIVFX == NULL)
1133 {
1134 CoUninitialize();
1135 return SFERR_SYSTEM_INIT;
1136 }
1137
1138 if(FAILED(hResult))
1139 {
1140 CoUninitialize();
1141 return hResult;
1142 }
1143
1144 // Create the Effect from a *.frc file
1145 DWORD dwInFlags = VFXCE_CREATE_SINGLE;
1146 hResult = pIVFX->CreateEffectFromFile(pDIDevice, ppDIEffect,
1147 0, pszFileName, NULL, NULL, dwInFlags, NULL);
1148
1149 // clean up
1150 pIVFX->Release();
1151 CoUninitialize();
1152
1153 if(FAILED(hResult)) return hResult;
1154
1155 return hResult;
1156 }
1157 #endif
1158
1159 // ----------------------------------------------------------------------------
1160 // Function: SWFF_CreateDIEffectFromFileEx
1161 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1162 // LPDIRECTINPUTEFFECT** pppDIEffect - Pointer to an array of
1163 // LPDIRECTINPUTEFFECT's.
1164 // This array is allocated
1165 // by the function. Caller is
1166 // responsible for deleting.
1167 // PDWORD pdwEffectCount - Gets the number of effects in array
1168 // TCHAR *pszFileName - Pointer to VFX File name
1169 // PPVOID ppUDBuffer - Gets an array containing custom force
1170 // samples. This array is allocated by
1171 // the function. Caller is
1172 // responsible for deleting.
1173 // PDWORD pdwOutFlags - Receives 0 if the file contains
1174 // a single effect. Otherwise
1175 // it receives VFXCE_CONCATENATE
1176 // or VFXCE_SUPERIMPOSE.
1177 //
1178 // Returns:
1179 // Algorithm:
1180 // Comments:
1181 // Note: call delete [] pppDIEffect and delete [] ppUDBuffer after
1182 // releasing the effects
1183 // ----------------------------------------------------------------------------
1184 #if 0
1185 HRESULT SWFF_CreateDIEffectFromFileEx(
1186 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1187 IN OUT LPDIRECTINPUTEFFECT** pppDIEffect,
1188 IN OUT PDWORD pdwEffectCount,
1189 IN const TCHAR *pszFileName,
1190 IN OUT void** ppUDBuffer,
1191 IN OUT PDWORD pdwOutFlags)
1192 {
1193 // parameter check
1194 if(pDIDevice == NULL || pszFileName == NULL || pppDIEffect == NULL ||
1195 pdwEffectCount == NULL || ppUDBuffer == NULL || pdwOutFlags == NULL)
1196 {
1197 return SFERR_INVALID_PARAM;
1198 }
1199
1200 // zero out the return values
1201 *pppDIEffect = NULL;
1202 *pdwEffectCount = 0;
1203 *ppUDBuffer = NULL;
1204 *pdwOutFlags = 0;
1205
1206 HRESULT hResult;
1207 PVFX pIVFX;
1208
1209 hResult = CoInitialize(NULL);
1210 if(FAILED(hResult))
1211 return hResult;
1212
1213 hResult = CoCreateInstance(CLSID_VFX,
1214 NULL,
1215 CLSCTX_INPROC_SERVER,
1216 IID_IVFX,
1217 (void**)&pIVFX);
1218 if(pIVFX == NULL)
1219 {
1220 CoUninitialize();
1221 return SFERR_SYSTEM_INIT;
1222 }
1223
1224 if(FAILED(hResult))
1225 {
1226 CoUninitialize();
1227 return hResult;
1228 }
1229
1230 // see how big a DIEffect array we have to allocate, and see how much memory, if any,
1231 // we need to allocate for UD sample caching
1232 DWORD dwInFlags = VFXCE_CALC_BUFFER_SIZE | VFXCE_CALC_EFFECT_COUNT;
1233 DWORD dwEffectCount;
1234 DWORD dwBufferSize;
1235 hResult = pIVFX->CreateEffectFromFile(NULL, NULL,
1236 &dwEffectCount, pszFileName, NULL, &dwBufferSize, dwInFlags, NULL);
1237 if(FAILED(hResult))
1238 {
1239 pIVFX->Release();
1240 CoUninitialize();
1241 return hResult;
1242 }
1243
1244 // allocate memory for the effects
1245 LPDIRECTINPUTEFFECT* ppDIEffect = new LPDIRECTINPUTEFFECT[dwEffectCount];
1246 if(ppDIEffect == NULL)
1247 {
1248 pIVFX->Release();
1249 CoUninitialize();
1250 return DIERR_OUTOFMEMORY;
1251 }
1252
1253 // allocate memory for the custom force samples
1254 PVOID pUDBuffer = NULL;
1255 if(dwBufferSize > 0)
1256 {
1257 pUDBuffer = new BYTE[dwBufferSize];
1258 if(pUDBuffer == NULL)
1259 {
1260 delete [] ppDIEffect;
1261 ppDIEffect = NULL;
1262 pIVFX->Release();
1263 CoUninitialize();
1264 return DIERR_OUTOFMEMORY;
1265 }
1266 }
1267
1268 // Create the Effect from a *.frc file
1269 DWORD dwOutFlags;
1270 dwInFlags = VFXCE_CREATE_MULTIPLE;
1271 hResult = pIVFX->CreateEffectFromFile(pDIDevice, ppDIEffect,
1272 &dwEffectCount, pszFileName, pUDBuffer, &dwBufferSize, dwInFlags, &dwOutFlags);
1273
1274 if(FAILED(hResult))
1275 {
1276 delete [] ppDIEffect;
1277 ppDIEffect = NULL;
1278 delete [] pUDBuffer;
1279 pUDBuffer = NULL;
1280 pIVFX->Release();
1281 CoUninitialize();
1282 return hResult;
1283 }
1284
1285 // clean up
1286 pIVFX->Release();
1287 CoUninitialize();
1288
1289 if(FAILED(hResult)) return hResult;
1290
1291 // assign the results
1292 *pppDIEffect = ppDIEffect;
1293 *pdwEffectCount = dwEffectCount;
1294 *ppUDBuffer = pUDBuffer;
1295 *pdwOutFlags = dwOutFlags;
1296
1297 return hResult;
1298 }
1299 #endif
1300
1301 // ----------------------------------------------------------------------------
1302 // Function: SWFF_CreateDIEffectFromBuffer
1303 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1304 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1305 // LPVOID pBuffer - Pointer to VFX Buffer
1306 // DWORD dwBufferSize - Buffer size in bytes
1307 //
1308 // Returns:
1309 // Algorithm:
1310 // Comments:
1311 // Note: If the file contains multiple effects or a custom effect this
1312 // function will fail. Use SWFF_CreateDIEffectFromBufferEx.
1313 // ----------------------------------------------------------------------------
1314 #if 0
1315 HRESULT SWFF_CreateDIEffectFromBuffer(
1316 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1317 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1318 IN const LPVOID pBuffer,
1319 IN DWORD dwBufferSize)
1320 {
1321 HRESULT hResult;
1322 PVFX pIVFX;
1323
1324 if(pDIDevice == NULL || pBuffer == NULL || ppDIEffect == NULL)
1325 return SFERR_INVALID_PARAM;
1326
1327 *ppDIEffect = NULL;
1328
1329 hResult = CoInitialize(NULL);
1330 if(FAILED(hResult))
1331 return hResult;
1332
1333 hResult = CoCreateInstance(CLSID_VFX,
1334 NULL,
1335 CLSCTX_INPROC_SERVER,
1336 IID_IVFX,
1337 (void**)&pIVFX);
1338 if(pIVFX == NULL)
1339 {
1340 CoUninitialize();
1341 return SFERR_SYSTEM_INIT;
1342 }
1343
1344 if(FAILED(hResult))
1345 {
1346 CoUninitialize();
1347 return hResult;
1348 }
1349
1350 // Create the Effect from a *.frc file
1351 DWORD dwInFlags = VFXCE_CREATE_SINGLE;
1352 hResult = pIVFX->CreateEffectFromBuffer(pDIDevice, ppDIEffect,
1353 0, pBuffer, dwBufferSize, NULL, NULL, dwInFlags, NULL);
1354
1355 // clean up
1356 pIVFX->Release();
1357 CoUninitialize();
1358
1359 if(FAILED(hResult)) return hResult;
1360
1361 return hResult;
1362 }
1363 #endif
1364
1365 // ----------------------------------------------------------------------------
1366 // Function: SWFF_CreateDIEffectFromBufferEx
1367 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - Pointer to DirectInputDevice
1368 // LPDIRECTINPUTEFFECT** pppDIEffect - Pointer to an array of
1369 // LPDIRECTINPUTEFFECT's.
1370 // This array is allocated
1371 // by the function. Caller is
1372 // responsible for deleting.
1373 // PDWORD pdwEffectCount - Gets the number of effects in array
1374 // LPVOID pBuffer - Pointer to VFX Buffer
1375 // DWORD dwBufferSize - Buffer size in bytes
1376 // PPVOID ppUDBuffer - Gets an array containing custom force
1377 // samples. This array is allocated by
1378 // the function. Caller is
1379 // responsible for deleting.
1380 // PDWORD pdwOutFlags - Receives 0 if the file contains
1381 // a single effect. Otherwise
1382 // it receives VFXCE_CONCATENATE
1383 // or VFXCE_SUPERIMPOSE.
1384 //
1385 // Returns:
1386 // Algorithm:
1387 // Comments:
1388 // Note: call delete [] pppDIEffect and delete [] ppUDBuffer after
1389 // releasing the effects
1390 // ----------------------------------------------------------------------------
1391 #if 0
1392 HRESULT SWFF_CreateDIEffectFromBufferEx(
1393 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1394 IN OUT LPDIRECTINPUTEFFECT** pppDIEffect,
1395 IN OUT PDWORD pdwEffectCount,
1396 IN const LPVOID pBuffer,
1397 IN DWORD dwBufferSize,
1398 IN OUT void** ppUDBuffer,
1399 IN OUT PDWORD pdwOutFlags)
1400 {
1401 // parameter check
1402 if(pDIDevice == NULL || pBuffer == NULL || pppDIEffect == NULL||
1403 pdwEffectCount == NULL || ppUDBuffer == NULL || pdwOutFlags == NULL)
1404 {
1405 return SFERR_INVALID_PARAM;
1406 }
1407
1408 // zero out the return values
1409 *pppDIEffect = NULL;
1410 *pdwEffectCount = 0;
1411 *ppUDBuffer = NULL;
1412 *pdwOutFlags = 0;
1413
1414 HRESULT hResult;
1415 PVFX pIVFX;
1416
1417
1418
1419 hResult = CoInitialize(NULL);
1420 if(FAILED(hResult))
1421 return hResult;
1422
1423 hResult = CoCreateInstance(CLSID_VFX,
1424 NULL,
1425 CLSCTX_INPROC_SERVER,
1426 IID_IVFX,
1427 (void**)&pIVFX);
1428 if(pIVFX == NULL)
1429 {
1430 CoUninitialize();
1431 return SFERR_SYSTEM_INIT;
1432 }
1433
1434 if(FAILED(hResult))
1435 {
1436 CoUninitialize();
1437 return hResult;
1438 }
1439
1440 // see how big a DIEffect array we have to allocate, and see how much memory, if any,
1441 // we need to allocate for UD sample caching
1442 DWORD dwInFlags = VFXCE_CALC_BUFFER_SIZE | VFXCE_CALC_EFFECT_COUNT;
1443 DWORD dwEffectCount;
1444 DWORD dwUDBufferSize;
1445 hResult = pIVFX->CreateEffectFromBuffer(NULL, NULL,
1446 &dwEffectCount, pBuffer, dwBufferSize, NULL, &dwUDBufferSize, dwInFlags, NULL);
1447 if(FAILED(hResult))
1448 {
1449 pIVFX->Release();
1450 CoUninitialize();
1451 return hResult;
1452 }
1453
1454 // allocate memory for the effects
1455 LPDIRECTINPUTEFFECT* ppDIEffect = new LPDIRECTINPUTEFFECT[dwEffectCount];
1456 if(ppDIEffect == NULL)
1457 {
1458 pIVFX->Release();
1459 CoUninitialize();
1460 return DIERR_OUTOFMEMORY;
1461 }
1462
1463 // allocate memory for the custom force samples
1464 PVOID pUDBuffer = NULL;
1465 if(dwUDBufferSize > 0)
1466 {
1467 pUDBuffer = new BYTE[dwUDBufferSize];
1468 if(pUDBuffer == NULL)
1469 {
1470 delete [] ppDIEffect;
1471 ppDIEffect = NULL;
1472 pIVFX->Release();
1473 CoUninitialize();
1474 return DIERR_OUTOFMEMORY;
1475 }
1476 }
1477
1478 // Create the Effect from a *.frc file
1479 DWORD dwOutFlags;
1480 dwInFlags = VFXCE_CREATE_MULTIPLE;
1481 hResult = pIVFX->CreateEffectFromBuffer(pDIDevice, ppDIEffect,
1482 &dwEffectCount, pBuffer, dwBufferSize, pUDBuffer, &dwUDBufferSize, dwInFlags, &dwOutFlags);
1483
1484 if(FAILED(hResult))
1485 {
1486 delete [] ppDIEffect;
1487 ppDIEffect = NULL;
1488 delete [] pUDBuffer;
1489 pUDBuffer = NULL;
1490 pIVFX->Release();
1491 CoUninitialize();
1492 return hResult;
1493 }
1494
1495 // clean up
1496 pIVFX->Release();
1497 CoUninitialize();
1498
1499 if(FAILED(hResult)) return hResult;
1500
1501 // assign the results
1502 *pppDIEffect = ppDIEffect;
1503 *pdwEffectCount = dwEffectCount;
1504 *ppUDBuffer = pUDBuffer;
1505 *pdwOutFlags = dwOutFlags;
1506
1507 return hResult;
1508 }
1509 #endif
1510
1511 // ----------------------------------------------------------------------------
1512 // Function: SWFF_CreatePeriodicEffect
1513 // Purpose: Creates a Periodic type Effect with specified params
1514 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1515 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1516 // DWORD dwType - Type of PERIODIC Effect (SINE | COSINE | ...)
1517 // DWORD dwDuration - uS
1518 // DWORD dwPeriod - uS
1519 // DWORD dwDirection - 0 to 35999
1520 // DWORD dwMagnitude - 0 to 10000
1521 // LONG lOffset - Offset in -10000 to 10000
1522 // DWORD dwAttackTime - Envelope Attack Time in uS
1523 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
1524 // DWORD dwFadeTime - Envelope Fade time in uS
1525 // DWORD dwFadeLevel - Envelope Fade Level
1526 // LONG lButton - Index of playback button, -1 for none
1527 //
1528 // Returns:
1529 // Algorithm:
1530 // Comments:
1531 //
1532 // ----------------------------------------------------------------------------
SWFF_CreatePeriodicEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwType,IN DWORD dwDuration,IN DWORD dwPeriod,IN DWORD dwDirection,IN DWORD dwMagnitude,IN LONG lOffset,IN DWORD dwAttackTime,IN DWORD dwAttackLevel,IN DWORD dwFadeTime,IN DWORD dwFadeLevel,IN LONG lButton)1533 HRESULT SWFF_CreatePeriodicEffect( IN LPDIRECTINPUTDEVICE2 pDIDevice,
1534 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1535 IN DWORD dwType,
1536 IN DWORD dwDuration,
1537 IN DWORD dwPeriod,
1538 IN DWORD dwDirection,
1539 IN DWORD dwMagnitude,
1540 IN LONG lOffset,
1541 IN DWORD dwAttackTime,
1542 IN DWORD dwAttackLevel,
1543 IN DWORD dwFadeTime,
1544 IN DWORD dwFadeLevel,
1545 IN LONG lButton)
1546 {
1547 if(pDIDevice == NULL || ppDIEffect == NULL)
1548 return SFERR_INVALID_PARAM;
1549 // Always clear return IPtr
1550 *ppDIEffect = NULL;
1551
1552 // type-specific stuff
1553 DWORD dwPhase = 0;
1554 GUID guid;
1555 switch(dwType)
1556 {
1557 case SINE:
1558 guid = GUID_Sine;
1559 break;
1560 case COSINE:
1561 guid = GUID_Sine;
1562 dwPhase = 9000;
1563 break;
1564 case SQUARE_HIGH:
1565 guid = GUID_Square;
1566 break;
1567 case SQUARE_LOW:
1568 guid = GUID_Square;
1569 dwPhase = 18000;
1570 break;
1571 case TRIANGLE_UP:
1572 guid = GUID_Triangle;
1573 break;
1574 case TRIANGLE_DOWN:
1575 guid = GUID_Triangle;
1576 dwPhase = 18000;
1577 break;
1578 case SAWTOOTH_UP:
1579 guid = GUID_SawtoothUp;
1580 break;
1581 case SAWTOOTH_DOWN:
1582 guid = GUID_SawtoothDown;
1583 break;
1584 default:
1585 // illegal
1586 break;
1587 }
1588
1589 DIPERIODIC DIPeriodicStruct;
1590 DIPeriodicStruct.dwMagnitude = dwMagnitude;
1591 DIPeriodicStruct.lOffset = lOffset;
1592 DIPeriodicStruct.dwPhase = dwPhase;
1593 DIPeriodicStruct.dwPeriod = dwPeriod;
1594
1595 DIENVELOPE DIEnvelopeStruct;
1596 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
1597 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
1598 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
1599 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
1600 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
1601
1602 DWORD rgdwAxes[2];
1603 rgdwAxes[0] = DIJOFS_X;
1604 rgdwAxes[1] = DIJOFS_Y;
1605
1606 LONG rglDirection[2];
1607 rglDirection[0] = dwDirection;
1608 rglDirection[1] = 0;
1609
1610 DIEFFECT DIEffectStruct;
1611 DIEffectStruct.dwSize = sizeof(DIEFFECT);
1612 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
1613 DIEffectStruct.dwDuration = dwDuration;
1614 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1615 DIEffectStruct.dwGain = 10000;
1616 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
1617 DIEffectStruct.dwTriggerRepeatInterval = 0;
1618 DIEffectStruct.cAxes = 2;
1619 DIEffectStruct.rgdwAxes = rgdwAxes;
1620 DIEffectStruct.rglDirection = rglDirection;
1621 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
1622 DIEffectStruct.cbTypeSpecificParams = sizeof(DIPeriodicStruct);
1623 DIEffectStruct.lpvTypeSpecificParams = &DIPeriodicStruct;
1624
1625 HRESULT hResult;
1626 hResult = pDIDevice->CreateEffect(guid, &DIEffectStruct, ppDIEffect, NULL);
1627
1628 return hResult;
1629 }
1630
1631 // ----------------------------------------------------------------------------
1632 // Function: SWFF_CreateSpringEffect
1633 // Purpose: Creates a Spring type Effect with specified params
1634 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1635 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1636 // DWORD dwDuration - Duration in uS
1637 // LONG lKx - X-Axis K Coefficient in -10000 to 10000
1638 // LONG lCenterx - X-Axis Center in -10000 to 10000
1639 // LONG lKy - Y-Axis K Coefficient in -10000 to 10000
1640 // LONG lCentery - Y-Axis Center in -10000 to 10000
1641 // LONG lButton - Index of playback button, -1 for none
1642 //
1643 // Returns:
1644 // Algorithm:
1645 // Comments:
1646 // To create a 1D spring, set the lKx or lKy parameter to 0
1647 // To create a 2D spring, set both lKx and lKy parameter to non-zero
1648 // or set both lFx and lFy to zero
1649 //
1650 // ----------------------------------------------------------------------------
SWFF_CreateSpringEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN LONG lKx,IN LONG lCenterx,IN LONG lKy,IN LONG lCentery,IN LONG lButton)1651 HRESULT SWFF_CreateSpringEffect( IN LPDIRECTINPUTDEVICE2 pDIDevice,
1652 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1653 IN DWORD dwDuration,
1654 IN LONG lKx,
1655 IN LONG lCenterx,
1656 IN LONG lKy,
1657 IN LONG lCentery,
1658 IN LONG lButton)
1659 {
1660 if(pDIDevice == NULL || ppDIEffect == NULL)
1661 return SFERR_INVALID_PARAM;
1662
1663 // Always clear return IPtr
1664 *ppDIEffect = NULL;
1665
1666 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1667 ppDIEffect,
1668 SPRING,
1669 dwDuration,
1670 lKx, lCenterx,
1671 lKy, lCentery,
1672 lButton);
1673
1674 return hResult;
1675 }
1676
1677 // ----------------------------------------------------------------------------
1678 // Function: SWFF_CreateDamperEffect
1679 // Purpose: Creates a Damper type Effect with specified params
1680 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1681 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1682 // DWORD dwDuration - Duration in uS
1683 // LONG lBx - X-Axis B Coefficient +/-10000
1684 // LONG lV0x - X-Axis Initial Velocity +/-10000
1685 // LONG lBy - Y-Axis B Coefficient +/-10000
1686 // LONG lV0y - Y-Axis Initial Velocity +/-10000
1687 // LONG lButton - Index of playback button, -1 for none
1688 // Returns:
1689 // Algorithm:
1690 // Comments:
1691 // To create a 1D Damper, set the lBx or lBy parameter to 0
1692 // To create a 2D Damper, set both lBx and lBy parameter to non-zero
1693 // or set both lFx and lFy to zero
1694 //
1695 // ----------------------------------------------------------------------------
SWFF_CreateDamperEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN LONG lBx,IN LONG lV0x,IN LONG lBy,IN LONG lV0y,IN LONG lButton)1696 HRESULT SWFF_CreateDamperEffect(
1697 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1698 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1699 IN DWORD dwDuration,
1700 IN LONG lBx,
1701 IN LONG lV0x,
1702 IN LONG lBy,
1703 IN LONG lV0y,
1704 IN LONG lButton)
1705 {
1706 if(pDIDevice == NULL || ppDIEffect == NULL)
1707 return SFERR_INVALID_PARAM;
1708
1709 // Always clear return IPtr
1710 *ppDIEffect = NULL;
1711
1712 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1713 ppDIEffect,
1714 DAMPER,
1715 dwDuration,
1716 lBx, lV0x,
1717 lBy, lV0y,
1718 lButton);
1719
1720 return hResult;
1721 }
1722
1723
1724 // ----------------------------------------------------------------------------
1725 // Function: SWFF_CreateInertiaEffect
1726 // Purpose: Creates an Inertia type Effect with specified params
1727 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1728 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1729 // DWORD dwDuration - Duration in uS
1730 // LONG lMx - X-Axis M Coefficient +/-10000
1731 // LONG lA0x - X-Axis Initial Acceleration +/-10000
1732 // LONG lMy - Y-Axis N Coefficient +/-10000
1733 // LONG lA0y - Y-Axis Initial Acceleration +/-10000
1734 // LONG lButton - Index of playback button, -1 for none
1735 // Returns:
1736 // Algorithm:
1737 // Comments:
1738 // To create a 1D Inertia, set the lMx or lMy parameter to 0
1739 // To create a 2D Inertia, set both lMx and lMy parameter to non-zero
1740 // or set both lFx and lFy to zero
1741 //
1742 // ----------------------------------------------------------------------------
SWFF_CreateInertiaEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN LONG lMx,IN LONG lA0x,IN LONG lMy,IN LONG lA0y,IN LONG lButton)1743 HRESULT SWFF_CreateInertiaEffect(
1744 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1745 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1746 IN DWORD dwDuration,
1747 IN LONG lMx,
1748 IN LONG lA0x,
1749 IN LONG lMy,
1750 IN LONG lA0y,
1751 IN LONG lButton)
1752 {
1753 if(pDIDevice == NULL || ppDIEffect == NULL)
1754 return SFERR_INVALID_PARAM;
1755
1756 // Always clear return IPtr
1757 *ppDIEffect = NULL;
1758
1759 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1760 ppDIEffect,
1761 INERTIA,
1762 dwDuration,
1763 lMx, lA0x,
1764 lMy, lA0y,
1765 lButton);
1766
1767 return hResult;
1768 }
1769
1770 // ----------------------------------------------------------------------------
1771 // Function: SWFF_CreateFrictionEffect
1772 // Purpose: Creates a Friction type Effect with specified params
1773 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1774 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1775 // DWORD dwDuration - Duration in uS
1776 // LONG lFx - X-Axis F Coefficient +/-10000
1777 // LONG lFy - Y-Axis F Coefficient +/-10000
1778 // LONG lButton - Index of playback button, -1 for none
1779 // Returns:
1780 // Algorithm:
1781 // Comments:
1782 // To create a 1D Friction, set the lFx or lFy parameter to 0
1783 // To create a 2D Friction, set both lFx and lFy parameter to non-zero
1784 // or set both lFx and lFy to zero
1785 //
1786 // ----------------------------------------------------------------------------
SWFF_CreateFrictionEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN LONG lFx,IN LONG lFy,IN LONG lButton)1787 HRESULT SWFF_CreateFrictionEffect(
1788 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1789 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1790 IN DWORD dwDuration,
1791 IN LONG lFx,
1792 IN LONG lFy,
1793 IN LONG lButton)
1794 {
1795 if(pDIDevice == NULL || ppDIEffect == NULL)
1796 return SFERR_INVALID_PARAM;
1797
1798 // Always clear return IPtr
1799 *ppDIEffect = NULL;
1800
1801 HRESULT hResult = SWFF_CreateConditionEffect(pDIDevice,
1802 ppDIEffect,
1803 FRICTION,
1804 dwDuration,
1805 lFx, 0,
1806 lFy, 0,
1807 lButton);
1808
1809 return hResult;
1810 }
1811
SWFF_CreateConditionEffectStruct(di_condition_effect_struct * ptr,IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwType,IN DWORD dwDuration,IN LONG lXCoefficient,IN LONG lXOffset,IN LONG lYCoefficient,IN LONG lYOffset,IN LONG lButton)1812 HRESULT SWFF_CreateConditionEffectStruct(
1813 di_condition_effect_struct *ptr,
1814 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1815 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1816 IN DWORD dwType,
1817 IN DWORD dwDuration,
1818 IN LONG lXCoefficient,
1819 IN LONG lXOffset,
1820 IN LONG lYCoefficient,
1821 IN LONG lYOffset,
1822 IN LONG lButton)
1823 {
1824 if(pDIDevice == NULL || ppDIEffect == NULL)
1825 return SFERR_INVALID_PARAM;
1826
1827 // Always clear return IPtr
1828 *ppDIEffect = NULL;
1829
1830 GUID guid;
1831 switch(dwType)
1832 {
1833 case SPRING:
1834 guid = GUID_Spring;
1835 break;
1836 case INERTIA:
1837 guid = GUID_Inertia;
1838 break;
1839 case DAMPER:
1840 guid = GUID_Damper;
1841 break;
1842 case FRICTION:
1843 guid = GUID_Friction;
1844 break;
1845 default:
1846 break;
1847 }
1848
1849 ptr->DIConditionStruct[0].lOffset = lXOffset;
1850 ptr->DIConditionStruct[0].lPositiveCoefficient = lXCoefficient;
1851 ptr->DIConditionStruct[0].lNegativeCoefficient = lXCoefficient;
1852 ptr->DIConditionStruct[0].dwPositiveSaturation = 10000;
1853 ptr->DIConditionStruct[0].dwNegativeSaturation = 10000;
1854 ptr->DIConditionStruct[0].lDeadBand = 0;
1855 ptr->DIConditionStruct[1].lOffset = lYOffset;
1856 ptr->DIConditionStruct[1].lPositiveCoefficient = lYCoefficient;
1857 ptr->DIConditionStruct[1].lNegativeCoefficient = lYCoefficient;
1858 ptr->DIConditionStruct[1].dwPositiveSaturation = 10000;
1859 ptr->DIConditionStruct[1].dwNegativeSaturation = 10000;
1860 ptr->DIConditionStruct[1].lDeadBand = 0;
1861
1862 DWORD rgdwAxes[2];
1863 int nAxisCount = 0;
1864 if(lXCoefficient != 0)
1865 {
1866 rgdwAxes[nAxisCount] = DIJOFS_X;
1867 nAxisCount++;
1868 }
1869
1870 if(lYCoefficient != 0)
1871 {
1872 rgdwAxes[nAxisCount] = DIJOFS_Y;
1873 nAxisCount++;
1874 }
1875
1876 if(lXCoefficient == 0 && lYCoefficient == 0)
1877 {
1878 nAxisCount = 2;
1879 rgdwAxes[0] = DIJOFS_X;
1880 rgdwAxes[1] = DIJOFS_Y;
1881 }
1882
1883 DWORD cbTypeSpecificParams;
1884 PVOID pvTypeSpecificParams;
1885
1886 if (nAxisCount == 1) {
1887 cbTypeSpecificParams = sizeof(DICONDITION[1]);
1888 if (lXCoefficient)
1889 pvTypeSpecificParams = &ptr->DIConditionStruct[0];
1890 else
1891 pvTypeSpecificParams = &ptr->DIConditionStruct[1];
1892
1893 } else {
1894 cbTypeSpecificParams = sizeof(DICONDITION[2]);
1895 pvTypeSpecificParams = &ptr->DIConditionStruct[0];
1896 }
1897
1898 ptr->rglDirection[0] = 0;
1899 ptr->rglDirection[1] = 0;
1900
1901 ptr->DIEffectStruct.dwSize = sizeof(DIEFFECT);
1902 ptr->DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
1903 ptr->DIEffectStruct.dwDuration = dwDuration;
1904 ptr->DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
1905 ptr->DIEffectStruct.dwGain = 10000;
1906 ptr->DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
1907 ptr->DIEffectStruct.dwTriggerRepeatInterval = 0;
1908 ptr->DIEffectStruct.cAxes = nAxisCount;
1909 ptr->DIEffectStruct.rgdwAxes = rgdwAxes;
1910 ptr->DIEffectStruct.rglDirection = ptr->rglDirection;
1911 ptr->DIEffectStruct.lpEnvelope = NULL;
1912 ptr->DIEffectStruct.cbTypeSpecificParams = cbTypeSpecificParams;
1913 ptr->DIEffectStruct.lpvTypeSpecificParams = pvTypeSpecificParams;
1914
1915 HRESULT hResult;
1916 hResult = pDIDevice->CreateEffect(guid, &ptr->DIEffectStruct, ppDIEffect, NULL);
1917
1918 return hResult;
1919 }
1920
1921 // ----------------------------------------------------------------------------
1922 // Function: SWFF_CreateConditionEffect
1923 // Purpose: Creates a Condition type Effect with specified params
1924 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
1925 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
1926 // DWORD dwType - SPRING | INERTIA | DAMPER | FRICTION
1927 // DWORD dwDuration - Duration in uS
1928 // LONG lXCoefficient - Coefficient in -10000 to 10000
1929 // LONG lXOffset - Offset in -10000 to 10000
1930 // LONG lYCoefficient - Coefficient in -10000 to 10000
1931 // LONG lYOffset - Offset in -10000 to 10000
1932 // LONG lButton - Index of playback button, -1 for none
1933 // Returns:
1934 // Algorithm:
1935 // Comments:
1936 // To create a 1D Friction, set the lFx or lFy parameter to 0
1937 // To create a 2D Friction, set both lFx and lFy parameter to non-zero
1938 // or set both lFx and lFy to zero
1939 //
1940 // ----------------------------------------------------------------------------
SWFF_CreateConditionEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwType,IN DWORD dwDuration,IN LONG lXCoefficient,IN LONG lXOffset,IN LONG lYCoefficient,IN LONG lYOffset,IN LONG lButton)1941 HRESULT SWFF_CreateConditionEffect(
1942 IN LPDIRECTINPUTDEVICE2 pDIDevice,
1943 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
1944 IN DWORD dwType,
1945 IN DWORD dwDuration,
1946 IN LONG lXCoefficient,
1947 IN LONG lXOffset,
1948 IN LONG lYCoefficient,
1949 IN LONG lYOffset,
1950 IN LONG lButton)
1951 {
1952 if(pDIDevice == NULL || ppDIEffect == NULL)
1953 return SFERR_INVALID_PARAM;
1954
1955 // Always clear return IPtr
1956 *ppDIEffect = NULL;
1957
1958 GUID guid;
1959 switch(dwType)
1960 {
1961 case SPRING:
1962 guid = GUID_Spring;
1963 break;
1964 case INERTIA:
1965 guid = GUID_Inertia;
1966 break;
1967 case DAMPER:
1968 guid = GUID_Damper;
1969 break;
1970 case FRICTION:
1971 guid = GUID_Friction;
1972 break;
1973 default:
1974 break;
1975 }
1976
1977 DICONDITION DIConditionStruct[2];
1978 DIConditionStruct[0].lOffset = lXOffset;
1979 DIConditionStruct[0].lPositiveCoefficient = lXCoefficient;
1980 DIConditionStruct[0].lNegativeCoefficient = lXCoefficient;
1981 DIConditionStruct[0].dwPositiveSaturation = 10000;
1982 DIConditionStruct[0].dwNegativeSaturation = 10000;
1983 DIConditionStruct[0].lDeadBand = 0;
1984 DIConditionStruct[1].lOffset = lYOffset;
1985 DIConditionStruct[1].lPositiveCoefficient = lYCoefficient;
1986 DIConditionStruct[1].lNegativeCoefficient = lYCoefficient;
1987 DIConditionStruct[1].dwPositiveSaturation = 10000;
1988 DIConditionStruct[1].dwNegativeSaturation = 10000;
1989 DIConditionStruct[1].lDeadBand = 0;
1990
1991 DWORD rgdwAxes[2];
1992 int nAxisCount = 0;
1993 if(lXCoefficient != 0)
1994 {
1995 rgdwAxes[nAxisCount] = DIJOFS_X;
1996 nAxisCount++;
1997 }
1998 if(lYCoefficient != 0)
1999 {
2000 rgdwAxes[nAxisCount] = DIJOFS_Y;
2001 nAxisCount++;
2002 }
2003 if(lXCoefficient == 0 && lYCoefficient == 0)
2004 {
2005 nAxisCount = 2;
2006 rgdwAxes[0] = DIJOFS_X;
2007 rgdwAxes[1] = DIJOFS_Y;
2008 }
2009
2010 DWORD cbTypeSpecificParams;
2011 PVOID pvTypeSpecificParams;
2012 if(nAxisCount == 1)
2013 {
2014 cbTypeSpecificParams = sizeof(DICONDITION[1]);
2015 if(lXCoefficient != 0)
2016 pvTypeSpecificParams = &DIConditionStruct[0];
2017 else
2018 pvTypeSpecificParams = &DIConditionStruct[1];
2019 }
2020 else
2021 {
2022 cbTypeSpecificParams = sizeof(DICONDITION[2]);
2023 pvTypeSpecificParams = &DIConditionStruct[0];
2024 }
2025
2026 LONG rglDirection[2];
2027 rglDirection[0] = 0;
2028 rglDirection[1] = 0;
2029
2030 DIEFFECT DIEffectStruct;
2031 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2032 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_CARTESIAN;
2033 DIEffectStruct.dwDuration = dwDuration;
2034 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2035 DIEffectStruct.dwGain = 10000;
2036 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2037 DIEffectStruct.dwTriggerRepeatInterval = 0;
2038 DIEffectStruct.cAxes = nAxisCount;
2039 DIEffectStruct.rgdwAxes = rgdwAxes;
2040 DIEffectStruct.rglDirection = rglDirection;
2041 DIEffectStruct.lpEnvelope = NULL;
2042 DIEffectStruct.cbTypeSpecificParams = cbTypeSpecificParams;
2043 DIEffectStruct.lpvTypeSpecificParams = pvTypeSpecificParams;
2044
2045 HRESULT hResult;
2046 hResult = pDIDevice->CreateEffect(guid, &DIEffectStruct, ppDIEffect, NULL);
2047
2048 return hResult;
2049 }
2050
2051 // ----------------------------------------------------------------------------
2052 // Function: SWFF_CreateRampEffect
2053 // Purpose: Creates a Ramp type Effect with specified params
2054 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2055 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2056 // DWORD dwDuration - uS
2057 // DWORD dwDirection - 0 to 35999
2058 // LONG lStart - -10000 to 10000
2059 // LONG lEnd - -10000 to 10000
2060 // DWORD dwAttackTime - Envelope Attack Time in uS
2061 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
2062 // DWORD dwFadeTime - Envelope Fade time in uS
2063 // DWORD dwFadeLevel - Envelope Fade Level
2064 // LONG lButton - Index of playback button, -1 for none
2065 // Returns:
2066 // Algorithm:
2067 // Comments:
2068 //
2069 // ----------------------------------------------------------------------------
SWFF_CreateRampEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN DWORD dwDirection,IN LONG lStart,IN LONG lEnd,IN DWORD dwAttackTime,IN DWORD dwAttackLevel,IN DWORD dwFadeTime,IN DWORD dwFadeLevel,IN LONG lButton)2070 HRESULT SWFF_CreateRampEffect(
2071 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2072 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2073 IN DWORD dwDuration,
2074 IN DWORD dwDirection,
2075 IN LONG lStart,
2076 IN LONG lEnd,
2077 IN DWORD dwAttackTime,
2078 IN DWORD dwAttackLevel,
2079 IN DWORD dwFadeTime,
2080 IN DWORD dwFadeLevel,
2081 IN LONG lButton)
2082 {
2083 if(pDIDevice == NULL || ppDIEffect == NULL)
2084 return SFERR_INVALID_PARAM;
2085
2086 // Always clear return IPtr
2087 *ppDIEffect = NULL;
2088
2089 DIRAMPFORCE DIRampStruct;
2090 DIRampStruct.lStart = lStart;
2091 DIRampStruct.lEnd = lEnd;
2092
2093 DIENVELOPE DIEnvelopeStruct;
2094 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
2095 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
2096 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
2097 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
2098 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
2099
2100 DWORD rgdwAxes[2];
2101 rgdwAxes[0] = DIJOFS_X;
2102 rgdwAxes[1] = DIJOFS_Y;
2103
2104 LONG rglDirection[2];
2105 rglDirection[0] = dwDirection;
2106 rglDirection[1] = 0;
2107
2108 DIEFFECT DIEffectStruct;
2109 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2110 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2111 DIEffectStruct.dwDuration = dwDuration;
2112 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2113 DIEffectStruct.dwGain = 10000;
2114 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2115 DIEffectStruct.dwTriggerRepeatInterval = 0;
2116 DIEffectStruct.cAxes = 2;
2117 DIEffectStruct.rgdwAxes = rgdwAxes;
2118 DIEffectStruct.rglDirection = rglDirection;
2119 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
2120 DIEffectStruct.cbTypeSpecificParams = sizeof(DIRampStruct);
2121 DIEffectStruct.lpvTypeSpecificParams = &DIRampStruct;
2122
2123 HRESULT hResult;
2124 hResult = pDIDevice->CreateEffect(GUID_RampForce, &DIEffectStruct, ppDIEffect, NULL);
2125
2126 return hResult;
2127 }
2128
2129 // ----------------------------------------------------------------------------
2130 // Function: SWFF_CreateConstantForceEffect
2131 // Purpose: Creates a ConstantForce type Effect with specified params
2132 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2133 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2134 // DWORD dwDuration - in uS
2135 // DWORD dwDirection - in 0 to 35999
2136 // LONG lMagnitude - in -10000 to 10000
2137 // DWORD dwAttackTime - Envelope Attack Time in uS
2138 // DWORD dwAttackLevel - Envelope Attack Level in 0 to 10000
2139 // DWORD dwFadeTime - Envelope Fade time in uS
2140 // DWORD dwFadeLevel - Envelope Fade Level
2141 // LONG lButton - Index of playback button, -1 for none
2142 // Returns:
2143 // Algorithm:
2144 // Comments:
2145 //
2146 // ----------------------------------------------------------------------------
SWFF_CreateConstantForceEffect(IN LPDIRECTINPUTDEVICE2 pDIDevice,IN OUT LPDIRECTINPUTEFFECT * ppDIEffect,IN DWORD dwDuration,IN DWORD dwDirection,IN LONG lMagnitude,IN DWORD dwAttackTime,IN DWORD dwAttackLevel,IN DWORD dwFadeTime,IN DWORD dwFadeLevel,IN LONG lButton)2147 HRESULT SWFF_CreateConstantForceEffect(
2148 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2149 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2150 IN DWORD dwDuration,
2151 IN DWORD dwDirection,
2152 IN LONG lMagnitude,
2153 IN DWORD dwAttackTime,
2154 IN DWORD dwAttackLevel,
2155 IN DWORD dwFadeTime,
2156 IN DWORD dwFadeLevel,
2157 IN LONG lButton)
2158 {
2159 if(pDIDevice == NULL || ppDIEffect == NULL)
2160 return SFERR_INVALID_PARAM;
2161
2162 // Always clear return IPtr
2163 *ppDIEffect = NULL;
2164
2165 DICONSTANTFORCE DIConstantForceStruct;
2166 DIConstantForceStruct.lMagnitude = lMagnitude;
2167
2168 DIENVELOPE DIEnvelopeStruct;
2169 DIEnvelopeStruct.dwSize = sizeof(DIENVELOPE);
2170 DIEnvelopeStruct.dwAttackTime = dwAttackTime;
2171 DIEnvelopeStruct.dwAttackLevel = dwAttackLevel;
2172 DIEnvelopeStruct.dwFadeTime = dwFadeTime;
2173 DIEnvelopeStruct.dwFadeLevel = dwFadeLevel;
2174
2175 DWORD rgdwAxes[2];
2176 rgdwAxes[0] = DIJOFS_X;
2177 rgdwAxes[1] = DIJOFS_Y;
2178
2179 LONG rglDirection[2];
2180 rglDirection[0] = dwDirection;
2181 rglDirection[1] = 0;
2182
2183 DIEFFECT DIEffectStruct;
2184 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2185 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2186 DIEffectStruct.dwDuration = dwDuration;
2187 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2188 DIEffectStruct.dwGain = 10000;
2189 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2190 DIEffectStruct.dwTriggerRepeatInterval = 0;
2191 DIEffectStruct.cAxes = 2;
2192 DIEffectStruct.rgdwAxes = rgdwAxes;
2193 DIEffectStruct.rglDirection = rglDirection;
2194 DIEffectStruct.lpEnvelope = &DIEnvelopeStruct;
2195 DIEffectStruct.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
2196 DIEffectStruct.lpvTypeSpecificParams = &DIConstantForceStruct;
2197
2198 HRESULT hResult;
2199 hResult = pDIDevice->CreateEffect(GUID_ConstantForce, &DIEffectStruct, ppDIEffect, NULL);
2200
2201 return hResult;
2202 }
2203
2204
2205 // ----------------------------------------------------------------------------
2206 // Function: SWFF_CreateWallEffect
2207 // Purpose: Creates a Wall Effect
2208 // Parameters: LPDIRECTINPUTDEVICE2 pDIDevice - IDIRECTINPUTDEVICE2 interface
2209 // LPDIRECTINPUTEFFECT* ppDIEffect - Receives pointer to created effect
2210 // DWORD dwDuration - in uS
2211 // DWORD dwDirection - 0 | 9000 | 18000 | 27000
2212 // DWORD dwDistance - Distance from centerin 0 to 10000
2213 // BOOL bInner - T/F = Inner/Outer
2214 // LONG lCoefficient - Wall Constant in 0 to 10000
2215 // LONG lButton - Index of playback button, -1 for none
2216 // Returns:
2217 // Algorithm:
2218 // Comments:
2219 //
2220 // ----------------------------------------------------------------------------
2221 #if 0
2222 HRESULT SWFF_CreateWallEffect(
2223 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2224 IN OUT LPDIRECTINPUTEFFECT* ppDIEffect,
2225 IN DWORD dwDuration,
2226 IN DWORD dwDirection,
2227 IN DWORD dwDistance,
2228 IN BOOL bInner,
2229 IN LONG lWallCoefficient,
2230 IN LONG lButton)
2231 {
2232 if(pDIDevice == NULL || ppDIEffect == NULL)
2233 return SFERR_INVALID_PARAM;
2234
2235 // Always clear return IPtr
2236 *ppDIEffect = NULL;
2237
2238 BE_WALL_PARAM WallStruct;
2239 WallStruct.m_Bytes = sizeof(WallStruct);
2240 WallStruct.m_WallType = bInner ? WALL_INNER : WALL_OUTER;
2241 WallStruct.m_WallConstant = lWallCoefficient;
2242 WallStruct.m_WallAngle = dwDirection;
2243 WallStruct.m_WallDistance = dwDistance;
2244
2245
2246 DWORD rgdwAxes[2];
2247 rgdwAxes[0] = DIJOFS_X;
2248 rgdwAxes[1] = DIJOFS_Y;
2249
2250 LONG rglDirection[2];
2251 rglDirection[0] = 0;
2252 rglDirection[1] = 0;
2253
2254 DIEFFECT DIEffectStruct;
2255 DIEffectStruct.dwSize = sizeof(DIEFFECT);
2256 DIEffectStruct.dwFlags = DIEFF_OBJECTOFFSETS | DIEFF_POLAR;
2257 DIEffectStruct.dwDuration = dwDuration;
2258 DIEffectStruct.dwSamplePeriod = HZ_TO_uS(100);
2259 DIEffectStruct.dwGain = 10000;
2260 DIEffectStruct.dwTriggerButton = lButton == -1 ? DIEB_NOTRIGGER : FIELD_OFFSET(DIJOYSTATE, rgbButtons) + lButton;
2261 DIEffectStruct.dwTriggerRepeatInterval = 0;
2262 DIEffectStruct.cAxes = 2;
2263 DIEffectStruct.rgdwAxes = rgdwAxes;
2264 DIEffectStruct.rglDirection = rglDirection;
2265 DIEffectStruct.lpEnvelope = NULL;
2266 DIEffectStruct.cbTypeSpecificParams = sizeof(WallStruct);
2267 DIEffectStruct.lpvTypeSpecificParams = &WallStruct;
2268
2269 HRESULT hResult;
2270 hResult = pDIDevice->CreateEffect(GUID_Wall, &DIEffectStruct, ppDIEffect, NULL);
2271
2272 return hResult;
2273 }
2274 #endif
2275
2276
2277 // ----------------------------------------------------------------------------
2278 // FUNCTION: SWFF_GetJoyData
2279 // PURPOSE: Retrieves Joystick data
2280 // PARAMETERS: int nJoyID - JOYSTICKID1-16
2281 // JOYINFOEX *pjix - PTR to a JOYYINFOEX structure
2282 // char *pszErr - Ptr to Error code string
2283 // RETURNS: JOYINFOEX filled in
2284 //
2285 // The axis and buttons info:
2286 // All axis are in the range 0 to 65535.
2287 // jix.dwXpos - X position.
2288 // jix.dwYpos - Y position.
2289 // jix.dwZpos - Throttle slider control
2290 // jix.dwRpos - Z Rotation position.
2291 //
2292 // To see if button 1 is pressed:
2293 // (jix.dwButtons & JOY_BUTTON1) ? PRESSED : NOT_PRESSED;
2294 // likewise for the other buttons JOY_BUTTON2, JOY_BUTTON3 �
2295 // JOY_BUTTON8
2296 //
2297 // Hat Switch (POV) is in jix.dwPOV
2298 // The range is 0 to 35900 and the value is -1 if the
2299 // Hat Switch is not pressed.
2300 //
2301 // TRUE if successful, else FALSE
2302 // COMMENTS:
2303 // ----------------------------------------------------------------------------
SWFF_GetJoyData(int nJoyID,JOYINFOEX * pjix,char * pszErr)2304 BOOL SWFF_GetJoyData(int nJoyID, JOYINFOEX * pjix, char *pszErr)
2305 {
2306 if(pjix == NULL || pszErr == NULL)
2307 return FALSE;
2308
2309 memset(pjix, 0x00, sizeof(JOYINFOEX)); // for good measure
2310 pjix->dwSize = sizeof(JOYINFOEX);
2311
2312 // NOTE: With SideWinder Digital OverDrive, it takes no more time to return all
2313 // information from the joystick than it does to just get
2314 // the button states or axis.
2315 //
2316 pjix->dwFlags = JOY_RETURNALL;
2317
2318
2319 // joyGetPoxEx will fill in the joyinfoex struct with all the
2320 // joystick information
2321 //
2322
2323 switch(joyGetPosEx(nJoyID, pjix))
2324 {
2325 case JOYERR_NOERROR: // no problem
2326 strcpy(pszErr,"SUCCESS");
2327 break;
2328
2329 case MMSYSERR_NODRIVER:
2330 strcpy(pszErr,"The joystick driver is not present.");
2331 return FALSE;
2332
2333 case MMSYSERR_INVALPARAM:
2334 strcpy(pszErr,"An invalid parameter was passed.");
2335 return FALSE;
2336
2337 case MMSYSERR_BADDEVICEID:
2338 strcpy(pszErr,"The specified joystick identifier is invalid.");
2339 return FALSE;
2340
2341 case JOYERR_UNPLUGGED:
2342 strcpy(pszErr,"Your joystick is unplugged.");
2343 return FALSE;
2344
2345 default:
2346 strcpy(pszErr,"Unknown joystick error.");
2347 return FALSE;
2348
2349 } // end of switch
2350 return TRUE;
2351 } // GetJoyData()
2352
2353
2354 // ----------------------------------------------------------------------------
2355 // FUNCTION: SWFF_GetJoyData2
2356 // PURPOSE: Retrieves Joystick data using DInput calls
2357 // PARAMETERS: LPDIRECTINPUTDEVICE2 pDIDevice - Pointer to DirectInputDevice
2358 // LPDIJOYSTATE pjs - PTR to a DIJOYSTATE structure
2359 // RETURNS: DIJOYSTATE filled in
2360 //
2361 // The axis info:
2362 // all axes have range from 0 to 65535
2363 // pjs->lX - X position
2364 // pjs->lY - Y position
2365 // pjs->lZ - Throttle position
2366 //
2367 // To see if button 0 is pressed:
2368 // (pjs->rgbButtons[0] & 0x80) ? PRESSED : NOT_PRESSED;
2369 // likewise for the other buttons pjs->rgbButtons[1],
2370 // pjs->rgbButtons[2]
2371 //
2372 // Hat Switch (POV) is in pjs->rgdwPov[0]
2373 // The range is 0 to 35999 and the value is -1 if the
2374 // Hat Switch is not pressed.
2375 //
2376 // COMMENTS:
2377 // ----------------------------------------------------------------------------
2378 /*HRESULT SWFF_GetJoyData2(
2379 IN LPDIRECTINPUTDEVICE2 pDIDevice,
2380 IN OUT LPDIJOYSTATE pjs)
2381 {
2382 HRESULT hResult;
2383
2384 if(pDIDevice == NULL || pjs == NULL)
2385 return SFERR_INVALID_PARAM;
2386
2387 memset(pjs, 0x00, sizeof(DIJOYSTATE)); // for good measure
2388
2389 // NOTE: With SideWinder Digital OverDrive, it takes no more time to return all
2390 // information from the joystick than it does to just get
2391 // the button states or axis.
2392 //
2393
2394 // must poll before using GetDeviceState(...)
2395 hResult = pDIDevice->Poll();
2396 if(FAILED(hResult))
2397 return hResult;
2398
2399 // retrieve the values cached during Poll()
2400 hResult = pDIDevice->GetDeviceState(sizeof(DIJOYSTATE), pjs);
2401
2402 return hResult;
2403 } // GetJoyData2()
2404 */
2405
2406 // ----------------------------------------------------------------------------
2407 // Function: SWFF_ErrorCodeToString
2408 // Parameters: HRESULT hResult - Error Code
2409 // TCHAR * pszString - Ptr to string to fill with code
2410 // Returns:
2411 // Algorithm:
2412 // Comments:
2413 //
2414 // ----------------------------------------------------------------------------
SWFF_ErrorCodeToString(HRESULT hResult,TCHAR * pszCodeString)2415 void SWFF_ErrorCodeToString(HRESULT hResult, TCHAR * pszCodeString)
2416 {
2417 if(pszCodeString == NULL)
2418 return;
2419
2420 //XSTR:OFF
2421
2422 switch(hResult)
2423 {
2424 case S_FALSE: strcpy(pszCodeString, "S_FALSE"); break;
2425 case DI_POLLEDDEVICE: strcpy(pszCodeString, "DI_POLLEDDEVICE"); break;
2426 // case DI_DOWNLOADSKIPPED: strcpy(pszCodeString, "DI_DOWNLOADSKIPPED"); break;
2427 // case DI_EFFECTRESTARTED: strcpy(pszCodeString, "DI_EFFECTRESTARTED"); break;
2428 case DIERR_OLDDIRECTINPUTVERSION: strcpy(pszCodeString, "DIERR_OLDDIRECTINPUTVERSION" ); break;
2429 case DIERR_BETADIRECTINPUTVERSION: strcpy(pszCodeString, "DIERR_BETADIRECTINPUTVERSION" ); break;
2430 case DIERR_BADDRIVERVER: strcpy(pszCodeString, "DIERR_BADDRIVERVER" ); break;
2431 case DIERR_DEVICENOTREG: strcpy(pszCodeString, "DIERR_DEVICENOTREG" ); break;
2432 case DIERR_NOTFOUND: strcpy(pszCodeString, "DIERR_NOTFOUND" ); break;
2433 case DIERR_INVALIDPARAM: strcpy(pszCodeString, "DIERR_INVALIDPARAM" ); break;
2434 case DIERR_NOINTERFACE: strcpy(pszCodeString, "DIERR_NOINTERFACE" ); break;
2435 case DIERR_GENERIC: strcpy(pszCodeString, "DIERR_GENERIC" ); break;
2436 case DIERR_OUTOFMEMORY: strcpy(pszCodeString, "DIERR_OUTOFMEMORY" ); break;
2437 case DIERR_UNSUPPORTED: strcpy(pszCodeString, "DIERR_UNSUPPORTED" ); break;
2438 case DIERR_NOTINITIALIZED: strcpy(pszCodeString, "DIERR_NOTINITIALIZED" ); break;
2439 case DIERR_ALREADYINITIALIZED: strcpy(pszCodeString, "DIERR_ALREADYINITIALIZED" ); break;
2440 case DIERR_NOAGGREGATION: strcpy(pszCodeString, "DIERR_NOAGGREGATION" ); break;
2441 case DIERR_INPUTLOST: strcpy(pszCodeString, "DIERR_INPUTLOST" ); break;
2442 case DIERR_ACQUIRED: strcpy(pszCodeString, "DIERR_ACQUIRED" ); break;
2443 case DIERR_NOTACQUIRED: strcpy(pszCodeString, "DIERR_NOTACQUIRED" ); break;
2444 case E_ACCESSDENIED: strcpy(pszCodeString, "E_ACCESSDENIED: DIERR_OTHERAPPHASPRIO, DIERR_READONLY, DIERR_HANDLEEXISTS"); break;
2445 case E_PENDING: strcpy(pszCodeString, "E_PENDING" ); break;
2446 case DIERR_INSUFFICIENTPRIVS: strcpy(pszCodeString, "DIERR_INSUFFICIENTPRIVS" ); break;
2447 case DIERR_DEVICEFULL: strcpy(pszCodeString, "DIERR_DEVICEFULL" ); break;
2448 case DIERR_MOREDATA: strcpy(pszCodeString, "DIERR_MOREDATA" ); break;
2449 case DIERR_NOTDOWNLOADED: strcpy(pszCodeString, "DIERR_NOTDOWNLOADED" ); break;
2450 case DIERR_HASEFFECTS: strcpy(pszCodeString, "DIERR_HASEFFECTS" ); break;
2451 case DIERR_NOTEXCLUSIVEACQUIRED: strcpy(pszCodeString, "DIERR_NOTEXCLUSIVEACQUIRED"); break;
2452 case DIERR_INCOMPLETEEFFECT: strcpy(pszCodeString, "DIERR_INCOMPLETEEFFECT" ); break;
2453 case DIERR_NOTBUFFERED: strcpy(pszCodeString, "DIERR_NOTBUFFERED" ); break;
2454 case DIERR_EFFECTPLAYING: strcpy(pszCodeString, "DIERR_EFFECTPLAYING"); break;
2455 case SFERR_INVALID_OBJECT: strcpy(pszCodeString, "SFERR_INVALID_OBJECT" ); break;
2456 case SFERR_END_OF_LIST: strcpy(pszCodeString, "SFERR_END_OF_LIST" ); break;
2457 case SFERR_DEVICE_NACK: strcpy(pszCodeString, "SFERR_DEVICE_NACK" ); break;
2458 case SFERR_RAW_OUT_DATAEVENT_CREATION: strcpy(pszCodeString, "SFERR_RAW_OUT_DATAEVENT_CREATION" ); break;
2459 case SFERR_RAW_OUT_THREAD_CREATION: strcpy(pszCodeString, "SFERR_RAW_OUT_THREAD_CREATION" ); break;
2460 case SFERR_SYSTEM_INIT: strcpy(pszCodeString, "SFERR_SYSTEM_INIT" ); break;
2461 case SFERR_DRIVER_ERROR: strcpy(pszCodeString, "SFERR_DRIVER_ERROR" ); break;
2462 case SFERR_NON_FF_DEVICE: strcpy(pszCodeString, "SFERR_NON_FF_DEVICE" ); break;
2463 case SFERR_INVALID_HAL_OBJECT: strcpy(pszCodeString, "SFERR_INVALID_HAL_OBJECT" ); break;
2464 // case VFX_ERR_FILE_NOT_FOUND: strcpy(pszCodeString, "VFX_ERR_FILE_NOT_FOUND" ); break;
2465 // case VFX_ERR_FILE_CANNOT_OPEN: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_OPEN" ); break;
2466 // case VFX_ERR_FILE_CANNOT_CLOSE: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_CLOSE" ); break;
2467 // case VFX_ERR_FILE_CANNOT_READ: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_READ" ); break;
2468 // case VFX_ERR_FILE_CANNOT_WRITE: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_WRITE" ); break;
2469 // case VFX_ERR_FILE_CANNOT_SEEK: strcpy(pszCodeString, "VFX_ERR_FILE_CANNOT_SEEK" ); break;
2470 case VFX_ERR_FILE_UNKNOWN_ERROR: strcpy(pszCodeString, "VFX_ERR_FILE_UNKNOWN_ERROR" ); break;
2471 case VFX_ERR_FILE_BAD_FORMAT: strcpy(pszCodeString, "VFX_ERR_FILE_BAD_FORMAT" ); break;
2472 // case VFX_ERR_FILE_ACCESS_DENIED: strcpy(pszCodeString, "VFX_ERR_FILE_ACCESS_DENIED" ); break;
2473 // case VFX_ERR_FILE_SHARING_VIOLATION: strcpy(pszCodeString, "VFX_ERR_FILE_SHARING_VIOLATION" ); break;
2474 // case VFX_ERR_FILE_NETWORK_ERROR: strcpy(pszCodeString, "VFX_ERR_FILE_NETWORK_ERROR" ); break;
2475 // case VFX_ERR_FILE_TOO_MANY_OPEN_FILES: strcpy(pszCodeString, "VFX_ERR_FILE_TOO_MANY_OPEN_FILES" ); break;
2476 // case VFX_ERR_FILE_INVALID: strcpy(pszCodeString, "VFX_ERR_FILE_INVALID" ); break;
2477 case VFX_ERR_FILE_END_OF_FILE: strcpy(pszCodeString, "VFX_ERR_FILE_END_OF_FILE" ); break;
2478 case SWDEV_ERR_INVALID_ID : strcpy(pszCodeString, "SWDEV_ERR_INVALID_ID" ); break;
2479 case SWDEV_ERR_INVALID_PARAM : strcpy(pszCodeString, "SWDEV_ERR_INVALID_PARAM" ); break;
2480 case SWDEV_ERR_CHECKSUM : strcpy(pszCodeString, "SWDEV_ERR_CHECKSUM" ); break;
2481 case SWDEV_ERR_TYPE_FULL : strcpy(pszCodeString, "SWDEV_ERR_TYPE_FULL" ); break;
2482 case SWDEV_ERR_UNKNOWN_CMD : strcpy(pszCodeString, "SWDEV_ERR_UNKNOWN_CMD" ); break;
2483 case SWDEV_ERR_PLAYLIST_FULL : strcpy(pszCodeString, "SWDEV_ERR_PLAYLIST_FULL" ); break;
2484 case SWDEV_ERR_PROCESSLIST_FULL : strcpy(pszCodeString, "SWDEV_ERR_PROCESSLIST_FULL" ); break;
2485 default: sprintf(pszCodeString, "%x", hResult); break;
2486 }
2487
2488 //XSTR:ON
2489
2490 }
2491