Mercurial > sdl-ios-xcode
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 } |