comparison src/haptic/win32/SDL_syshaptic.c @ 2617:a168397d6549 gsoc2008_force_feedback

Finished implementing the haptic<->joystick functions.
author Edgar Simo <bobbens@gmail.com>
date Wed, 06 Aug 2008 09:06:41 +0000
parents 088907e9a2bb
children fb71df34124f
comparison
equal deleted inserted replaced
2616:acd5da848404 2617:a168397d6549
25 25
26 #include "SDL_haptic.h" 26 #include "SDL_haptic.h"
27 #include "../SDL_syshaptic.h" 27 #include "../SDL_syshaptic.h"
28 #include "SDL_joystick.h" 28 #include "SDL_joystick.h"
29 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ 29 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
30 /*#include "../../joystick/win32/SDL_sysjoystick_c.h"*/ /* For joystick hwdata */ 30 #include "../../joystick/win32/SDL_dxjoystick_c.h" /* For joystick hwdata */
31 31
32 #define WIN32_LEAN_AND_MEAN 32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h> 33 #include <windows.h>
34 34
35 #define DIRECTINPUT_VERSION 0x0700 /* Need at least DirectX 7 for dwStartDelay */ 35 #define DIRECTINPUT_VERSION 0x0700 /* Need at least DirectX 7 for dwStartDelay */
65 * Haptic system hardware data. 65 * Haptic system hardware data.
66 */ 66 */
67 struct haptic_hwdata 67 struct haptic_hwdata
68 { 68 {
69 LPDIRECTINPUTDEVICE2 device; 69 LPDIRECTINPUTDEVICE2 device;
70 DWORD axes[3]; 70 DWORD axes[3]; /* Axes to use. */
71 int is_joystick; /* Device is loaded as joystick. */
71 }; 72 };
72 73
73 74
74 /* 75 /*
75 * Haptic system effect data. 76 * Haptic system effect data.
107 DI_SetError(const char *str, HRESULT err) 108 DI_SetError(const char *str, HRESULT err)
108 { 109 {
109 SDL_SetError( "Haptic: %s - %s: %s", str, 110 SDL_SetError( "Haptic: %s - %s: %s", str,
110 DXGetErrorString(err), 111 DXGetErrorString(err),
111 DXGetErrorDescription(err)); 112 DXGetErrorDescription(err));
113 }
114
115
116 /*
117 * Checks to see if two GUID are the same.
118 */
119 static int
120 DI_GUIDIsSame(GUID * a, GUID * b)
121 {
122 if (((a)->Data1 == (b)->Data1) &&
123 ((a)->Data2 == (b)->Data2) &&
124 ((a)->Data3 == (b)->Data3) &&
125 (SDL_strcmp((a)->Data4, (b)->Data4)==0))
126 return 1;
127 return 0;
112 } 128 }
113 129
114 130
115 /* 131 /*
116 * Initializes the haptic subsystem. 132 * Initializes the haptic subsystem.
217 233
218 234
219 /* 235 /*
220 * Callback to get all supported effects. 236 * Callback to get all supported effects.
221 */ 237 */
222 #define EFFECT_TEST(e,s) \ 238 #define EFFECT_TEST(e,s) \
223 if ((pei->guid.Data1 == e.Data1) && \ 239 if (DI_GUIDIsSame(&pei->guid, &(e))) \
224 (pei->guid.Data2 == e.Data2) && \
225 (pei->guid.Data3 == e.Data3) && \
226 (SDL_strcmp(pei->guid.Data4,e.Data4)==0)) \
227 haptic->supported |= (s) 240 haptic->supported |= (s)
228 static BOOL CALLBACK 241 static BOOL CALLBACK
229 DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) 242 DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
230 { 243 {
231 /* Prepare the haptic device. */ 244 /* Prepare the haptic device. */
278 * 291 *
279 * Steps: 292 * Steps:
280 * - Open temporary DirectInputDevice interface. 293 * - Open temporary DirectInputDevice interface.
281 * - Create DirectInputDevice2 interface. 294 * - Create DirectInputDevice2 interface.
282 * - Release DirectInputDevice interface. 295 * - Release DirectInputDevice interface.
283 * - Set cooperative level. 296 * - Call SDL_SYS_HapticOpenFromDevice2
284 * - Set data format.
285 * - Acquire exclusiveness.
286 * - Reset actuators.
287 * - Get supported featuers.
288 */ 297 */
289 static int 298 static int
290 SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) 299 SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
291 { 300 {
292 HRESULT ret; 301 HRESULT ret;
302 int ret2;
293 LPDIRECTINPUTDEVICE device; 303 LPDIRECTINPUTDEVICE device;
294 DIPROPDWORD dipdw; 304 DIPROPDWORD dipdw;
295 305
296 /* Allocate the hwdata */ 306 /* Allocate the hwdata */
297 haptic->hwdata = (struct haptic_hwdata *) 307 haptic->hwdata = (struct haptic_hwdata *)
319 if (FAILED(ret)) { 329 if (FAILED(ret)) {
320 DI_SetError("Querying DirectInput interface",ret); 330 DI_SetError("Querying DirectInput interface",ret);
321 goto creat_err; 331 goto creat_err;
322 } 332 }
323 333
334 ret2 = SDL_SYS_HapticOpenFromDevice2( haptic, haptic->hwdata->device );
335 if (ret2 < 0) {
336 goto query_err;
337 }
338
339 return 0;
340
341 query_err:
342 IDirectInputDevice2_Release(haptic->hwdata->device);
343 creat_err:
344 if (haptic->hwdata != NULL) {
345 SDL_free(haptic->hwdata);
346 haptic->hwdata = NULL;
347 }
348 }
349
350
351 /*
352 * Opens the haptic device from the file descriptor.
353 *
354 * Steps:
355 * - Set cooperative level.
356 * - Set data format.
357 * - Acquire exclusiveness.
358 * - Reset actuators.
359 * - Get supported featuers.
360 */
361 static int
362 SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE2 device2)
363
364 {
365 HRESULT ret;
366
367 /* We'll use the device2 from now on. */
368 haptic->hwdata->device = device2;
369
324 /* Grab it exclusively to use force feedback stuff. */ 370 /* Grab it exclusively to use force feedback stuff. */
325 ret =IDirectInputDevice2_SetCooperativeLevel( haptic->hwdata->device, 371 ret =IDirectInputDevice2_SetCooperativeLevel( haptic->hwdata->device,
326 SDL_HelperWindow, 372 SDL_HelperWindow,
327 DISCL_EXCLUSIVE | DISCL_BACKGROUND ); 373 DISCL_EXCLUSIVE | DISCL_BACKGROUND );
328 if (FAILED(ret)) { 374 if (FAILED(ret)) {
333 /* Set data format. */ 379 /* Set data format. */
334 ret = IDirectInputDevice2_SetDataFormat( haptic->hwdata->device, 380 ret = IDirectInputDevice2_SetDataFormat( haptic->hwdata->device,
335 &c_dfDIJoystick2 ); 381 &c_dfDIJoystick2 );
336 if (FAILED(ret)) { 382 if (FAILED(ret)) {
337 DI_SetError("Setting data format",ret); 383 DI_SetError("Setting data format",ret);
338 goto query_err; 384 goto acquire_err;
339 } 385 }
340 386
341 /* Get number of axes. */ 387 /* Get number of axes. */
342 ret = IDirectInputDevice2_EnumObjects( haptic->hwdata->device, 388 ret = IDirectInputDevice2_EnumObjects( haptic->hwdata->device,
343 DI_DeviceObjectCallback, 389 DI_DeviceObjectCallback,
344 haptic, DIDFT_AXIS ); 390 haptic, DIDFT_AXIS );
345 if (FAILED(ret)) { 391 if (FAILED(ret)) {
346 DI_SetError("Getting device axes",ret); 392 DI_SetError("Getting device axes",ret);
347 goto query_err; 393 goto acquire_err;
348 } 394 }
349 395
350 /* Acquire the device. */ 396 /* Acquire the device. */
351 ret = IDirectInputDevice2_Acquire(haptic->hwdata->device); 397 ret = IDirectInputDevice2_Acquire(haptic->hwdata->device);
352 if (FAILED(ret)) { 398 if (FAILED(ret)) {
353 DI_SetError("Acquiring DirectInput device",ret); 399 DI_SetError("Acquiring DirectInput device",ret);
354 goto query_err; 400 goto acquire_err;
355 } 401 }
356 402
357 /* Reset all actuators - just in case. */ 403 /* Reset all actuators - just in case. */
358 ret = IDirectInputDevice2_SendForceFeedbackCommand( haptic->hwdata->device, 404 ret = IDirectInputDevice2_SendForceFeedbackCommand( haptic->hwdata->device,
359 DISFFC_RESET ); 405 DISFFC_RESET );
420 return 0; 466 return 0;
421 467
422 /* Error handling */ 468 /* Error handling */
423 acquire_err: 469 acquire_err:
424 IDirectInputDevice2_Unacquire(haptic->hwdata->device); 470 IDirectInputDevice2_Unacquire(haptic->hwdata->device);
425 query_err:
426 IDirectInputDevice2_Release(haptic->hwdata->device);
427 creat_err:
428 if (haptic->hwdata != NULL) {
429 SDL_free(haptic->hwdata);
430 haptic->hwdata = NULL;
431 }
432 return -1; 471 return -1;
433 472
434 } 473 }
435 474
436 475
468 * Checks to see if a joystick has haptic features. 507 * Checks to see if a joystick has haptic features.
469 */ 508 */
470 int 509 int
471 SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) 510 SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
472 { 511 {
512 if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
513 return SDL_TRUE;
514 }
515
473 return SDL_FALSE; 516 return SDL_FALSE;
474 } 517 }
475 518
476 519
477 /* 520 /*
478 * Checks to see if the haptic device and joystick and in reality the same. 521 * Checks to see if the haptic device and joystick and in reality the same.
479 */ 522 */
480 int 523 int
481 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) 524 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
482 { 525 {
526 HRESULT ret;
527 DIDEVICEINSTANCE hap_instance, joy_instance;
528
529 /* Get the device instances. */
530 ret = IDirectInputDevice2_GetDeviceInfo( haptic->hwdata->device,
531 &hap_instance );
532 if (FAILED(ret)) {
533 return 0;
534 }
535 ret = IDirectInputDevice2_GetDeviceInfo( joystick->hwdata->InputDevice,
536 &joy_instance );
537 if (FAILED(ret)) {
538 return 0;
539 }
540
541 if (DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance))
542 return 1;
543
483 return 0; 544 return 0;
484 } 545 }
485 546
486 547
487 /* 548 /*
488 * Opens a SDL_Haptic from a SDL_Joystick. 549 * Opens a SDL_Haptic from a SDL_Joystick.
489 */ 550 */
490 int 551 int
491 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) 552 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
492 { 553 {
493 return -1; 554 int ret;
555
556 ret = SDL_SYS_HapticOpenFromDevice2( haptic, joystick->hwdata->InputDevice );
557 if (ret < 0) {
558 return -1;
559 }
560
561 /* It's using the joystick device. */
562 haptic->hwdata->is_joystick = 1;
563
564 return 0;
494 } 565 }
495 566
496 567
497 /* 568 /*
498 * Closes the haptic device. 569 * Closes the haptic device.
507 haptic->effects = NULL; 578 haptic->effects = NULL;
508 haptic->neffects = 0; 579 haptic->neffects = 0;
509 580
510 /* Clean up */ 581 /* Clean up */
511 IDirectInputDevice2_Unacquire(haptic->hwdata->device); 582 IDirectInputDevice2_Unacquire(haptic->hwdata->device);
512 IDirectInputDevice2_Release(haptic->hwdata->device); 583 /* Only release if isn't grabbed by a joystick. */
584 if (haptic->hwdata->is_joystick == 0) {
585 IDirectInputDevice2_Release(haptic->hwdata->device);
586 }
513 587
514 /* Free */ 588 /* Free */
515 SDL_free(haptic->hwdata); 589 SDL_free(haptic->hwdata);
516 haptic->hwdata = NULL; 590 haptic->hwdata = NULL;
517 } 591 }