Updated Haptic API for SDL 3.0 conventions

Also removed the XInput haptic support since using the haptic API for rumble is no longer supported.
main
Sam Lantinga 2024-01-17 15:22:35 -08:00
parent 8ca9134115
commit f224af5ac5
35 changed files with 943 additions and 1320 deletions

View File

@ -1981,19 +1981,11 @@ elseif(WINDOWS)
set(HAVE_SDL_JOYSTICK TRUE) set(HAVE_SDL_JOYSTICK TRUE)
if(SDL_HAPTIC) if(SDL_HAPTIC)
if((HAVE_DINPUT_H OR HAVE_XINPUT_H) AND NOT WINDOWS_STORE) if(HAVE_DINPUT_H AND NOT WINDOWS_STORE)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/haptic/windows/*.c") sdl_glob_sources("${SDL3_SOURCE_DIR}/src/haptic/windows/*.c")
if(HAVE_DINPUT_H) set(SDL_HAPTIC_DINPUT 1)
set(SDL_HAPTIC_DINPUT 1) set(HAVE_SDL_HAPTIC TRUE)
endif()
if(HAVE_XINPUT_H)
set(SDL_HAPTIC_XINPUT 1)
endif()
else()
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/haptic/dummy/*.c")
set(SDL_HAPTIC_DUMMY 1)
endif() endif()
set(HAVE_SDL_HAPTIC TRUE)
endif() endif()
endif() endif()

View File

@ -422,7 +422,6 @@
<ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" /> <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" /> <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
<ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" /> <ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="..\..\src\joystick\controller_type.h" /> <ClInclude Include="..\..\src\joystick\controller_type.h" />
@ -636,16 +635,6 @@
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">stdcpp17</LanguageStandard> <LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">stdcpp17</LanguageStandard> <LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c">
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">stdcpp17</LanguageStandard>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" /> <ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" /> <ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" /> <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
@ -834,4 +823,4 @@
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -49,7 +49,6 @@
<ClCompile Include="..\..\src\haptic\SDL_haptic.c" /> <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" /> <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" /> <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" /> <ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" /> <ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" /> <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
@ -313,7 +312,6 @@
<ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" /> <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" /> <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
<ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" /> <ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="..\..\src\joystick\controller_type.h" /> <ClInclude Include="..\..\src\joystick\controller_type.h" />
@ -433,4 +431,4 @@
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\src\core\windows\version.rc" /> <ResourceCompile Include="..\..\src\core\windows\version.rc" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -122,7 +122,6 @@
<ClInclude Include="..\src\haptic\SDL_syshaptic.h" /> <ClInclude Include="..\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="..\src\haptic\windows\SDL_dinputhaptic_c.h" /> <ClInclude Include="..\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="..\src\haptic\windows\SDL_windowshaptic_c.h" /> <ClInclude Include="..\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="..\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="..\src\joystick\controller_type.h" /> <ClInclude Include="..\src\joystick\controller_type.h" />
<ClInclude Include="..\src\joystick\SDL_gamepad_c.h" /> <ClInclude Include="..\src\joystick\SDL_gamepad_c.h" />
<ClInclude Include="..\src\joystick\SDL_gamepad_db.h" /> <ClInclude Include="..\src\joystick\SDL_gamepad_db.h" />
@ -326,7 +325,6 @@
<ClCompile Include="..\src\haptic\SDL_haptic.c" /> <ClCompile Include="..\src\haptic\SDL_haptic.c" />
<ClCompile Include="..\src\haptic\windows\SDL_dinputhaptic.c" /> <ClCompile Include="..\src\haptic\windows\SDL_dinputhaptic.c" />
<ClCompile Include="..\src\haptic\windows\SDL_windowshaptic.c" /> <ClCompile Include="..\src\haptic\windows\SDL_windowshaptic.c" />
<ClCompile Include="..\src\haptic\windows\SDL_xinputhaptic.c" />
<ClCompile Include="..\src\hidapi\SDL_hidapi.c" /> <ClCompile Include="..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\src\joystick\dummy\SDL_sysjoystick.c" /> <ClCompile Include="..\src\joystick\dummy\SDL_sysjoystick.c" />
<ClCompile Include="..\src\joystick\controller_type.c" /> <ClCompile Include="..\src\joystick\controller_type.c" />

View File

@ -435,9 +435,6 @@
<ClInclude Include="..\src\SDL_list.h"> <ClInclude Include="..\src\SDL_list.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\haptic\windows\SDL_xinputhaptic_c.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\haptic\windows\SDL_dinputhaptic_c.h"> <ClInclude Include="..\src\haptic\windows\SDL_dinputhaptic_c.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
@ -855,9 +852,6 @@
<ClCompile Include="..\src\haptic\windows\SDL_windowshaptic.c"> <ClCompile Include="..\src\haptic\windows\SDL_windowshaptic.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\haptic\windows\SDL_xinputhaptic.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\video\SDL_yuv.c"> <ClCompile Include="..\src\video\SDL_yuv.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@ -348,7 +348,6 @@
<ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" /> <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" /> <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" /> <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
<ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" /> <ClInclude Include="..\..\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="..\..\src\joystick\controller_type.h" /> <ClInclude Include="..\..\src\joystick\controller_type.h" />
@ -515,7 +514,6 @@
<ClCompile Include="..\..\src\haptic\SDL_haptic.c" /> <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" /> <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" /> <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
<ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" /> <ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" /> <ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" /> <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />

View File

@ -546,9 +546,6 @@
<ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h"> <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h">
<Filter>haptic\windows</Filter> <Filter>haptic\windows</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h">
<Filter>haptic\windows</Filter>
</ClInclude>
<ClInclude Include="..\..\src\joystick\hidapi\SDL_hidapijoystick_c.h"> <ClInclude Include="..\..\src\joystick\hidapi\SDL_hidapijoystick_c.h">
<Filter>joystick\hidapi</Filter> <Filter>joystick\hidapi</Filter>
</ClInclude> </ClInclude>
@ -1050,9 +1047,6 @@
<ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c"> <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c">
<Filter>haptic\windows</Filter> <Filter>haptic\windows</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c">
<Filter>haptic\windows</Filter>
</ClCompile>
<ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c"> <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c">
<Filter>haptic\dummy</Filter> <Filter>haptic\dummy</Filter>
</ClCompile> </ClCompile>

View File

@ -2764,3 +2764,123 @@ expression e1, e2, e3, e4;
@@ @@
- SDL_SoftStretchLinear(e1, e2, e3, e4) - SDL_SoftStretchLinear(e1, e2, e3, e4)
+ SDL_SoftStretch(e1, e2, e3, e4, SDL_SCALEMODE_LINEAR) + SDL_SoftStretch(e1, e2, e3, e4, SDL_SCALEMODE_LINEAR)
@@
@@
- SDL_HapticClose
+ SDL_CloseHaptic
(...)
@@
@@
- SDL_HapticOpen
+ SDL_OpenHaptic
(...)
@@
@@
- SDL_HapticOpenFromMouse
+ SDL_OpenHapticFromMouse
(...)
@@
@@
- SDL_HapticOpenFromJoystick
+ SDL_OpenHapticFromJoystick
(...)
@@
@@
- SDL_MouseIsHaptic
+ SDL_IsMouseHaptic
(...)
@@
@@
- SDL_JoystickIsHaptic
+ SDL_IsJoystickHaptic
(...)
@@
@@
- SDL_HapticNumEffects
+ SDL_GetMaxHapticEffects
(...)
@@
@@
- SDL_HapticNumEffectsPlaying
+ SDL_GetMaxHapticEffectsPlaying
(...)
@@
@@
- SDL_HapticQuery
+ SDL_GetHapticFeatures
(...)
@@
@@
- SDL_HapticNumAxes
+ SDL_GetNumHapticAxes
(...)
@@
@@
- SDL_HapticNewEffect
+ SDL_CreateHapticEffect
(...)
@@
@@
- SDL_HapticUpdateEffect
+ SDL_UpdateHapticEffect
(...)
@@
@@
- SDL_HapticRunEffect
+ SDL_RunHapticEffect
(...)
@@
@@
- SDL_HapticStopEffect
+ SDL_StopHapticEffect
(...)
@@
@@
- SDL_HapticDestroyEffect
+ SDL_DestroyHapticEffect
(...)
@@
@@
- SDL_HapticGetEffectStatus
+ SDL_GetHapticEffectStatus
(...)
@@
@@
- SDL_HapticSetGain
+ SDL_SetHapticGain
(...)
@@
@@
- SDL_HapticSetAutocenter
+ SDL_SetHapticAutocenter
(...)
@@
@@
- SDL_HapticPause
+ SDL_PauseHaptic
(...)
@@
@@
- SDL_HapticUnpause
+ SDL_ResumeHaptic
(...)
@@
@@
- SDL_HapticStopAll
+ SDL_StopHapticEffects
(...)
@@
@@
- SDL_HapticRumbleInit
+ SDL_InitHapticRumble
(...)
@@
@@
- SDL_HapticRumblePlay
+ SDL_PlayHapticRumble
(...)
@@
@@
- SDL_HapticRumbleStop
+ SDL_StopHapticRumble
(...)

View File

@ -618,6 +618,65 @@ be dropped into an SDL3 or SDL2 program, to continue to provide this
functionality to your app and aid migration. That is located in the functionality to your app and aid migration. That is located in the
[SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture). [SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture).
## SDL_haptic.h
Gamepads with simple rumble capability no longer show up in the SDL haptics interface, instead you should use SDL_RumbleGamepad().
Rather than iterating over haptic devices using device index, there is a new function SDL_GetHaptics() to get the current list of haptic devices, and new functions to get information about haptic devices from their instance ID:
```c
{
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0) {
int i, num_haptics;
SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics);
if (haptics) {
for (i = 0; i < num_haptics; ++i) {
SDL_HapticID instance_id = haptics[i];
const char *name = SDL_GetHapticInstanceName(instance_id);
SDL_Log("Haptic %" SDL_PRIu32 ": %s\n",
instance_id, name ? name : "Unknown");
}
SDL_free(haptics);
}
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
}
}
```
SDL_HapticEffectSupported(), SDL_HapticRumbleSupported(), and SDL_IsJoystickHaptic() now return SDL_bool instead of an optional negative error code.
The following functions have been renamed:
* SDL_HapticClose() => SDL_CloseHaptic()
* SDL_HapticDestroyEffect() => SDL_DestroyHapticEffect()
* SDL_HapticGetEffectStatus() => SDL_GetHapticEffectStatus()
* SDL_HapticNewEffect() => SDL_CreateHapticEffect()
* SDL_HapticNumAxes() => SDL_GetNumHapticAxes()
* SDL_HapticNumEffects() => SDL_GetMaxHapticEffects()
* SDL_HapticNumEffectsPlaying() => SDL_GetMaxHapticEffectsPlaying()
* SDL_HapticOpen() => SDL_OpenHaptic()
* SDL_HapticOpenFromJoystick() => SDL_OpenHapticFromJoystick()
* SDL_HapticOpenFromMouse() => SDL_OpenHapticFromMouse()
* SDL_HapticPause() => SDL_PauseHaptic()
* SDL_HapticQuery() => SDL_GetHapticFeatures()
* SDL_HapticRumbleInit() => SDL_InitHapticRumble()
* SDL_HapticRumblePlay() => SDL_PlayHapticRumble()
* SDL_HapticRumbleStop() => SDL_StopHapticRumble()
* SDL_HapticRunEffect() => SDL_RunHapticEffect()
* SDL_HapticSetAutocenter() => SDL_SetHapticAutocenter()
* SDL_HapticSetGain() => SDL_SetHapticGain()
* SDL_HapticStopAll() => SDL_StopHapticEffects()
* SDL_HapticStopEffect() => SDL_StopHapticEffect()
* SDL_HapticUnpause() => SDL_ResumeHaptic()
* SDL_HapticUpdateEffect() => SDL_UpdateHapticEffect()
* SDL_JoystickIsHaptic() => SDL_IsJoystickHaptic()
* SDL_MouseIsHaptic() => SDL_IsMouseHaptic()
The following functions have been removed:
* SDL_HapticIndex() - replaced with SDL_GetHapticInstanceID()
* SDL_HapticName() - replaced with SDL_GetHapticInstanceName()
* SDL_HapticOpened() - replaced with SDL_GetHapticFromInstanceID()
* SDL_NumHaptics() - replaced with SDL_GetHaptics()
## SDL_hints.h ## SDL_hints.h
SDL_AddHintCallback() now returns a standard int result instead of void, returning 0 if the function succeeds or a negative error code if there was an error. SDL_AddHintCallback() now returns a standard int result instead of void, returning 0 if the function succeeds or a negative error code if there was an error.

View File

@ -27,55 +27,60 @@
* The basic usage is as follows: * The basic usage is as follows:
* - Initialize the subsystem (::SDL_INIT_HAPTIC). * - Initialize the subsystem (::SDL_INIT_HAPTIC).
* - Open a haptic device. * - Open a haptic device.
* - SDL_HapticOpen() to open from index. * - SDL_OpenHaptic() to open from index.
* - SDL_HapticOpenFromJoystick() to open from an existing joystick. * - SDL_OpenHapticFromJoystick() to open from an existing joystick.
* - Create an effect (::SDL_HapticEffect). * - Create an effect (::SDL_HapticEffect).
* - Upload the effect with SDL_HapticNewEffect(). * - Upload the effect with SDL_CreateHapticEffect().
* - Run the effect with SDL_HapticRunEffect(). * - Run the effect with SDL_RunHapticEffect().
* - (optional) Free the effect with SDL_HapticDestroyEffect(). * - (optional) Free the effect with SDL_DestroyHapticEffect().
* - Close the haptic device with SDL_HapticClose(). * - Close the haptic device with SDL_CloseHaptic().
* *
* \par Simple rumble example: * \par Simple rumble example:
* \code * \code
* SDL_Haptic *haptic; * SDL_Haptic *haptic = NULL;
* *
* // Open the device * // Open the device
* haptic = SDL_HapticOpen( 0 ); * SDL_HapticID *haptics = SDL_GetHaptics(NULL);
* if (haptics) {
* haptic = SDL_OpenHaptic(haptics[0]);
* SDL_free(haptics);
* }
* if (haptic == NULL) * if (haptic == NULL)
* return -1; * return -1;
* *
* // Initialize simple rumble * // Initialize simple rumble
* if (SDL_HapticRumbleInit( haptic ) != 0) * if (SDL_InitHapticRumble(haptic) != 0)
* return -1; * return -1;
* *
* // Play effect at 50% strength for 2 seconds * // Play effect at 50% strength for 2 seconds
* if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) * if (SDL_PlayHapticRumble(haptic, 0.5, 2000) != 0)
* return -1; * return -1;
* SDL_Delay( 2000 ); * SDL_Delay(2000);
* *
* // Clean up * // Clean up
* SDL_HapticClose( haptic ); * SDL_CloseHaptic(haptic);
* \endcode * \endcode
* *
* \par Complete example: * \par Complete example:
* \code * \code
* int test_haptic( SDL_Joystick * joystick ) { * int test_haptic(SDL_Joystick *joystick)
* {
* SDL_Haptic *haptic; * SDL_Haptic *haptic;
* SDL_HapticEffect effect; * SDL_HapticEffect effect;
* int effect_id; * int effect_id;
* *
* // Open the device * // Open the device
* haptic = SDL_HapticOpenFromJoystick( joystick ); * haptic = SDL_OpenHapticFromJoystick(joystick);
* if (haptic == NULL) return -1; // Most likely joystick isn't haptic * if (haptic == NULL) return -1; // Most likely joystick isn't haptic
* *
* // See if it can do sine waves * // See if it can do sine waves
* if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { * if ((SDL_GetHapticFeatures(haptic) & SDL_HAPTIC_SINE)==0) {
* SDL_HapticClose(haptic); // No sine effect * SDL_CloseHaptic(haptic); // No sine effect
* return -1; * return -1;
* } * }
* *
* // Create the effect * // Create the effect
* SDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default * SDL_memset(&effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
* effect.type = SDL_HAPTIC_SINE; * effect.type = SDL_HAPTIC_SINE;
* effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
* effect.periodic.direction.dir[0] = 18000; // Force comes from south * effect.periodic.direction.dir[0] = 18000; // Force comes from south
@ -86,21 +91,23 @@
* effect.periodic.fade_length = 1000; // Takes 1 second to fade away * effect.periodic.fade_length = 1000; // Takes 1 second to fade away
* *
* // Upload the effect * // Upload the effect
* effect_id = SDL_HapticNewEffect( haptic, &effect ); * effect_id = SDL_CreateHapticEffect(haptic, &effect);
* *
* // Test the effect * // Test the effect
* SDL_HapticRunEffect( haptic, effect_id, 1 ); * SDL_RunHapticEffect(haptic, effect_id, 1);
* SDL_Delay( 5000); // Wait for the effect to finish * SDL_Delay(5000); // Wait for the effect to finish
* *
* // We destroy the effect, although closing the device also does this * // We destroy the effect, although closing the device also does this
* SDL_HapticDestroyEffect( haptic, effect_id ); * SDL_DestroyHapticEffect(haptic, effect_id);
* *
* // Close the device * // Close the device
* SDL_HapticClose(haptic); * SDL_CloseHaptic(haptic);
* *
* return 0; // Success * return 0; // Success
* } * }
* \endcode * \endcode
*
* Note that the SDL haptic subsystem is not thread-safe.
*/ */
#ifndef SDL_haptic_h_ #ifndef SDL_haptic_h_
@ -132,9 +139,9 @@ extern "C" {
* *
* The haptic structure used to identify an SDL haptic. * The haptic structure used to identify an SDL haptic.
* *
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
* \sa SDL_HapticOpenFromJoystick * \sa SDL_OpenHapticFromJoystick
* \sa SDL_HapticClose * \sa SDL_CloseHaptic
*/ */
struct SDL_Haptic; struct SDL_Haptic;
typedef struct SDL_Haptic SDL_Haptic; typedef struct SDL_Haptic SDL_Haptic;
@ -276,7 +283,7 @@ typedef struct SDL_Haptic SDL_Haptic;
* *
* Device supports setting the global gain. * Device supports setting the global gain.
* *
* \sa SDL_HapticSetGain * \sa SDL_SetHapticGain
*/ */
#define SDL_HAPTIC_GAIN (1u<<12) #define SDL_HAPTIC_GAIN (1u<<12)
@ -285,7 +292,7 @@ typedef struct SDL_Haptic SDL_Haptic;
* *
* Device supports setting autocenter. * Device supports setting autocenter.
* *
* \sa SDL_HapticSetAutocenter * \sa SDL_SetHapticAutocenter
*/ */
#define SDL_HAPTIC_AUTOCENTER (1u<<13) #define SDL_HAPTIC_AUTOCENTER (1u<<13)
@ -294,7 +301,7 @@ typedef struct SDL_Haptic SDL_Haptic;
* *
* Device supports querying effect status. * Device supports querying effect status.
* *
* \sa SDL_HapticGetEffectStatus * \sa SDL_GetHapticEffectStatus
*/ */
#define SDL_HAPTIC_STATUS (1u<<14) #define SDL_HAPTIC_STATUS (1u<<14)
@ -303,8 +310,8 @@ typedef struct SDL_Haptic SDL_Haptic;
* *
* Devices supports being paused. * Devices supports being paused.
* *
* \sa SDL_HapticPause * \sa SDL_PauseHaptic
* \sa SDL_HapticUnpause * \sa SDL_ResumeHaptic
*/ */
#define SDL_HAPTIC_PAUSE (1u<<15) #define SDL_HAPTIC_PAUSE (1u<<15)
@ -356,7 +363,7 @@ typedef struct SDL_Haptic SDL_Haptic;
/** /**
* Used to play a device an infinite number of times. * Used to play a device an infinite number of times.
* *
* \sa SDL_HapticRunEffect * \sa SDL_RunHapticEffect
*/ */
#define SDL_HAPTIC_INFINITY 4294967295U #define SDL_HAPTIC_INFINITY 4294967295U
@ -455,7 +462,7 @@ typedef struct SDL_Haptic SDL_Haptic;
* \sa SDL_HAPTIC_SPHERICAL * \sa SDL_HAPTIC_SPHERICAL
* \sa SDL_HAPTIC_STEERING_AXIS * \sa SDL_HAPTIC_STEERING_AXIS
* \sa SDL_HapticEffect * \sa SDL_HapticEffect
* \sa SDL_HapticNumAxes * \sa SDL_GetNumHapticAxes
*/ */
typedef struct SDL_HapticDirection typedef struct SDL_HapticDirection
{ {
@ -819,36 +826,45 @@ typedef union SDL_HapticEffect
SDL_HapticCustom custom; /**< Custom effect. */ SDL_HapticCustom custom; /**< Custom effect. */
} SDL_HapticEffect; } SDL_HapticEffect;
/**
* This is a unique ID for a haptic device for the time it is connected to the system, and is never reused for the lifetime of the application. If the haptic device is disconnected and reconnected, it will get a new ID.
*
* The ID value starts at 1 and increments from there. The value 0 is an invalid ID.
*/
typedef Uint32 SDL_HapticID;
/* Function prototypes */ /* Function prototypes */
/** /**
* Count the number of haptic devices attached to the system. * Get a list of currently connected haptic devices.
* *
* \returns the number of haptic devices detected on the system or a negative * \param count a pointer filled in with the number of haptic devices returned
* error code on failure; call SDL_GetError() for more information. * \returns a 0 terminated array of haptic device instance IDs which should be
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
* more details.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticName * \sa SDL_OpenHaptic
*/ */
extern DECLSPEC int SDLCALL SDL_NumHaptics(void); extern DECLSPEC SDL_HapticID *SDLCALL SDL_GetHaptics(int *count);
/** /**
* Get the implementation dependent name of a haptic device. * Get the implementation dependent name of a haptic device.
* *
* This can be called before any joysticks are opened. If no name can be * This can be called before any haptic devices are opened.
* found, this function returns NULL.
* *
* \param device_index index of the device to query. * \param instance_id the haptic device instance ID
* \returns the name of the device or NULL on failure; call SDL_GetError() for * \returns the name of the selected haptic device. If no name can be found, this
* more information. * function returns NULL; call SDL_GetError() for more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_NumHaptics * \sa SDL_GetHapticName
* \sa SDL_OpenHaptic
*/ */
extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); extern DECLSPEC const char *SDLCALL SDL_GetHapticInstanceName(SDL_HapticID instance_id);
/** /**
* Open a haptic device for use. * Open a haptic device for use.
@ -857,53 +873,63 @@ extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index);
* system. * system.
* *
* When opening a haptic device, its gain will be set to maximum and * When opening a haptic device, its gain will be set to maximum and
* autocenter will be disabled. To modify these values use SDL_HapticSetGain() * autocenter will be disabled. To modify these values use SDL_SetHapticGain()
* and SDL_HapticSetAutocenter(). * and SDL_SetHapticAutocenter().
* *
* \param device_index index of the device to open * \param instance_id the haptic device instance ID
* \returns the device identifier or NULL on failure; call SDL_GetError() for * \returns the device identifier or NULL on failure; call SDL_GetError() for
* more information. * more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticClose * \sa SDL_CloseHaptic
* \sa SDL_HapticIndex * \sa SDL_OpenHapticFromJoystick
* \sa SDL_HapticOpenFromJoystick * \sa SDL_OpenHapticFromMouse
* \sa SDL_HapticOpenFromMouse * \sa SDL_PauseHaptic
* \sa SDL_HapticPause * \sa SDL_SetHapticAutocenter
* \sa SDL_HapticSetAutocenter * \sa SDL_SetHapticGain
* \sa SDL_HapticSetGain * \sa SDL_StopHapticEffects
* \sa SDL_HapticStopAll
*/ */
extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); extern DECLSPEC SDL_Haptic *SDLCALL SDL_OpenHaptic(SDL_HapticID instance_id);
/** /**
* Check if the haptic device at the designated index has been opened. * Get the SDL_Haptic associated with an instance ID, if it has been opened.
* *
* \param device_index the index of the device to query * \param instance_id the instance ID to get the SDL_Haptic for
* \returns 1 if it has been opened, 0 if it hasn't or on failure; call * \returns an SDL_Haptic on success or NULL on failure or if it hasn't been
* SDL_GetError() for more information. * opened yet; call SDL_GetError() for more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_HapticIndex
* \sa SDL_HapticOpen
*/ */
extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); extern DECLSPEC SDL_Haptic *SDLCALL SDL_GetHapticFromInstanceID(SDL_HapticID instance_id);
/** /**
* Get the index of a haptic device. * Get the instance ID of an opened haptic device.
* *
* \param haptic the SDL_Haptic device to query * \param haptic the SDL_Haptic device to query
* \returns the index of the specified haptic device or a negative error code * \returns the instance ID of the specified haptic device on success or 0 on
* on failure; call SDL_GetError() for more information. * failure; call SDL_GetError() for more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
* \sa SDL_HapticOpened
*/ */
extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); extern DECLSPEC SDL_HapticID SDLCALL SDL_GetHapticInstanceID(SDL_Haptic *haptic);
/**
* Get the implementation dependent name of a haptic device.
*
* \param haptic the SDL_Haptic obtained from SDL_OpenJoystick()
* \returns the name of the selected haptic device. If no name can be found, this
* function returns NULL; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetHapticInstanceName
* \sa SDL_OpenHaptic
*/
extern DECLSPEC const char *SDLCALL SDL_GetHapticName(SDL_Haptic *haptic);
/** /**
* Query whether or not the current mouse has haptic capabilities. * Query whether or not the current mouse has haptic capabilities.
@ -912,9 +938,9 @@ extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpenFromMouse * \sa SDL_OpenHapticFromMouse
*/ */
extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); extern DECLSPEC SDL_bool SDLCALL SDL_IsMouseHaptic(void);
/** /**
* Try to open a haptic device from the current mouse. * Try to open a haptic device from the current mouse.
@ -924,24 +950,22 @@ extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
* \sa SDL_MouseIsHaptic * \sa SDL_IsMouseHaptic
*/ */
extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); extern DECLSPEC SDL_Haptic *SDLCALL SDL_OpenHapticFromMouse(void);
/** /**
* Query if a joystick has haptic features. * Query if a joystick has haptic features.
* *
* \param joystick the SDL_Joystick to test for haptic capabilities * \param joystick the SDL_Joystick to test for haptic capabilities
* \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a * \returns SDL_TRUE if the joystick is haptic or SDL_FALSE if it isn't.
* negative error code on failure; call SDL_GetError() for more
* information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpenFromJoystick * \sa SDL_OpenHapticFromJoystick
*/ */
extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); extern DECLSPEC SDL_bool SDLCALL SDL_IsJoystickHaptic(SDL_Joystick *joystick);
/** /**
* Open a haptic device for use from a joystick device. * Open a haptic device for use from a joystick device.
@ -960,30 +984,29 @@ extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticClose * \sa SDL_CloseHaptic
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
* \sa SDL_JoystickIsHaptic * \sa SDL_IsJoystickHaptic
*/ */
extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * extern DECLSPEC SDL_Haptic *SDLCALL SDL_OpenHapticFromJoystick(SDL_Joystick *joystick);
joystick);
/** /**
* Close a haptic device previously opened with SDL_HapticOpen(). * Close a haptic device previously opened with SDL_OpenHaptic().
* *
* \param haptic the SDL_Haptic device to close * \param haptic the SDL_Haptic device to close
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
*/ */
extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); extern DECLSPEC void SDLCALL SDL_CloseHaptic(SDL_Haptic *haptic);
/** /**
* Get the number of effects a haptic device can store. * Get the number of effects a haptic device can store.
* *
* On some platforms this isn't fully supported, and therefore is an * On some platforms this isn't fully supported, and therefore is an
* approximation. Always check to see if your created effect was actually * approximation. Always check to see if your created effect was actually
* created and do not rely solely on SDL_HapticNumEffects(). * created and do not rely solely on SDL_GetMaxHapticEffects().
* *
* \param haptic the SDL_Haptic device to query * \param haptic the SDL_Haptic device to query
* \returns the number of effects the haptic device can store or a negative * \returns the number of effects the haptic device can store or a negative
@ -991,10 +1014,10 @@ extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticNumEffectsPlaying * \sa SDL_GetMaxHapticEffectsPlaying
* \sa SDL_HapticQuery * \sa SDL_GetHapticFeatures
*/ */
extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_GetMaxHapticEffects(SDL_Haptic *haptic);
/** /**
* Get the number of effects a haptic device can play at the same time. * Get the number of effects a haptic device can play at the same time.
@ -1008,10 +1031,10 @@ extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticNumEffects * \sa SDL_GetMaxHapticEffects
* \sa SDL_HapticQuery * \sa SDL_GetHapticFeatures
*/ */
extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_GetMaxHapticEffectsPlaying(SDL_Haptic *haptic);
/** /**
* Get the haptic device's supported features in bitwise manner. * Get the haptic device's supported features in bitwise manner.
@ -1023,9 +1046,9 @@ extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic);
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticEffectSupported * \sa SDL_HapticEffectSupported
* \sa SDL_HapticNumEffects * \sa SDL_GetMaxHapticEffects
*/ */
extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); extern DECLSPEC unsigned int SDLCALL SDL_GetHapticFeatures(SDL_Haptic *haptic);
/** /**
@ -1040,25 +1063,21 @@ extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
*/ */
extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_GetNumHapticAxes(SDL_Haptic *haptic);
/** /**
* Check to see if an effect is supported by a haptic device. * Check to see if an effect is supported by a haptic device.
* *
* \param haptic the SDL_Haptic device to query * \param haptic the SDL_Haptic device to query
* \param effect the desired effect to query * \param effect the desired effect to query
* \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a * \returns SDL_TRUE if the effect is supported or SDL_FALSE if it isn't.
* negative error code on failure; call SDL_GetError() for more
* information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticNewEffect * \sa SDL_CreateHapticEffect
* \sa SDL_HapticQuery * \sa SDL_GetHapticFeatures
*/ */
extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, extern DECLSPEC SDL_bool SDLCALL SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect);
SDL_HapticEffect *
effect);
/** /**
* Create a new haptic effect on a specified device. * Create a new haptic effect on a specified device.
@ -1071,12 +1090,11 @@ extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticDestroyEffect * \sa SDL_DestroyHapticEffect
* \sa SDL_HapticRunEffect * \sa SDL_RunHapticEffect
* \sa SDL_HapticUpdateEffect * \sa SDL_UpdateHapticEffect
*/ */
extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_CreateHapticEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect);
SDL_HapticEffect * effect);
/** /**
* Update the properties of an effect. * Update the properties of an effect.
@ -1084,7 +1102,7 @@ extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic,
* Can be used dynamically, although behavior when dynamically changing * Can be used dynamically, although behavior when dynamically changing
* direction may be strange. Specifically the effect may re-upload itself and * direction may be strange. Specifically the effect may re-upload itself and
* start playing from the start. You also cannot change the type either when * start playing from the start. You also cannot change the type either when
* running SDL_HapticUpdateEffect(). * running SDL_UpdateHapticEffect().
* *
* \param haptic the SDL_Haptic device that has the effect * \param haptic the SDL_Haptic device that has the effect
* \param effect the identifier of the effect to update * \param effect the identifier of the effect to update
@ -1095,13 +1113,11 @@ extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticDestroyEffect * \sa SDL_DestroyHapticEffect
* \sa SDL_HapticNewEffect * \sa SDL_CreateHapticEffect
* \sa SDL_HapticRunEffect * \sa SDL_RunHapticEffect
*/ */
extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_UpdateHapticEffect(SDL_Haptic *haptic, int effect, SDL_HapticEffect *data);
int effect,
SDL_HapticEffect * data);
/** /**
* Run the haptic effect on its associated haptic device. * Run the haptic effect on its associated haptic device.
@ -1121,13 +1137,11 @@ extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticDestroyEffect * \sa SDL_DestroyHapticEffect
* \sa SDL_HapticGetEffectStatus * \sa SDL_GetHapticEffectStatus
* \sa SDL_HapticStopEffect * \sa SDL_StopHapticEffect
*/ */
extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_RunHapticEffect(SDL_Haptic *haptic, int effect, Uint32 iterations);
int effect,
Uint32 iterations);
/** /**
* Stop the haptic effect on its associated haptic device. * Stop the haptic effect on its associated haptic device.
@ -1141,11 +1155,10 @@ extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticDestroyEffect * \sa SDL_DestroyHapticEffect
* \sa SDL_HapticRunEffect * \sa SDL_RunHapticEffect
*/ */
extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_StopHapticEffect(SDL_Haptic *haptic, int effect);
int effect);
/** /**
* Destroy a haptic effect on the device. * Destroy a haptic effect on the device.
@ -1158,10 +1171,9 @@ extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticNewEffect * \sa SDL_CreateHapticEffect
*/ */
extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, extern DECLSPEC void SDLCALL SDL_DestroyHapticEffect(SDL_Haptic *haptic, int effect);
int effect);
/** /**
* Get the status of the current effect on the specified haptic device. * Get the status of the current effect on the specified haptic device.
@ -1175,11 +1187,10 @@ extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticRunEffect * \sa SDL_RunHapticEffect
* \sa SDL_HapticStopEffect * \sa SDL_StopHapticEffect
*/ */
extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_GetHapticEffectStatus(SDL_Haptic *haptic, int effect);
int effect);
/** /**
* Set the global gain of the specified haptic device. * Set the global gain of the specified haptic device.
@ -1188,7 +1199,7 @@ extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic,
* *
* The user may specify the maximum gain by setting the environment variable * The user may specify the maximum gain by setting the environment variable
* `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to
* SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the * SDL_SetHapticGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the
* maximum. * maximum.
* *
* \param haptic the SDL_Haptic device to set the gain on * \param haptic the SDL_Haptic device to set the gain on
@ -1198,9 +1209,9 @@ extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticQuery * \sa SDL_GetHapticFeatures
*/ */
extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); extern DECLSPEC int SDLCALL SDL_SetHapticGain(SDL_Haptic *haptic, int gain);
/** /**
* Set the global autocenter of the device. * Set the global autocenter of the device.
@ -1217,16 +1228,15 @@ extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticQuery * \sa SDL_GetHapticFeatures
*/ */
extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, extern DECLSPEC int SDLCALL SDL_SetHapticAutocenter(SDL_Haptic *haptic, int autocenter);
int autocenter);
/** /**
* Pause a haptic device. * Pause a haptic device.
* *
* Device must support the `SDL_HAPTIC_PAUSE` feature. Call * Device must support the `SDL_HAPTIC_PAUSE` feature. Call
* SDL_HapticUnpause() to resume playback. * SDL_ResumeHaptic() to resume playback.
* *
* Do not modify the effects nor add new ones while the device is paused. That * Do not modify the effects nor add new ones while the device is paused. That
* can cause all sorts of weird errors. * can cause all sorts of weird errors.
@ -1237,14 +1247,14 @@ extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic,
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticUnpause * \sa SDL_ResumeHaptic
*/ */
extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_PauseHaptic(SDL_Haptic *haptic);
/** /**
* Unpause a haptic device. * Resume a haptic device.
* *
* Call to unpause after SDL_HapticPause(). * Call to unpause after SDL_PauseHaptic().
* *
* \param haptic the SDL_Haptic device to unpause * \param haptic the SDL_Haptic device to unpause
* \returns 0 on success or a negative error code on failure; call * \returns 0 on success or a negative error code on failure; call
@ -1252,9 +1262,9 @@ extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticPause * \sa SDL_PauseHaptic
*/ */
extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_ResumeHaptic(SDL_Haptic *haptic);
/** /**
* Stop all the currently playing effects on a haptic device. * Stop all the currently playing effects on a haptic device.
@ -1265,7 +1275,7 @@ extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
*/ */
extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_StopHapticEffects(SDL_Haptic *haptic);
/** /**
* Check whether rumble is supported on a haptic device. * Check whether rumble is supported on a haptic device.
@ -1277,11 +1287,11 @@ extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticRumbleInit * \sa SDL_InitHapticRumble
* \sa SDL_HapticRumblePlay * \sa SDL_PlayHapticRumble
* \sa SDL_HapticRumbleStop * \sa SDL_StopHapticRumble
*/ */
extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic *haptic);
/** /**
* Initialize a haptic device for simple rumble playback. * Initialize a haptic device for simple rumble playback.
@ -1292,12 +1302,12 @@ extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticOpen * \sa SDL_OpenHaptic
* \sa SDL_HapticRumblePlay * \sa SDL_PlayHapticRumble
* \sa SDL_HapticRumbleStop * \sa SDL_StopHapticRumble
* \sa SDL_HapticRumbleSupported * \sa SDL_HapticRumbleSupported
*/ */
extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_InitHapticRumble(SDL_Haptic *haptic);
/** /**
* Run a simple rumble effect on a haptic device. * Run a simple rumble effect on a haptic device.
@ -1310,11 +1320,11 @@ extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic);
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticRumbleInit * \sa SDL_InitHapticRumble
* \sa SDL_HapticRumbleStop * \sa SDL_StopHapticRumble
* \sa SDL_HapticRumbleSupported * \sa SDL_HapticRumbleSupported
*/ */
extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); extern DECLSPEC int SDLCALL SDL_PlayHapticRumble(SDL_Haptic *haptic, float strength, Uint32 length);
/** /**
* Stop the simple rumble on a haptic device. * Stop the simple rumble on a haptic device.
@ -1325,11 +1335,11 @@ extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float stre
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HapticRumbleInit * \sa SDL_InitHapticRumble
* \sa SDL_HapticRumblePlay * \sa SDL_PlayHapticRumble
* \sa SDL_HapticRumbleSupported * \sa SDL_HapticRumbleSupported
*/ */
extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); extern DECLSPEC int SDLCALL SDL_StopHapticRumble(SDL_Haptic *haptic);
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -251,6 +251,32 @@
#define SDL_INIT_GAMECONTROLLER SDL_INIT_GAMEPAD #define SDL_INIT_GAMECONTROLLER SDL_INIT_GAMEPAD
#define SDL_IsGameController SDL_IsGamepad #define SDL_IsGameController SDL_IsGamepad
/* ##SDL_haptic.h */
#define SDL_HapticClose SDL_CloseHaptic
#define SDL_HapticDestroyEffect SDL_DestroyHapticEffect
#define SDL_HapticGetEffectStatus SDL_GetHapticEffectStatus
#define SDL_HapticNewEffect SDL_CreateHapticEffect
#define SDL_HapticNumAxes SDL_GetNumHapticAxes
#define SDL_HapticNumEffects SDL_GetMaxHapticEffects
#define SDL_HapticNumEffectsPlaying SDL_GetMaxHapticEffectsPlaying
#define SDL_HapticOpen SDL_OpenHaptic
#define SDL_HapticOpenFromJoystick SDL_OpenHapticFromJoystick
#define SDL_HapticOpenFromMouse SDL_OpenHapticFromMouse
#define SDL_HapticPause SDL_PauseHaptic
#define SDL_HapticQuery SDL_GetHapticFeatures
#define SDL_HapticRumbleInit SDL_InitHapticRumble
#define SDL_HapticRumblePlay SDL_PlayHapticRumble
#define SDL_HapticRumbleStop SDL_StopHapticRumble
#define SDL_HapticRunEffect SDL_RunHapticEffect
#define SDL_HapticSetAutocenter SDL_SetHapticAutocenter
#define SDL_HapticSetGain SDL_SetHapticGain
#define SDL_HapticStopAll SDL_StopHapticEffects
#define SDL_HapticStopEffect SDL_StopHapticEffect
#define SDL_HapticUnpause SDL_ResumeHaptic
#define SDL_HapticUpdateEffect SDL_UpdateHapticEffect
#define SDL_JoystickIsHaptic SDL_IsJoystickHaptic
#define SDL_MouseIsHaptic SDL_IsMouseHaptic
/* ##SDL_joystick.h */ /* ##SDL_joystick.h */
#define SDL_JOYSTICK_TYPE_GAMECONTROLLER SDL_JOYSTICK_TYPE_GAMEPAD #define SDL_JOYSTICK_TYPE_GAMECONTROLLER SDL_JOYSTICK_TYPE_GAMEPAD
#define SDL_JoystickAttachVirtual SDL_AttachVirtualJoystick #define SDL_JoystickAttachVirtual SDL_AttachVirtualJoystick
@ -696,6 +722,32 @@
#define SDL_INIT_GAMECONTROLLER SDL_INIT_GAMECONTROLLER_renamed_SDL_INIT_GAMEPAD #define SDL_INIT_GAMECONTROLLER SDL_INIT_GAMECONTROLLER_renamed_SDL_INIT_GAMEPAD
#define SDL_IsGameController SDL_IsGameController_renamed_SDL_IsGamepad #define SDL_IsGameController SDL_IsGameController_renamed_SDL_IsGamepad
/* ##SDL_haptic.h */
#define SDL_HapticClose SDL_HapticClose_renamed_SDL_CloseHaptic
#define SDL_HapticDestroyEffect SDL_HapticDestroyEffect_renamed_SDL_DestroyHapticEffect
#define SDL_HapticGetEffectStatus SDL_HapticGetEffectStatus_renamed_SDL_GetHapticEffectStatus
#define SDL_HapticNewEffect SDL_HapticNewEffect_renamed_SDL_CreateHapticEffect
#define SDL_HapticNumAxes SDL_HapticNumAxes_renamed_SDL_GetNumHapticAxes
#define SDL_HapticNumEffects SDL_HapticNumEffects_renamed_SDL_GetMaxHapticEffects
#define SDL_HapticNumEffectsPlaying SDL_HapticNumEffectsPlaying_renamed_SDL_GetMaxHapticEffectsPlaying
#define SDL_HapticOpen SDL_HapticOpen_renamed_SDL_OpenHaptic
#define SDL_HapticOpenFromJoystick SDL_HapticOpenFromJoystick_renamed_SDL_OpenHapticFromJoystick
#define SDL_HapticOpenFromMouse SDL_HapticOpenFromMouse_renamed_SDL_OpenHapticFromMouse
#define SDL_HapticPause SDL_HapticPause_renamed_SDL_PauseHaptic
#define SDL_HapticQuery SDL_HapticQuery_renamed_SDL_GetHapticFeatures
#define SDL_HapticRumbleInit SDL_HapticRumbleInit_renamed_SDL_InitHapticRumble
#define SDL_HapticRumblePlay SDL_HapticRumblePlay_renamed_SDL_PlayHapticRumble
#define SDL_HapticRumbleStop SDL_HapticRumbleStop_renamed_SDL_StopHapticRumble
#define SDL_HapticRunEffect SDL_HapticRunEffect_renamed_SDL_RunHapticEffect
#define SDL_HapticSetAutocenter SDL_HapticSetAutocenter_renamed_SDL_SetHapticAutocenter
#define SDL_HapticSetGain SDL_HapticSetGain_renamed_SDL_SetHapticGain
#define SDL_HapticStopAll SDL_HapticStopAll_renamed_SDL_StopHapticEffects
#define SDL_HapticStopEffect SDL_HapticStopEffect_renamed_SDL_StopHapticEffect
#define SDL_HapticUnpause SDL_HapticUnpause_renamed_SDL_ResumeHaptic
#define SDL_HapticUpdateEffect SDL_HapticUpdateEffect_renamed_SDL_UpdateHapticEffect
#define SDL_JoystickIsHaptic SDL_JoystickIsHaptic_renamed_SDL_IsJoystickHaptic
#define SDL_MouseIsHaptic SDL_MouseIsHaptic_renamed_SDL_IsMouseHaptic
/* ##SDL_joystick.h */ /* ##SDL_joystick.h */
#define SDL_JOYSTICK_TYPE_GAMECONTROLLER SDL_JOYSTICK_TYPE_GAMECONTROLLER_renamed_SDL_JOYSTICK_TYPE_GAMEPAD #define SDL_JOYSTICK_TYPE_GAMECONTROLLER SDL_JOYSTICK_TYPE_GAMECONTROLLER_renamed_SDL_JOYSTICK_TYPE_GAMEPAD
#define SDL_JoystickAttachVirtual SDL_JoystickAttachVirtual_renamed_SDL_AttachVirtualJoystick #define SDL_JoystickAttachVirtual SDL_JoystickAttachVirtual_renamed_SDL_AttachVirtualJoystick

View File

@ -323,7 +323,6 @@
#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@ #cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@
#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@ #cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@
#cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@ #cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@
#cmakedefine SDL_HAPTIC_XINPUT @SDL_HAPTIC_XINPUT@
#cmakedefine SDL_HAPTIC_ANDROID @SDL_HAPTIC_ANDROID@ #cmakedefine SDL_HAPTIC_ANDROID @SDL_HAPTIC_ANDROID@
#cmakedefine SDL_LIBUSB_DYNAMIC @SDL_LIBUSB_DYNAMIC@ #cmakedefine SDL_LIBUSB_DYNAMIC @SDL_LIBUSB_DYNAMIC@
#cmakedefine SDL_UDEV_DYNAMIC @SDL_UDEV_DYNAMIC@ #cmakedefine SDL_UDEV_DYNAMIC @SDL_UDEV_DYNAMIC@

View File

@ -241,7 +241,6 @@ typedef unsigned int uintptr_t;
#endif #endif
#define SDL_JOYSTICK_XINPUT 1 #define SDL_JOYSTICK_XINPUT 1
#define SDL_HAPTIC_DINPUT 1 #define SDL_HAPTIC_DINPUT 1
#define SDL_HAPTIC_XINPUT 1
/* Enable the sensor driver */ /* Enable the sensor driver */
#ifdef HAVE_SENSORSAPI_H #ifdef HAVE_SENSORSAPI_H

View File

@ -181,7 +181,6 @@
#endif #endif
#define SDL_JOYSTICK_XINPUT 1 #define SDL_JOYSTICK_XINPUT 1
#define SDL_HAPTIC_DINPUT 1 #define SDL_HAPTIC_DINPUT 1
#define SDL_HAPTIC_XINPUT 1
/* Enable the sensor driver */ /* Enable the sensor driver */
#ifdef HAVE_SENSORSAPI_H #ifdef HAVE_SENSORSAPI_H

View File

@ -168,7 +168,6 @@
#define SDL_HAPTIC_DISABLED 1 #define SDL_HAPTIC_DISABLED 1
#else #else
#define SDL_JOYSTICK_XINPUT 1 #define SDL_JOYSTICK_XINPUT 1
#define SDL_HAPTIC_XINPUT 1
#endif /* WIN10 */ #endif /* WIN10 */
#endif #endif

View File

@ -181,7 +181,6 @@
#endif #endif
#define SDL_JOYSTICK_XINPUT 1 #define SDL_JOYSTICK_XINPUT 1
/*#define SDL_HAPTIC_DINPUT 1*/ /*#define SDL_HAPTIC_DINPUT 1*/
#define SDL_HAPTIC_XINPUT 1
/* Enable the sensor driver */ /* Enable the sensor driver */
#ifdef HAVE_SENSORSAPI_H #ifdef HAVE_SENSORSAPI_H

View File

@ -352,33 +352,30 @@ SDL3_0.0.0 {
SDL_GetWindowTitle; SDL_GetWindowTitle;
SDL_GetYUVConversionMode; SDL_GetYUVConversionMode;
SDL_GetYUVConversionModeForResolution; SDL_GetYUVConversionModeForResolution;
SDL_HapticClose; SDL_CloseHaptic;
SDL_HapticDestroyEffect; SDL_DestroyHapticEffect;
SDL_HapticEffectSupported; SDL_HapticEffectSupported;
SDL_HapticGetEffectStatus; SDL_GetHapticEffectStatus;
SDL_HapticIndex; SDL_CreateHapticEffect;
SDL_HapticName; SDL_GetNumHapticAxes;
SDL_HapticNewEffect; SDL_GetMaxHapticEffects;
SDL_HapticNumAxes; SDL_GetMaxHapticEffectsPlaying;
SDL_HapticNumEffects; SDL_OpenHaptic;
SDL_HapticNumEffectsPlaying; SDL_OpenHapticFromJoystick;
SDL_HapticOpen; SDL_OpenHapticFromMouse;
SDL_HapticOpenFromJoystick; SDL_PauseHaptic;
SDL_HapticOpenFromMouse; SDL_GetHapticFeatures;
SDL_HapticOpened; SDL_InitHapticRumble;
SDL_HapticPause; SDL_PlayHapticRumble;
SDL_HapticQuery; SDL_StopHapticRumble;
SDL_HapticRumbleInit;
SDL_HapticRumblePlay;
SDL_HapticRumbleStop;
SDL_HapticRumbleSupported; SDL_HapticRumbleSupported;
SDL_HapticRunEffect; SDL_RunHapticEffect;
SDL_HapticSetAutocenter; SDL_SetHapticAutocenter;
SDL_HapticSetGain; SDL_SetHapticGain;
SDL_HapticStopAll; SDL_StopHapticEffects;
SDL_HapticStopEffect; SDL_StopHapticEffect;
SDL_HapticUnpause; SDL_ResumeHaptic;
SDL_HapticUpdateEffect; SDL_UpdateHapticEffect;
SDL_HasARMSIMD; SDL_HasARMSIMD;
SDL_HasAVX2; SDL_HasAVX2;
SDL_HasAVX512F; SDL_HasAVX512F;
@ -417,7 +414,7 @@ SDL3_0.0.0 {
SDL_JoystickHasLED; SDL_JoystickHasLED;
SDL_JoystickHasRumble; SDL_JoystickHasRumble;
SDL_JoystickHasRumbleTriggers; SDL_JoystickHasRumbleTriggers;
SDL_JoystickIsHaptic; SDL_IsJoystickHaptic;
SDL_LinuxSetThreadPriority; SDL_LinuxSetThreadPriority;
SDL_LinuxSetThreadPriorityAndPolicy; SDL_LinuxSetThreadPriorityAndPolicy;
SDL_LoadBMP; SDL_LoadBMP;
@ -457,8 +454,7 @@ SDL3_0.0.0 {
SDL_Metal_DestroyView; SDL_Metal_DestroyView;
SDL_Metal_GetLayer; SDL_Metal_GetLayer;
SDL_MinimizeWindow; SDL_MinimizeWindow;
SDL_MouseIsHaptic; SDL_IsMouseHaptic;
SDL_NumHaptics;
SDL_OnApplicationDidBecomeActive; SDL_OnApplicationDidBecomeActive;
SDL_OnApplicationDidChangeStatusBarOrientation; SDL_OnApplicationDidChangeStatusBarOrientation;
SDL_OnApplicationDidEnterBackground; SDL_OnApplicationDidEnterBackground;
@ -962,6 +958,11 @@ SDL3_0.0.0 {
SDL_SyncWindow; SDL_SyncWindow;
SDL_GetGamepadSteamHandle; SDL_GetGamepadSteamHandle;
SDL_GetRendererFromTexture; SDL_GetRendererFromTexture;
SDL_GetHaptics;
SDL_GetHapticInstanceName;
SDL_GetHapticFromInstanceID;
SDL_GetHapticInstanceID;
SDL_GetHapticName;
# extra symbols go here (don't modify this line) # extra symbols go here (don't modify this line)
local: *; local: *;
}; };

View File

@ -376,33 +376,30 @@
#define SDL_GetWindowTitle SDL_GetWindowTitle_REAL #define SDL_GetWindowTitle SDL_GetWindowTitle_REAL
#define SDL_GetYUVConversionMode SDL_GetYUVConversionMode_REAL #define SDL_GetYUVConversionMode SDL_GetYUVConversionMode_REAL
#define SDL_GetYUVConversionModeForResolution SDL_GetYUVConversionModeForResolution_REAL #define SDL_GetYUVConversionModeForResolution SDL_GetYUVConversionModeForResolution_REAL
#define SDL_HapticClose SDL_HapticClose_REAL #define SDL_CloseHaptic SDL_CloseHaptic_REAL
#define SDL_HapticDestroyEffect SDL_HapticDestroyEffect_REAL #define SDL_DestroyHapticEffect SDL_DestroyHapticEffect_REAL
#define SDL_HapticEffectSupported SDL_HapticEffectSupported_REAL #define SDL_HapticEffectSupported SDL_HapticEffectSupported_REAL
#define SDL_HapticGetEffectStatus SDL_HapticGetEffectStatus_REAL #define SDL_GetHapticEffectStatus SDL_GetHapticEffectStatus_REAL
#define SDL_HapticIndex SDL_HapticIndex_REAL #define SDL_CreateHapticEffect SDL_CreateHapticEffect_REAL
#define SDL_HapticName SDL_HapticName_REAL #define SDL_GetNumHapticAxes SDL_GetNumHapticAxes_REAL
#define SDL_HapticNewEffect SDL_HapticNewEffect_REAL #define SDL_GetMaxHapticEffects SDL_GetMaxHapticEffects_REAL
#define SDL_HapticNumAxes SDL_HapticNumAxes_REAL #define SDL_GetMaxHapticEffectsPlaying SDL_GetMaxHapticEffectsPlaying_REAL
#define SDL_HapticNumEffects SDL_HapticNumEffects_REAL #define SDL_OpenHaptic SDL_OpenHaptic_REAL
#define SDL_HapticNumEffectsPlaying SDL_HapticNumEffectsPlaying_REAL #define SDL_OpenHapticFromJoystick SDL_OpenHapticFromJoystick_REAL
#define SDL_HapticOpen SDL_HapticOpen_REAL #define SDL_OpenHapticFromMouse SDL_OpenHapticFromMouse_REAL
#define SDL_HapticOpenFromJoystick SDL_HapticOpenFromJoystick_REAL #define SDL_PauseHaptic SDL_PauseHaptic_REAL
#define SDL_HapticOpenFromMouse SDL_HapticOpenFromMouse_REAL #define SDL_GetHapticFeatures SDL_GetHapticFeatures_REAL
#define SDL_HapticOpened SDL_HapticOpened_REAL #define SDL_InitHapticRumble SDL_InitHapticRumble_REAL
#define SDL_HapticPause SDL_HapticPause_REAL #define SDL_PlayHapticRumble SDL_PlayHapticRumble_REAL
#define SDL_HapticQuery SDL_HapticQuery_REAL #define SDL_StopHapticRumble SDL_StopHapticRumble_REAL
#define SDL_HapticRumbleInit SDL_HapticRumbleInit_REAL
#define SDL_HapticRumblePlay SDL_HapticRumblePlay_REAL
#define SDL_HapticRumbleStop SDL_HapticRumbleStop_REAL
#define SDL_HapticRumbleSupported SDL_HapticRumbleSupported_REAL #define SDL_HapticRumbleSupported SDL_HapticRumbleSupported_REAL
#define SDL_HapticRunEffect SDL_HapticRunEffect_REAL #define SDL_RunHapticEffect SDL_RunHapticEffect_REAL
#define SDL_HapticSetAutocenter SDL_HapticSetAutocenter_REAL #define SDL_SetHapticAutocenter SDL_SetHapticAutocenter_REAL
#define SDL_HapticSetGain SDL_HapticSetGain_REAL #define SDL_SetHapticGain SDL_SetHapticGain_REAL
#define SDL_HapticStopAll SDL_HapticStopAll_REAL #define SDL_StopHapticEffects SDL_StopHapticEffects_REAL
#define SDL_HapticStopEffect SDL_HapticStopEffect_REAL #define SDL_StopHapticEffect SDL_StopHapticEffect_REAL
#define SDL_HapticUnpause SDL_HapticUnpause_REAL #define SDL_ResumeHaptic SDL_ResumeHaptic_REAL
#define SDL_HapticUpdateEffect SDL_HapticUpdateEffect_REAL #define SDL_UpdateHapticEffect SDL_UpdateHapticEffect_REAL
#define SDL_HasARMSIMD SDL_HasARMSIMD_REAL #define SDL_HasARMSIMD SDL_HasARMSIMD_REAL
#define SDL_HasAVX SDL_HasAVX_REAL #define SDL_HasAVX SDL_HasAVX_REAL
#define SDL_HasAVX2 SDL_HasAVX2_REAL #define SDL_HasAVX2 SDL_HasAVX2_REAL
@ -441,7 +438,7 @@
#define SDL_JoystickHasLED SDL_JoystickHasLED_REAL #define SDL_JoystickHasLED SDL_JoystickHasLED_REAL
#define SDL_JoystickHasRumble SDL_JoystickHasRumble_REAL #define SDL_JoystickHasRumble SDL_JoystickHasRumble_REAL
#define SDL_JoystickHasRumbleTriggers SDL_JoystickHasRumbleTriggers_REAL #define SDL_JoystickHasRumbleTriggers SDL_JoystickHasRumbleTriggers_REAL
#define SDL_JoystickIsHaptic SDL_JoystickIsHaptic_REAL #define SDL_IsJoystickHaptic SDL_IsJoystickHaptic_REAL
#define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL #define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL
#define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL #define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL
#define SDL_LoadBMP SDL_LoadBMP_REAL #define SDL_LoadBMP SDL_LoadBMP_REAL
@ -481,8 +478,7 @@
#define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL #define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL
#define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL #define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL
#define SDL_MinimizeWindow SDL_MinimizeWindow_REAL #define SDL_MinimizeWindow SDL_MinimizeWindow_REAL
#define SDL_MouseIsHaptic SDL_MouseIsHaptic_REAL #define SDL_IsMouseHaptic SDL_IsMouseHaptic_REAL
#define SDL_NumHaptics SDL_NumHaptics_REAL
#define SDL_OnApplicationDidBecomeActive SDL_OnApplicationDidBecomeActive_REAL #define SDL_OnApplicationDidBecomeActive SDL_OnApplicationDidBecomeActive_REAL
#define SDL_OnApplicationDidChangeStatusBarOrientation SDL_OnApplicationDidChangeStatusBarOrientation_REAL #define SDL_OnApplicationDidChangeStatusBarOrientation SDL_OnApplicationDidChangeStatusBarOrientation_REAL
#define SDL_OnApplicationDidEnterBackground SDL_OnApplicationDidEnterBackground_REAL #define SDL_OnApplicationDidEnterBackground SDL_OnApplicationDidEnterBackground_REAL
@ -987,3 +983,8 @@
#define SDL_SyncWindow SDL_SyncWindow_REAL #define SDL_SyncWindow SDL_SyncWindow_REAL
#define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL #define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL
#define SDL_GetRendererFromTexture SDL_GetRendererFromTexture_REAL #define SDL_GetRendererFromTexture SDL_GetRendererFromTexture_REAL
#define SDL_GetHaptics SDL_GetHaptics_REAL
#define SDL_GetHapticInstanceName SDL_GetHapticInstanceName_REAL
#define SDL_GetHapticFromInstanceID SDL_GetHapticFromInstanceID_REAL
#define SDL_GetHapticInstanceID SDL_GetHapticInstanceID_REAL
#define SDL_GetHapticName SDL_GetHapticName_REAL

View File

@ -435,33 +435,30 @@ SDL_DYNAPI_PROC(SDL_Surface*,SDL_GetWindowSurface,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetWindowTitle,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetWindowTitle,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionMode,(void),(),return) SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionMode,(void),(),return)
SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionModeForResolution,(int a, int b),(a,b),return) SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionModeForResolution,(int a, int b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_HapticClose,(SDL_Haptic *a),(a),) SDL_DYNAPI_PROC(void,SDL_CloseHaptic,(SDL_Haptic *a),(a),)
SDL_DYNAPI_PROC(void,SDL_HapticDestroyEffect,(SDL_Haptic *a, int b),(a,b),) SDL_DYNAPI_PROC(void,SDL_DestroyHapticEffect,(SDL_Haptic *a, int b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_HapticEffectSupported,(SDL_Haptic *a, SDL_HapticEffect *b),(a,b),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HapticEffectSupported,(SDL_Haptic *a, SDL_HapticEffect *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticGetEffectStatus,(SDL_Haptic *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetHapticEffectStatus,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticIndex,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_CreateHapticEffect,(SDL_Haptic *a, SDL_HapticEffect *b),(a,b),return)
SDL_DYNAPI_PROC(const char*,SDL_HapticName,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumHapticAxes,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticNewEffect,(SDL_Haptic *a, SDL_HapticEffect *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffects,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticNumAxes,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffectsPlaying,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticNumEffects,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(SDL_Haptic*,SDL_OpenHaptic,(SDL_HapticID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticNumEffectsPlaying,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(SDL_Haptic*,SDL_OpenHapticFromJoystick,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_Haptic*,SDL_HapticOpen,(int a),(a),return) SDL_DYNAPI_PROC(SDL_Haptic*,SDL_OpenHapticFromMouse,(void),(),return)
SDL_DYNAPI_PROC(SDL_Haptic*,SDL_HapticOpenFromJoystick,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PauseHaptic,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(SDL_Haptic*,SDL_HapticOpenFromMouse,(void),(),return) SDL_DYNAPI_PROC(unsigned int,SDL_GetHapticFeatures,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticOpened,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_InitHapticRumble,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticPause,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PlayHapticRumble,(SDL_Haptic *a, float b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(unsigned int,SDL_HapticQuery,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_StopHapticRumble,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticRumbleInit,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HapticRumbleSupported,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticRumblePlay,(SDL_Haptic *a, float b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_RunHapticEffect,(SDL_Haptic *a, int b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_HapticRumbleStop,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetHapticAutocenter,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticRumbleSupported,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticRunEffect,(SDL_Haptic *a, int b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_StopHapticEffects,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticSetAutocenter,(SDL_Haptic *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_StopHapticEffect,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticSetGain,(SDL_Haptic *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_ResumeHaptic,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticStopAll,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_UpdateHapticEffect,(SDL_Haptic *a, int b, SDL_HapticEffect *c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_HapticStopEffect,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_HapticUnpause,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_HapticUpdateEffect,(SDL_Haptic *a, int b, SDL_HapticEffect *c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasARMSIMD,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasARMSIMD,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX2,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX2,(void),(),return)
@ -497,7 +494,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickEventsEnabled,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasLED,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasLED,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumble,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumble,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumbleTriggers,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumbleTriggers,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickIsHaptic,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsJoystickHaptic,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadBMP,(const char *a),(a),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadBMP,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadBMP_RW,(SDL_RWops *a, SDL_bool b),(a,b),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadBMP_RW,(SDL_RWops *a, SDL_bool b),(a,b),return)
SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return) SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return)
@ -527,8 +524,7 @@ SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),) SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),)
SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return) SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return)
SDL_DYNAPI_PROC(int,SDL_MinimizeWindow,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(int,SDL_MinimizeWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_MouseIsHaptic,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsMouseHaptic,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_NumHaptics,(void),(),return)
SDL_DYNAPI_PROC(void,SDL_OnApplicationDidBecomeActive,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationDidBecomeActive,(void),(),)
SDL_DYNAPI_PROC(void,SDL_OnApplicationDidEnterBackground,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationDidEnterBackground,(void),(),)
SDL_DYNAPI_PROC(void,SDL_OnApplicationDidReceiveMemoryWarning,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationDidReceiveMemoryWarning,(void),(),)
@ -1012,3 +1008,8 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t
SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetGamepadSteamHandle,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(Uint64,SDL_GetGamepadSteamHandle,(SDL_Gamepad *a),(a),return)
SDL_DYNAPI_PROC(SDL_Renderer*,SDL_GetRendererFromTexture,(SDL_Texture *a),(a),return) SDL_DYNAPI_PROC(SDL_Renderer*,SDL_GetRendererFromTexture,(SDL_Texture *a),(a),return)
SDL_DYNAPI_PROC(SDL_HapticID*,SDL_GetHaptics,(int *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetHapticInstanceName,(SDL_HapticID a),(a),return)
SDL_DYNAPI_PROC(SDL_Haptic*,SDL_GetHapticFromInstanceID,(SDL_HapticID a),(a),return)
SDL_DYNAPI_PROC(SDL_HapticID,SDL_GetHapticInstanceID,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetHapticName,(SDL_Haptic *a),(a),return)

View File

@ -24,16 +24,15 @@
#include "SDL_haptic_c.h" #include "SDL_haptic_c.h"
#include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */ #include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */
/* Global for SDL_windowshaptic.c */
#if (defined(SDL_HAPTIC_DINPUT) && SDL_HAPTIC_DINPUT) || (defined(SDL_HAPTIC_XINPUT) && SDL_HAPTIC_XINPUT)
SDL_Haptic *SDL_haptics = NULL;
#else
static SDL_Haptic *SDL_haptics = NULL; static SDL_Haptic *SDL_haptics = NULL;
#endif static char SDL_haptic_magic;
#define CHECK_HAPTIC_MAGIC(haptic, retval) \
if (!haptic || haptic->magic != &SDL_haptic_magic) { \
SDL_InvalidParamError("haptic"); \
return retval; \
}
/*
* Initializes the Haptic devices.
*/
int SDL_InitHaptics(void) int SDL_InitHaptics(void)
{ {
int status; int status;
@ -46,75 +45,82 @@ int SDL_InitHaptics(void)
return status; return status;
} }
/* static SDL_bool SDL_GetHapticIndex(SDL_HapticID instance_id, int *driver_index)
* Checks to see if the haptic device is valid
*/
static int ValidHaptic(SDL_Haptic *haptic)
{ {
int valid; int num_haptics, device_index;
SDL_Haptic *hapticlist;
valid = 0; if (instance_id > 0) {
if (haptic) { num_haptics = SDL_SYS_NumHaptics();
hapticlist = SDL_haptics; for (device_index = 0; device_index < num_haptics; ++device_index) {
while (hapticlist) { SDL_HapticID haptic_id = SDL_SYS_HapticInstanceID(device_index);
if (hapticlist == haptic) { if (haptic_id == instance_id) {
valid = 1; *driver_index = device_index;
break; return SDL_TRUE;
} }
hapticlist = hapticlist->next;
} }
} }
/* Create the error here. */ SDL_SetError("Haptic device %" SDL_PRIu32 " not found", instance_id);
if (valid == 0) { return SDL_FALSE;
SDL_SetError("Haptic: Invalid haptic device identifier"); }
SDL_HapticID *SDL_GetHaptics(int *count)
{
int device_index;
int haptic_index = 0, num_haptics = 0;
SDL_HapticID *haptics;
num_haptics = SDL_SYS_NumHaptics();
haptics = (SDL_HapticID *)SDL_malloc((num_haptics + 1) * sizeof(*haptics));
if (haptics) {
if (count) {
*count = num_haptics;
}
for (device_index = 0; device_index < num_haptics; ++device_index) {
haptics[haptic_index] = SDL_SYS_HapticInstanceID(device_index);
SDL_assert(haptics[haptic_index] > 0);
++haptic_index;
}
haptics[haptic_index] = 0;
} else {
if (count) {
*count = 0;
}
} }
return valid; return haptics;
} }
/* const char *SDL_GetHapticInstanceName(SDL_HapticID instance_id)
* Returns the number of available devices.
*/
int SDL_NumHaptics(void)
{ {
return SDL_SYS_NumHaptics(); int device_index;
} const char *name = NULL;
/* if (SDL_GetHapticIndex(instance_id, &device_index)) {
* Gets the name of a Haptic device by index. name = SDL_SYS_HapticName(device_index);
*/
const char *SDL_HapticName(int device_index)
{
if ((device_index < 0) || (device_index >= SDL_NumHaptics())) {
SDL_SetError("Haptic: There are %d haptic devices available",
SDL_NumHaptics());
return NULL;
} }
return SDL_SYS_HapticName(device_index); return name;
} }
/* SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id)
* Opens a Haptic device.
*/
SDL_Haptic *SDL_HapticOpen(int device_index)
{ {
SDL_Haptic *haptic; SDL_Haptic *haptic;
SDL_Haptic *hapticlist; SDL_Haptic *hapticlist;
const char *name;
int device_index = 0;
if ((device_index < 0) || (device_index >= SDL_NumHaptics())) { if (!SDL_GetHapticIndex(instance_id, &device_index)) {
SDL_SetError("Haptic: There are %d haptic devices available",
SDL_NumHaptics());
return NULL; return NULL;
} }
hapticlist = SDL_haptics; hapticlist = SDL_haptics;
/* If the haptic is already open, return it /* If the haptic device is already open, return it
* TODO: Should we create haptic instance IDs like the Joystick API? * it is important that we have a single haptic device for each instance id
*/ */
while (hapticlist) { while (hapticlist) {
if (device_index == hapticlist->index) { if (instance_id == hapticlist->instance_id) {
haptic = hapticlist; haptic = hapticlist;
++haptic->ref_count; ++haptic->ref_count;
return haptic; return haptic;
@ -123,20 +129,27 @@ SDL_Haptic *SDL_HapticOpen(int device_index)
} }
/* Create the haptic device */ /* Create the haptic device */
haptic = (SDL_Haptic *)SDL_malloc(sizeof(*haptic)); haptic = (SDL_Haptic *)SDL_calloc(1, sizeof(*haptic));
if (!haptic) { if (!haptic) {
return NULL; return NULL;
} }
/* Initialize the haptic device */ /* Initialize the haptic device */
SDL_memset(haptic, 0, sizeof(*haptic)); haptic->magic = &SDL_haptic_magic;
haptic->instance_id = instance_id;
haptic->rumble_id = -1; haptic->rumble_id = -1;
haptic->index = (Uint8)device_index;
if (SDL_SYS_HapticOpen(haptic) < 0) { if (SDL_SYS_HapticOpen(haptic) < 0) {
SDL_free(haptic); SDL_free(haptic);
return NULL; return NULL;
} }
if (!haptic->name) {
name = SDL_SYS_HapticName(device_index);
if (name) {
haptic->name = SDL_strdup(name);
}
}
/* Add haptic to list */ /* Add haptic to list */
++haptic->ref_count; ++haptic->ref_count;
/* Link the haptic in the list */ /* Link the haptic in the list */
@ -145,59 +158,42 @@ SDL_Haptic *SDL_HapticOpen(int device_index)
/* Disable autocenter and set gain to max. */ /* Disable autocenter and set gain to max. */
if (haptic->supported & SDL_HAPTIC_GAIN) { if (haptic->supported & SDL_HAPTIC_GAIN) {
SDL_HapticSetGain(haptic, 100); SDL_SetHapticGain(haptic, 100);
} }
if (haptic->supported & SDL_HAPTIC_AUTOCENTER) { if (haptic->supported & SDL_HAPTIC_AUTOCENTER) {
SDL_HapticSetAutocenter(haptic, 0); SDL_SetHapticAutocenter(haptic, 0);
} }
return haptic; return haptic;
} }
/* SDL_Haptic *SDL_GetHapticFromInstanceID(SDL_HapticID instance_id)
* Returns 1 if the device has been opened.
*/
int SDL_HapticOpened(int device_index)
{ {
int opened; SDL_Haptic *haptic;
SDL_Haptic *hapticlist;
/* Make sure it's valid. */ for (haptic = SDL_haptics; haptic; haptic = haptic->next) {
if ((device_index < 0) || (device_index >= SDL_NumHaptics())) { if (instance_id == haptic->instance_id) {
SDL_SetError("Haptic: There are %d haptic devices available",
SDL_NumHaptics());
return 0;
}
opened = 0;
hapticlist = SDL_haptics;
/* TODO Should this use an instance ID? */
while (hapticlist) {
if (hapticlist->index == (Uint8)device_index) {
opened = 1;
break; break;
} }
hapticlist = hapticlist->next;
} }
return opened; return haptic;
} }
/* SDL_HapticID SDL_GetHapticInstanceID(SDL_Haptic *haptic)
* Returns the index to a haptic device.
*/
int SDL_HapticIndex(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, 0);
return -1;
}
return haptic->index; return haptic->instance_id;
} }
/* const char *SDL_GetHapticName(SDL_Haptic *haptic)
* Returns SDL_TRUE if mouse is haptic, SDL_FALSE if it isn't. {
*/ CHECK_HAPTIC_MAGIC(haptic, 0);
int SDL_MouseIsHaptic(void)
return haptic->name;
}
SDL_bool SDL_IsMouseHaptic(void)
{ {
if (SDL_SYS_HapticMouse() < 0) { if (SDL_SYS_HapticMouse() < 0) {
return SDL_FALSE; return SDL_FALSE;
@ -205,10 +201,7 @@ int SDL_MouseIsHaptic(void)
return SDL_TRUE; return SDL_TRUE;
} }
/* SDL_Haptic *SDL_OpenHapticFromMouse(void)
* Returns the haptic device if mouse is haptic or NULL elsewise.
*/
SDL_Haptic *SDL_HapticOpenFromMouse(void)
{ {
int device_index; int device_index;
@ -219,52 +212,33 @@ SDL_Haptic *SDL_HapticOpenFromMouse(void)
return NULL; return NULL;
} }
return SDL_HapticOpen(device_index); return SDL_OpenHaptic(device_index);
} }
/* SDL_bool SDL_IsJoystickHaptic(SDL_Joystick *joystick)
* Returns SDL_TRUE if joystick has haptic features.
*/
int SDL_JoystickIsHaptic(SDL_Joystick *joystick)
{ {
int ret; SDL_bool result = SDL_FALSE;
SDL_LockJoysticks(); SDL_LockJoysticks();
{ {
/* Must be a valid joystick */ /* Must be a valid joystick */
if (!SDL_IsJoystickValid(joystick)) { if (SDL_IsJoystickValid(joystick) &&
SDL_UnlockJoysticks(); !SDL_IsGamepad(SDL_GetJoystickInstanceID(joystick))) {
return -1; if (SDL_SYS_JoystickIsHaptic(joystick) > 0) {
result = SDL_TRUE;
}
} }
ret = SDL_SYS_JoystickIsHaptic(joystick);
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
if (ret > 0) { return result;
return SDL_TRUE;
} else if (ret == 0) {
return SDL_FALSE;
}
return -1;
} }
/* SDL_Haptic *SDL_OpenHapticFromJoystick(SDL_Joystick *joystick)
* Opens a haptic device from a joystick.
*/
SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
{ {
SDL_Haptic *haptic; SDL_Haptic *haptic;
SDL_Haptic *hapticlist; SDL_Haptic *hapticlist;
/* Make sure there is room. */
if (SDL_NumHaptics() <= 0) {
SDL_SetError("Haptic: There are %d haptic devices available",
SDL_NumHaptics());
return NULL;
}
SDL_LockJoysticks(); SDL_LockJoysticks();
{ {
/* Must be a valid joystick */ /* Must be a valid joystick */
@ -275,7 +249,8 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
} }
/* Joystick must be haptic */ /* Joystick must be haptic */
if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) { if (SDL_IsGamepad(SDL_GetJoystickInstanceID(joystick)) ||
SDL_SYS_JoystickIsHaptic(joystick) <= 0) {
SDL_SetError("Haptic: Joystick isn't a haptic device."); SDL_SetError("Haptic: Joystick isn't a haptic device.");
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return NULL; return NULL;
@ -294,14 +269,15 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
} }
/* Create the haptic device */ /* Create the haptic device */
haptic = (SDL_Haptic *)SDL_malloc(sizeof(*haptic)); haptic = (SDL_Haptic *)SDL_calloc(1, sizeof(*haptic));
if (!haptic) { if (!haptic) {
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return NULL; return NULL;
} }
/* Initialize the haptic device */ /* Initialize the haptic device
SDL_memset(haptic, 0, sizeof(SDL_Haptic)); * This function should fill in the instance ID and name.
*/
haptic->rumble_id = -1; haptic->rumble_id = -1;
if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) { if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) {
SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed."); SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed.");
@ -309,6 +285,7 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return NULL; return NULL;
} }
SDL_assert(haptic->instance_id != 0);
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
@ -321,19 +298,13 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
return haptic; return haptic;
} }
/* void SDL_CloseHaptic(SDL_Haptic *haptic)
* Closes a SDL_Haptic device.
*/
void SDL_HapticClose(SDL_Haptic *haptic)
{ {
int i; int i;
SDL_Haptic *hapticlist; SDL_Haptic *hapticlist;
SDL_Haptic *hapticlistprev; SDL_Haptic *hapticlistprev;
/* Must be valid */ CHECK_HAPTIC_MAGIC(haptic,);
if (!ValidHaptic(haptic)) {
return;
}
/* Check if it's still in use */ /* Check if it's still in use */
if (--haptic->ref_count > 0) { if (--haptic->ref_count > 0) {
@ -343,10 +314,11 @@ void SDL_HapticClose(SDL_Haptic *haptic)
/* Close it, properly removing effects if needed */ /* Close it, properly removing effects if needed */
for (i = 0; i < haptic->neffects; i++) { for (i = 0; i < haptic->neffects; i++) {
if (haptic->effects[i].hweffect != NULL) { if (haptic->effects[i].hweffect != NULL) {
SDL_HapticDestroyEffect(haptic, i); SDL_DestroyHapticEffect(haptic, i);
} }
} }
SDL_SYS_HapticClose(haptic); SDL_SYS_HapticClose(haptic);
haptic->magic = NULL;
/* Remove from the list */ /* Remove from the list */
hapticlist = SDL_haptics; hapticlist = SDL_haptics;
@ -366,78 +338,51 @@ void SDL_HapticClose(SDL_Haptic *haptic)
hapticlist = hapticlist->next; hapticlist = hapticlist->next;
} }
/* Free */ /* Free the data associated with this device */
SDL_free(haptic->name);
SDL_free(haptic); SDL_free(haptic);
} }
/*
* Cleans up after the subsystem.
*/
void SDL_QuitHaptics(void) void SDL_QuitHaptics(void)
{ {
while (SDL_haptics) { while (SDL_haptics) {
SDL_HapticClose(SDL_haptics); SDL_CloseHaptic(SDL_haptics);
} }
SDL_SYS_HapticQuit(); SDL_SYS_HapticQuit();
} }
/* int SDL_GetMaxHapticEffects(SDL_Haptic *haptic)
* Returns the number of effects a haptic device has.
*/
int SDL_HapticNumEffects(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
return haptic->neffects; return haptic->neffects;
} }
/* int SDL_GetMaxHapticEffectsPlaying(SDL_Haptic *haptic)
* Returns the number of effects a haptic device can play.
*/
int SDL_HapticNumEffectsPlaying(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
return haptic->nplaying; return haptic->nplaying;
} }
/* unsigned int SDL_GetHapticFeatures(SDL_Haptic *haptic)
* Returns supported effects by the device.
*/
unsigned int SDL_HapticQuery(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, 0);
return 0; /* same as if no effects were supported */
}
return haptic->supported; return haptic->supported;
} }
/* int SDL_GetNumHapticAxes(SDL_Haptic *haptic)
* Returns the number of axis on the device.
*/
int SDL_HapticNumAxes(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
return haptic->naxes; return haptic->naxes;
} }
/* SDL_bool SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
* Checks to see if the device can support the effect.
*/
int SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, SDL_FALSE);
return -1;
}
if ((haptic->supported & effect->type) != 0) { if ((haptic->supported & effect->type) != 0) {
return SDL_TRUE; return SDL_TRUE;
@ -445,17 +390,11 @@ int SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
return SDL_FALSE; return SDL_FALSE;
} }
/* int SDL_CreateHapticEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
* Creates a new haptic effect.
*/
int SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
{ {
int i; int i;
/* Check for device validity. */ CHECK_HAPTIC_MAGIC(haptic, -1);
if (!ValidHaptic(haptic)) {
return -1;
}
/* Check to see if effect is supported */ /* Check to see if effect is supported */
if (SDL_HapticEffectSupported(haptic, effect) == SDL_FALSE) { if (SDL_HapticEffectSupported(haptic, effect) == SDL_FALSE) {
@ -480,9 +419,6 @@ int SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
return SDL_SetError("Haptic: Device has no free space left."); return SDL_SetError("Haptic: Device has no free space left.");
} }
/*
* Checks to see if an effect is valid.
*/
static int ValidEffect(SDL_Haptic *haptic, int effect) static int ValidEffect(SDL_Haptic *haptic, int effect)
{ {
if ((effect < 0) || (effect >= haptic->neffects)) { if ((effect < 0) || (effect >= haptic->neffects)) {
@ -492,13 +428,11 @@ static int ValidEffect(SDL_Haptic *haptic, int effect)
return 1; return 1;
} }
/* int SDL_UpdateHapticEffect(SDL_Haptic *haptic, int effect, SDL_HapticEffect *data)
* Updates an effect.
*/
int SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect,
SDL_HapticEffect *data)
{ {
if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { CHECK_HAPTIC_MAGIC(haptic, -1);
if (!ValidEffect(haptic, effect)) {
return -1; return -1;
} }
@ -518,12 +452,11 @@ int SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect,
return 0; return 0;
} }
/* int SDL_RunHapticEffect(SDL_Haptic *haptic, int effect, Uint32 iterations)
* Runs the haptic effect on the device.
*/
int SDL_HapticRunEffect(SDL_Haptic *haptic, int effect, Uint32 iterations)
{ {
if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { CHECK_HAPTIC_MAGIC(haptic, -1);
if (!ValidEffect(haptic, effect)) {
return -1; return -1;
} }
@ -535,12 +468,11 @@ int SDL_HapticRunEffect(SDL_Haptic *haptic, int effect, Uint32 iterations)
return 0; return 0;
} }
/* int SDL_StopHapticEffect(SDL_Haptic *haptic, int effect)
* Stops the haptic effect on the device.
*/
int SDL_HapticStopEffect(SDL_Haptic *haptic, int effect)
{ {
if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { CHECK_HAPTIC_MAGIC(haptic, -1);
if (!ValidEffect(haptic, effect)) {
return -1; return -1;
} }
@ -552,12 +484,11 @@ int SDL_HapticStopEffect(SDL_Haptic *haptic, int effect)
return 0; return 0;
} }
/* void SDL_DestroyHapticEffect(SDL_Haptic *haptic, int effect)
* Gets rid of a haptic effect.
*/
void SDL_HapticDestroyEffect(SDL_Haptic *haptic, int effect)
{ {
if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { CHECK_HAPTIC_MAGIC(haptic,);
if (!ValidEffect(haptic, effect)) {
return; return;
} }
@ -569,12 +500,11 @@ void SDL_HapticDestroyEffect(SDL_Haptic *haptic, int effect)
SDL_SYS_HapticDestroyEffect(haptic, &haptic->effects[effect]); SDL_SYS_HapticDestroyEffect(haptic, &haptic->effects[effect]);
} }
/* int SDL_GetHapticEffectStatus(SDL_Haptic *haptic, int effect)
* Gets the status of a haptic effect.
*/
int SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect)
{ {
if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { CHECK_HAPTIC_MAGIC(haptic, -1);
if (!ValidEffect(haptic, effect)) {
return -1; return -1;
} }
@ -585,17 +515,12 @@ int SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect)
return SDL_SYS_HapticGetEffectStatus(haptic, &haptic->effects[effect]); return SDL_SYS_HapticGetEffectStatus(haptic, &haptic->effects[effect]);
} }
/* int SDL_SetHapticGain(SDL_Haptic *haptic, int gain)
* Sets the global gain of the device.
*/
int SDL_HapticSetGain(SDL_Haptic *haptic, int gain)
{ {
const char *env; const char *env;
int real_gain, max_gain; int real_gain, max_gain;
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (!(haptic->supported & SDL_HAPTIC_GAIN)) { if (!(haptic->supported & SDL_HAPTIC_GAIN)) {
return SDL_SetError("Haptic: Device does not support setting gain."); return SDL_SetError("Haptic: Device does not support setting gain.");
@ -630,14 +555,9 @@ int SDL_HapticSetGain(SDL_Haptic *haptic, int gain)
return 0; return 0;
} }
/* int SDL_SetHapticAutocenter(SDL_Haptic *haptic, int autocenter)
* Makes the device autocenter, 0 disables.
*/
int SDL_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (!(haptic->supported & SDL_HAPTIC_AUTOCENTER)) { if (!(haptic->supported & SDL_HAPTIC_AUTOCENTER)) {
return SDL_SetError("Haptic: Device does not support setting autocenter."); return SDL_SetError("Haptic: Device does not support setting autocenter.");
@ -654,14 +574,9 @@ int SDL_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
return 0; return 0;
} }
/* int SDL_PauseHaptic(SDL_Haptic *haptic)
* Pauses the haptic device.
*/
int SDL_HapticPause(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (!(haptic->supported & SDL_HAPTIC_PAUSE)) { if (!(haptic->supported & SDL_HAPTIC_PAUSE)) {
return SDL_SetError("Haptic: Device does not support setting pausing."); return SDL_SetError("Haptic: Device does not support setting pausing.");
@ -670,14 +585,9 @@ int SDL_HapticPause(SDL_Haptic *haptic)
return SDL_SYS_HapticPause(haptic); return SDL_SYS_HapticPause(haptic);
} }
/* int SDL_ResumeHaptic(SDL_Haptic *haptic)
* Unpauses the haptic device.
*/
int SDL_HapticUnpause(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (!(haptic->supported & SDL_HAPTIC_PAUSE)) { if (!(haptic->supported & SDL_HAPTIC_PAUSE)) {
return 0; /* Not going to be paused, so we pretend it's unpaused. */ return 0; /* Not going to be paused, so we pretend it's unpaused. */
@ -686,41 +596,26 @@ int SDL_HapticUnpause(SDL_Haptic *haptic)
return SDL_SYS_HapticUnpause(haptic); return SDL_SYS_HapticUnpause(haptic);
} }
/* int SDL_StopHapticEffects(SDL_Haptic *haptic)
* Stops all the currently playing effects.
*/
int SDL_HapticStopAll(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
return SDL_SYS_HapticStopAll(haptic); return SDL_SYS_HapticStopAll(haptic);
} }
/* SDL_bool SDL_HapticRumbleSupported(SDL_Haptic *haptic)
* Checks to see if rumble is supported.
*/
int SDL_HapticRumbleSupported(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, SDL_FALSE);
return -1;
}
/* Most things can use SINE, but XInput only has LEFTRIGHT. */ /* Most things can use SINE, but XInput only has LEFTRIGHT. */
return (haptic->supported & (SDL_HAPTIC_SINE | SDL_HAPTIC_LEFTRIGHT)) != 0; return (haptic->supported & (SDL_HAPTIC_SINE | SDL_HAPTIC_LEFTRIGHT)) != 0;
} }
/* int SDL_InitHapticRumble(SDL_Haptic *haptic)
* Initializes the haptic device for simple rumble playback.
*/
int SDL_HapticRumbleInit(SDL_Haptic *haptic)
{ {
SDL_HapticEffect *efx = &haptic->rumble_effect; SDL_HapticEffect *efx = &haptic->rumble_effect;
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
/* Already allocated. */ /* Already allocated. */
if (haptic->rumble_id >= 0) { if (haptic->rumble_id >= 0) {
@ -745,24 +640,19 @@ int SDL_HapticRumbleInit(SDL_Haptic *haptic)
return SDL_SetError("Device doesn't support rumble"); return SDL_SetError("Device doesn't support rumble");
} }
haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect); haptic->rumble_id = SDL_CreateHapticEffect(haptic, &haptic->rumble_effect);
if (haptic->rumble_id >= 0) { if (haptic->rumble_id >= 0) {
return 0; return 0;
} }
return -1; return -1;
} }
/* int SDL_PlayHapticRumble(SDL_Haptic *haptic, float strength, Uint32 length)
* Runs simple rumble on a haptic device
*/
int SDL_HapticRumblePlay(SDL_Haptic *haptic, float strength, Uint32 length)
{ {
SDL_HapticEffect *efx; SDL_HapticEffect *efx;
Sint16 magnitude; Sint16 magnitude;
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (haptic->rumble_id < 0) { if (haptic->rumble_id < 0) {
return SDL_SetError("Haptic: Rumble effect not initialized on haptic device"); return SDL_SetError("Haptic: Rumble effect not initialized on haptic device");
@ -787,25 +677,20 @@ int SDL_HapticRumblePlay(SDL_Haptic *haptic, float strength, Uint32 length)
SDL_assert(0 && "This should have been caught elsewhere"); SDL_assert(0 && "This should have been caught elsewhere");
} }
if (SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect) < 0) { if (SDL_UpdateHapticEffect(haptic, haptic->rumble_id, &haptic->rumble_effect) < 0) {
return -1; return -1;
} }
return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1); return SDL_RunHapticEffect(haptic, haptic->rumble_id, 1);
} }
/* int SDL_StopHapticRumble(SDL_Haptic *haptic)
* Stops the simple rumble on a haptic device.
*/
int SDL_HapticRumbleStop(SDL_Haptic *haptic)
{ {
if (!ValidHaptic(haptic)) { CHECK_HAPTIC_MAGIC(haptic, -1);
return -1;
}
if (haptic->rumble_id < 0) { if (haptic->rumble_id < 0) {
return SDL_SetError("Haptic: Rumble effect not initialized on haptic device"); return SDL_SetError("Haptic: Rumble effect not initialized on haptic device");
} }
return SDL_HapticStopEffect(haptic, haptic->rumble_id); return SDL_StopHapticEffect(haptic, haptic->rumble_id);
} }

View File

@ -40,20 +40,23 @@ struct haptic_effect
*/ */
struct SDL_Haptic struct SDL_Haptic
{ {
Uint8 index; /* Stores index it is attached to */ const void *magic;
struct haptic_effect *effects; /* Allocated effects */ SDL_HapticID instance_id; /* Device instance, monotonically increasing from 0 */
int neffects; /* Maximum amount of effects */ char *name; /* Device name - system dependent */
int nplaying; /* Maximum amount of effects to play at the same time */
unsigned int supported; /* Supported effects */
int naxes; /* Number of axes on the device. */
struct haptic_hwdata *hwdata; /* Driver dependent */ struct haptic_effect *effects; /* Allocated effects */
int ref_count; /* Count for multiple opens */ int neffects; /* Maximum amount of effects */
int nplaying; /* Maximum amount of effects to play at the same time */
unsigned int supported; /* Supported effects */
int naxes; /* Number of axes on the device. */
struct haptic_hwdata *hwdata; /* Driver dependent */
int ref_count; /* Count for multiple opens */
int rumble_id; /* ID of rumble effect for simple rumble API. */ int rumble_id; /* ID of rumble effect for simple rumble API. */
SDL_HapticEffect rumble_effect; /* Rumble effect. */ SDL_HapticEffect rumble_effect; /* Rumble effect. */
struct SDL_Haptic *next; /* pointer to next haptic we have allocated */ struct SDL_Haptic *next; /* pointer to next haptic we have allocated */
}; };
/* /*
@ -66,6 +69,11 @@ extern int SDL_SYS_HapticInit(void);
/* Function to return the number of haptic devices plugged in right now */ /* Function to return the number of haptic devices plugged in right now */
extern int SDL_SYS_NumHaptics(void); extern int SDL_SYS_NumHaptics(void);
/*
* Gets the instance ID of the haptic device
*/
extern SDL_HapticID SDL_SYS_HapticInstanceID(int index);
/* /*
* Gets the device dependent name of the haptic device * Gets the device dependent name of the haptic device
*/ */

View File

@ -30,6 +30,7 @@
typedef struct SDL_hapticlist_item typedef struct SDL_hapticlist_item
{ {
SDL_HapticID instance_id;
int device_id; int device_id;
char *name; char *name;
SDL_Haptic *haptic; SDL_Haptic *haptic;
@ -66,6 +67,17 @@ static SDL_hapticlist_item *HapticByOrder(int index)
return item; return item;
} }
static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id)
{
SDL_hapticlist_item *item;
for (item = SDL_hapticlist; item; item = item->next) {
if (instance_id == item->instance_id) {
return item;
}
}
return NULL;
}
static SDL_hapticlist_item *HapticByDevId(int device_id) static SDL_hapticlist_item *HapticByDevId(int device_id)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
@ -78,6 +90,15 @@ static SDL_hapticlist_item *HapticByDevId(int device_id)
return NULL; return NULL;
} }
SDL_HapticID SDL_SYS_HapticInstanceID(int index)
{
SDL_hapticlist_item *item = HapticByOrder(index);
if (item) {
return item->instance_id;
}
return 0;
}
const char *SDL_SYS_HapticName(int index) const char *SDL_SYS_HapticName(int index)
{ {
SDL_hapticlist_item *item = HapticByOrder(index); SDL_hapticlist_item *item = HapticByOrder(index);
@ -102,20 +123,23 @@ static SDL_hapticlist_item *OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *
haptic->hwdata = (struct haptic_hwdata *)item; haptic->hwdata = (struct haptic_hwdata *)item;
item->haptic = haptic; item->haptic = haptic;
haptic->instance_id = item->instance_id;
if (item->name) {
haptic->name = SDL_strdup(item->name);
}
haptic->supported = SDL_HAPTIC_LEFTRIGHT; haptic->supported = SDL_HAPTIC_LEFTRIGHT;
haptic->neffects = 1; haptic->neffects = 1;
haptic->nplaying = haptic->neffects; haptic->nplaying = haptic->neffects;
haptic->effects = (struct haptic_effect *)SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); haptic->effects = (struct haptic_effect *)SDL_calloc(haptic->neffects, sizeof(struct haptic_effect));
if (!haptic->effects) { if (!haptic->effects) {
return NULL; return NULL;
} }
SDL_memset(haptic->effects, 0, sizeof(struct haptic_effect) * haptic->neffects);
return item; return item;
} }
static SDL_hapticlist_item *OpenHapticByOrder(SDL_Haptic *haptic, int index) static SDL_hapticlist_item *OpenHapticByInstanceID(SDL_Haptic *haptic, SDL_HapticID instance_id)
{ {
return OpenHaptic(haptic, HapticByOrder(index)); return OpenHaptic(haptic, HapticByInstanceID(instance_id));
} }
static SDL_hapticlist_item *OpenHapticByDevId(SDL_Haptic *haptic, int device_id) static SDL_hapticlist_item *OpenHapticByDevId(SDL_Haptic *haptic, int device_id)
@ -125,7 +149,7 @@ static SDL_hapticlist_item *OpenHapticByDevId(SDL_Haptic *haptic, int device_id)
int SDL_SYS_HapticOpen(SDL_Haptic *haptic) int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
{ {
return OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0; return OpenHapticByInstanceID(haptic, haptic->instance_id) == NULL ? -1 : 0;
} }
int SDL_SYS_HapticMouse(void) int SDL_SYS_HapticMouse(void)
@ -249,6 +273,7 @@ int Android_AddHaptic(int device_id, const char *name)
return -1; return -1;
} }
item->instance_id = SDL_GetNextObjectID();
item->device_id = device_id; item->device_id = device_id;
item->name = SDL_strdup(name); item->name = SDL_strdup(name);
if (!item->name) { if (!item->name) {
@ -275,7 +300,7 @@ int Android_RemoveHaptic(int device_id)
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
/* found it, remove it. */ /* found it, remove it. */
if (device_id == item->device_id) { if (device_id == item->device_id) {
const int retval = item->haptic ? item->haptic->index : -1; const int retval = item->haptic ? 0 : -1;
if (prev) { if (prev) {
prev->next = item->next; prev->next = item->next;

View File

@ -42,6 +42,7 @@
*/ */
typedef struct SDL_hapticlist_item typedef struct SDL_hapticlist_item
{ {
SDL_HapticID instance_id;
char name[256]; /* Name of the device. */ char name[256]; /* Name of the device. */
io_service_t dev; /* Node we use to create the device. */ io_service_t dev; /* Node we use to create the device. */
@ -201,6 +202,17 @@ static SDL_hapticlist_item *HapticByDevIndex(int device_index)
return item; return item;
} }
static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id)
{
SDL_hapticlist_item *item;
for (item = SDL_hapticlist; item; item = item->next) {
if (instance_id == item->instance_id) {
return item;
}
}
return NULL;
}
int MacHaptic_MaybeAddDevice(io_object_t device) int MacHaptic_MaybeAddDevice(io_object_t device)
{ {
IOReturn result; IOReturn result;
@ -229,6 +241,7 @@ int MacHaptic_MaybeAddDevice(io_object_t device)
if (!item) { if (!item) {
return SDL_SetError("Could not allocate haptic storage"); return SDL_SetError("Could not allocate haptic storage");
} }
item->instance_id = SDL_GetNextObjectID();
/* retain it as we are going to keep it around a while */ /* retain it as we are going to keep it around a while */
IOObjectRetain(device); IOObjectRetain(device);
@ -287,7 +300,7 @@ int MacHaptic_MaybeRemoveDevice(io_object_t device)
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
/* found it, remove it. */ /* found it, remove it. */
if (IOObjectIsEqualTo((io_object_t)item->dev, device)) { if (IOObjectIsEqualTo((io_object_t)item->dev, device)) {
const int retval = item->haptic ? item->haptic->index : -1; const int retval = item->haptic ? 0 : -1;
if (prev) { if (prev) {
prev->next = item->next; prev->next = item->next;
@ -313,6 +326,16 @@ int MacHaptic_MaybeRemoveDevice(io_object_t device)
return -1; return -1;
} }
SDL_HapticID SDL_SYS_HapticInstanceID(int index)
{
SDL_hapticlist_item *item;
item = HapticByDevIndex(index);
if (item) {
return item->instance_id;
}
return 0;
}
/* /*
* Return the name of a haptic device, does not need to be opened. * Return the name of a haptic device, does not need to be opened.
*/ */
@ -320,7 +343,10 @@ const char *SDL_SYS_HapticName(int index)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
item = HapticByDevIndex(index); item = HapticByDevIndex(index);
return item->name; if (item) {
return item->name;
}
return NULL;
} }
/* /*
@ -535,7 +561,7 @@ creat_err:
int SDL_SYS_HapticOpen(SDL_Haptic *haptic) int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
item = HapticByDevIndex(haptic->index); item = HapticByInstanceID(haptic->instance_id);
return SDL_SYS_HapticOpenFromService(haptic, item->dev); return SDL_SYS_HapticOpenFromService(haptic, item->dev);
} }
@ -598,7 +624,6 @@ int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{ {
#ifdef SDL_JOYSTICK_IOKIT #ifdef SDL_JOYSTICK_IOKIT
int device_index = 0;
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
if (joystick->driver != &SDL_DARWIN_JoystickDriver) { if (joystick->driver != &SDL_DARWIN_JoystickDriver) {
@ -607,10 +632,13 @@ int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
if (IOObjectIsEqualTo((io_object_t)item->dev, if (IOObjectIsEqualTo((io_object_t)item->dev,
joystick->hwdata->ffservice)) { joystick->hwdata->ffservice)) {
haptic->index = device_index; haptic->instance_id = item->instance_id;
break; break;
} }
++device_index; }
if (joystick->name) {
haptic->name = SDL_strdup(joystick->name);
} }
return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice); return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice);

View File

@ -39,6 +39,12 @@ int SDL_SYS_NumHaptics(void)
return 0; return 0;
} }
SDL_HapticID SDL_SYS_HapticInstanceID(int index)
{
SDL_SYS_LogicError();
return 0;
}
const char *SDL_SYS_HapticName(int index) const char *SDL_SYS_HapticName(int index)
{ {
SDL_SYS_LogicError(); SDL_SYS_LogicError();

View File

@ -49,6 +49,7 @@ static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class,
*/ */
typedef struct SDL_hapticlist_item typedef struct SDL_hapticlist_item
{ {
SDL_HapticID instance_id;
char *fname; /* Dev path name (like /dev/input/event1) */ char *fname; /* Dev path name (like /dev/input/event1) */
SDL_Haptic *haptic; /* Associated haptic. */ SDL_Haptic *haptic; /* Associated haptic. */
dev_t dev_num; dev_t dev_num;
@ -196,6 +197,17 @@ static SDL_hapticlist_item *HapticByDevIndex(int device_index)
return item; return item;
} }
static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id)
{
SDL_hapticlist_item *item;
for (item = SDL_hapticlist; item; item = item->next) {
if (instance_id == item->instance_id) {
return item;
}
}
return NULL;
}
#ifdef SDL_USE_LIBUDEV #ifdef SDL_USE_LIBUDEV
static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
{ {
@ -263,6 +275,7 @@ static int MaybeAddDevice(const char *path)
return -1; return -1;
} }
item->instance_id = SDL_GetNextObjectID();
item->fname = SDL_strdup(path); item->fname = SDL_strdup(path);
if (!item->fname) { if (!item->fname) {
SDL_free(item); SDL_free(item);
@ -299,7 +312,7 @@ static int MaybeRemoveDevice(const char *path)
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
/* found it, remove it. */ /* found it, remove it. */
if (SDL_strcmp(path, item->fname) == 0) { if (SDL_strcmp(path, item->fname) == 0) {
const int retval = item->haptic ? item->haptic->index : -1; const int retval = item->haptic ? 0 : -1;
if (prev) { if (prev) {
prev->next = item->next; prev->next = item->next;
@ -326,6 +339,20 @@ static int MaybeRemoveDevice(const char *path)
} }
#endif /* SDL_USE_LIBUDEV */ #endif /* SDL_USE_LIBUDEV */
/*
* Return the instance ID of a haptic device, does not need to be opened.
*/
SDL_HapticID SDL_SYS_HapticInstanceID(int index)
{
SDL_hapticlist_item *item;
item = HapticByDevIndex(index);
if (item) {
return item->instance_id;
}
return 0;
}
/* /*
* Gets the name from a file descriptor. * Gets the name from a file descriptor.
*/ */
@ -348,23 +375,23 @@ const char *SDL_SYS_HapticName(int index)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
int fd; int fd;
const char *name; const char *name = NULL;
item = HapticByDevIndex(index); item = HapticByDevIndex(index);
/* Open the haptic device. */ if (item) {
name = NULL; /* Open the haptic device. */
fd = open(item->fname, O_RDONLY | O_CLOEXEC, 0); fd = open(item->fname, O_RDONLY | O_CLOEXEC, 0);
if (fd >= 0) { if (fd >= 0) {
name = SDL_SYS_HapticNameFromFD(fd); name = SDL_SYS_HapticNameFromFD(fd);
if (!name) { if (!name) {
/* No name found, return device character device */ /* No name found, return device character device */
name = item->fname; name = item->fname;
}
close(fd);
} }
close(fd);
} }
return name; return name;
} }
@ -422,7 +449,7 @@ int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
int ret; int ret;
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
item = HapticByDevIndex(haptic->index); item = HapticByInstanceID(haptic->instance_id);
/* Open the character device */ /* Open the character device */
fd = open(item->fname, O_RDWR | O_CLOEXEC, 0); fd = open(item->fname, O_RDWR | O_CLOEXEC, 0);
if (fd < 0) { if (fd < 0) {
@ -516,10 +543,10 @@ int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{ {
#ifdef SDL_JOYSTICK_LINUX #ifdef SDL_JOYSTICK_LINUX
int device_index = 0;
int fd; int fd;
int ret; int ret;
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
const char *name;
SDL_AssertJoysticksLocked(); SDL_AssertJoysticksLocked();
@ -529,14 +556,9 @@ int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
/* Find the joystick in the haptic list. */ /* Find the joystick in the haptic list. */
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
if (SDL_strcmp(item->fname, joystick->hwdata->fname) == 0) { if (SDL_strcmp(item->fname, joystick->hwdata->fname) == 0) {
haptic->instance_id = item->instance_id;
break; break;
} }
++device_index;
}
haptic->index = device_index;
if (device_index >= MAX_HAPTICS) {
return SDL_SetError("Haptic: Joystick doesn't have Haptic capabilities");
} }
fd = open(joystick->hwdata->fname, O_RDWR | O_CLOEXEC, 0); fd = open(joystick->hwdata->fname, O_RDWR | O_CLOEXEC, 0);
@ -551,6 +573,10 @@ int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
haptic->hwdata->fname = SDL_strdup(joystick->hwdata->fname); haptic->hwdata->fname = SDL_strdup(joystick->hwdata->fname);
name = SDL_SYS_HapticNameFromFD(fd);
if (name) {
haptic->name = SDL_strdup(name);
}
return 0; return 0;
#else #else
return -1; return -1;

View File

@ -139,7 +139,7 @@ int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance)
/* Make sure we don't already have it */ /* Make sure we don't already have it */
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
if ((!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0)) { if (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) {
return -1; /* Already added */ return -1; /* Already added */
} }
} }
@ -170,6 +170,7 @@ int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance)
return -1; return -1;
} }
item->instance_id = SDL_GetNextObjectID();
item->name = WIN_StringToUTF8(pdidInstance->tszProductName); item->name = WIN_StringToUTF8(pdidInstance->tszProductName);
if (!item->name) { if (!item->name) {
SDL_free(item); SDL_free(item);
@ -193,7 +194,7 @@ int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance)
} }
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
if (!item->bXInputHaptic && SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) { if (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) {
/* found it, remove it. */ /* found it, remove it. */
return SDL_SYS_RemoveHapticDevice(prev, item); return SDL_SYS_RemoveHapticDevice(prev, item);
} }
@ -298,7 +299,7 @@ static int SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic *haptic, LPDIRECTINPUTDEVI
/* !!! FIXME: opening a haptic device here first will make an attempt to /* !!! FIXME: opening a haptic device here first will make an attempt to
!!! FIXME: SDL_OpenJoystick() that same device fail later, since we !!! FIXME: SDL_OpenJoystick() that same device fail later, since we
!!! FIXME: have it open in exclusive mode. But this will allow !!! FIXME: have it open in exclusive mode. But this will allow
!!! FIXME: SDL_OpenJoystick() followed by SDL_HapticOpenFromJoystick() !!! FIXME: SDL_OpenJoystick() followed by SDL_OpenHapticFromJoystick()
!!! FIXME: to work, and that's probably the common case. Still, !!! FIXME: to work, and that's probably the common case. Still,
!!! FIXME: ideally, We need to unify the opening code. */ !!! FIXME: ideally, We need to unify the opening code. */
@ -461,7 +462,6 @@ int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
Uint8 index = 0;
HRESULT ret; HRESULT ret;
DIDEVICEINSTANCE joy_instance; DIDEVICEINSTANCE joy_instance;
@ -473,11 +473,11 @@ int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick
/* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */ /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
for (item = SDL_hapticlist; item; item = item->next) { for (item = SDL_hapticlist; item; item = item->next) {
if (!item->bXInputHaptic && WIN_IsEqualGUID(&item->instance.guidInstance, &joy_instance.guidInstance)) { if (WIN_IsEqualGUID(&item->instance.guidInstance, &joy_instance.guidInstance)) {
haptic->index = index; haptic->instance_id = item->instance_id;
haptic->name = SDL_strdup(item->name);
return SDL_DINPUT_HapticOpenFromDevice(haptic, joystick->hwdata->InputDevice, SDL_TRUE); return SDL_DINPUT_HapticOpenFromDevice(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
} }
++index;
} }
return SDL_SetError("Couldn't find joystick in haptic device list"); return SDL_SetError("Couldn't find joystick in haptic device list");

View File

@ -20,7 +20,7 @@
*/ */
#include "SDL_internal.h" #include "SDL_internal.h"
#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) #ifdef SDL_HAPTIC_DINPUT
#include "../SDL_syshaptic.h" #include "../SDL_syshaptic.h"
#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
@ -29,7 +29,6 @@
#include "SDL_windowshaptic_c.h" #include "SDL_windowshaptic_c.h"
#include "SDL_dinputhaptic_c.h" #include "SDL_dinputhaptic_c.h"
#include "SDL_xinputhaptic_c.h"
/* Set up for C function definitions, even when using C++ */ /* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
@ -53,9 +52,6 @@ int SDL_SYS_HapticInit(void)
if (SDL_DINPUT_HapticInit() < 0) { if (SDL_DINPUT_HapticInit() < 0) {
return -1; return -1;
} }
if (SDL_XINPUT_HapticInit() < 0) {
return -1;
}
/* The joystick subsystem will usually be initialized before haptics, /* The joystick subsystem will usually be initialized before haptics,
* so the initial HapticMaybeAddDevice() calls from the joystick * so the initial HapticMaybeAddDevice() calls from the joystick
@ -63,11 +59,7 @@ int SDL_SYS_HapticInit(void)
* invoke those callbacks again here to pick up any joysticks that * invoke those callbacks again here to pick up any joysticks that
* were added prior to haptics initialization. */ * were added prior to haptics initialization. */
for (device = SYS_Joystick; device; device = device->pNext) { for (device = SYS_Joystick; device; device = device->pNext) {
if (device->bXInputDevice) { SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice);
SDL_XINPUT_HapticMaybeAddDevice(device->XInputUserId);
} else {
SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice);
}
} }
return numhaptics; return numhaptics;
@ -90,7 +82,7 @@ int SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item)
int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item) int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item)
{ {
const int retval = item->haptic ? item->haptic->index : -1; const int retval = item->haptic ? 0 : -1;
if (prev) { if (prev) {
prev->next = item->next; prev->next = item->next;
} else { } else {
@ -127,6 +119,26 @@ static SDL_hapticlist_item *HapticByDevIndex(int device_index)
return item; return item;
} }
static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id)
{
SDL_hapticlist_item *item;
for (item = SDL_hapticlist; item; item = item->next) {
if (instance_id == item->instance_id) {
return item;
}
}
return NULL;
}
SDL_HapticID SDL_SYS_HapticInstanceID(int index)
{
SDL_hapticlist_item *item = HapticByDevIndex(index);
if (item) {
return item->instance_id;
}
return 0;
}
/* /*
* Return the name of a haptic device, does not need to be opened. * Return the name of a haptic device, does not need to be opened.
*/ */
@ -141,12 +153,8 @@ const char *SDL_SYS_HapticName(int index)
*/ */
int SDL_SYS_HapticOpen(SDL_Haptic *haptic) int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
{ {
SDL_hapticlist_item *item = HapticByDevIndex(haptic->index); SDL_hapticlist_item *item = HapticByInstanceID(haptic->instance_id);
if (item->bXInputHaptic) { return SDL_DINPUT_HapticOpen(haptic, item);
return SDL_XINPUT_HapticOpen(haptic, item);
} else {
return SDL_DINPUT_HapticOpen(haptic, item);
}
} }
/* /*
@ -177,16 +185,9 @@ int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { if (joystick->driver != &SDL_WINDOWS_JoystickDriver) {
return 0; return 0;
} }
#ifdef SDL_HAPTIC_XINPUT
if (joystick->hwdata->bXInputHaptic) {
return 1;
}
#endif
#ifdef SDL_HAPTIC_DINPUT
if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
return 1; return 1;
} }
#endif
return 0; return 0;
} }
@ -198,13 +199,7 @@ int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { if (joystick->driver != &SDL_WINDOWS_JoystickDriver) {
return 0; return 0;
} }
if (joystick->hwdata->bXInputHaptic != haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_JoystickSameHaptic(haptic, joystick);
return 0; /* one is XInput, one is not; not the same device. */
} else if (joystick->hwdata->bXInputHaptic) {
return SDL_XINPUT_JoystickSameHaptic(haptic, joystick);
} else {
return SDL_DINPUT_JoystickSameHaptic(haptic, joystick);
}
} }
/* /*
@ -214,11 +209,7 @@ int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{ {
SDL_assert(joystick->driver == &SDL_WINDOWS_JoystickDriver); SDL_assert(joystick->driver == &SDL_WINDOWS_JoystickDriver);
if (joystick->hwdata->bXInputDevice) { return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick);
return SDL_XINPUT_HapticOpenFromJoystick(haptic, joystick);
} else {
return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick);
}
} }
/* /*
@ -234,11 +225,7 @@ void SDL_SYS_HapticClose(SDL_Haptic *haptic)
haptic->neffects = 0; haptic->neffects = 0;
/* Clean up */ /* Clean up */
if (haptic->hwdata->bXInputHaptic) { SDL_DINPUT_HapticClose(haptic);
SDL_XINPUT_HapticClose(haptic);
} else {
SDL_DINPUT_HapticClose(haptic);
}
/* Free */ /* Free */
SDL_free(haptic->hwdata); SDL_free(haptic->hwdata);
@ -253,17 +240,6 @@ void SDL_SYS_HapticQuit(void)
{ {
SDL_hapticlist_item *item; SDL_hapticlist_item *item;
SDL_hapticlist_item *next = NULL; SDL_hapticlist_item *next = NULL;
SDL_Haptic *hapticitem = NULL;
extern SDL_Haptic *SDL_haptics;
for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
/* we _have_ to stop the thread before we free the XInput DLL! */
SDL_AtomicSet(&hapticitem->hwdata->stopThread, 1);
SDL_WaitThread(hapticitem->hwdata->thread, NULL);
hapticitem->hwdata->thread = NULL;
}
}
for (item = SDL_hapticlist; item; item = next) { for (item = SDL_hapticlist; item; item = next) {
/* Opened and not closed haptics are leaked, this is on purpose. /* Opened and not closed haptics are leaked, this is on purpose.
@ -274,7 +250,6 @@ void SDL_SYS_HapticQuit(void)
SDL_free(item); SDL_free(item);
} }
SDL_XINPUT_HapticQuit();
SDL_DINPUT_HapticQuit(); SDL_DINPUT_HapticQuit();
numhaptics = 0; numhaptics = 0;
@ -296,11 +271,7 @@ int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect,
return -1; return -1;
} }
if (haptic->hwdata->bXInputHaptic) { result = SDL_DINPUT_HapticNewEffect(haptic, effect, base);
result = SDL_XINPUT_HapticNewEffect(haptic, effect, base);
} else {
result = SDL_DINPUT_HapticNewEffect(haptic, effect, base);
}
if (result < 0) { if (result < 0) {
SDL_free(effect->hweffect); SDL_free(effect->hweffect);
effect->hweffect = NULL; effect->hweffect = NULL;
@ -311,28 +282,17 @@ int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect,
/* /*
* Updates an effect. * Updates an effect.
*/ */
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
struct haptic_effect *effect,
SDL_HapticEffect *data)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data);
return SDL_XINPUT_HapticUpdateEffect(haptic, effect, data);
} else {
return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data);
}
} }
/* /*
* Runs an effect. * Runs an effect.
*/ */
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
Uint32 iterations)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations);
return SDL_XINPUT_HapticRunEffect(haptic, effect, iterations);
} else {
return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations);
}
} }
/* /*
@ -340,11 +300,7 @@ int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect,
*/ */
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticStopEffect(haptic, effect);
return SDL_XINPUT_HapticStopEffect(haptic, effect);
} else {
return SDL_DINPUT_HapticStopEffect(haptic, effect);
}
} }
/* /*
@ -352,11 +308,7 @@ int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
*/ */
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{ {
if (haptic->hwdata->bXInputHaptic) { SDL_DINPUT_HapticDestroyEffect(haptic, effect);
SDL_XINPUT_HapticDestroyEffect(haptic, effect);
} else {
SDL_DINPUT_HapticDestroyEffect(haptic, effect);
}
SDL_free(effect->hweffect); SDL_free(effect->hweffect);
effect->hweffect = NULL; effect->hweffect = NULL;
} }
@ -364,14 +316,9 @@ void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effec
/* /*
* Gets the status of a haptic effect. * Gets the status of a haptic effect.
*/ */
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
struct haptic_effect *effect)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticGetEffectStatus(haptic, effect);
return SDL_XINPUT_HapticGetEffectStatus(haptic, effect);
} else {
return SDL_DINPUT_HapticGetEffectStatus(haptic, effect);
}
} }
/* /*
@ -379,11 +326,7 @@ int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic,
*/ */
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticSetGain(haptic, gain);
return SDL_XINPUT_HapticSetGain(haptic, gain);
} else {
return SDL_DINPUT_HapticSetGain(haptic, gain);
}
} }
/* /*
@ -391,11 +334,7 @@ int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
*/ */
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter);
return SDL_XINPUT_HapticSetAutocenter(haptic, autocenter);
} else {
return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter);
}
} }
/* /*
@ -403,11 +342,7 @@ int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
*/ */
int SDL_SYS_HapticPause(SDL_Haptic *haptic) int SDL_SYS_HapticPause(SDL_Haptic *haptic)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticPause(haptic);
return SDL_XINPUT_HapticPause(haptic);
} else {
return SDL_DINPUT_HapticPause(haptic);
}
} }
/* /*
@ -415,11 +350,7 @@ int SDL_SYS_HapticPause(SDL_Haptic *haptic)
*/ */
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticUnpause(haptic);
return SDL_XINPUT_HapticUnpause(haptic);
} else {
return SDL_DINPUT_HapticUnpause(haptic);
}
} }
/* /*
@ -427,11 +358,7 @@ int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
*/ */
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
{ {
if (haptic->hwdata->bXInputHaptic) { return SDL_DINPUT_HapticStopAll(haptic);
return SDL_XINPUT_HapticStopAll(haptic);
} else {
return SDL_DINPUT_HapticStopAll(haptic);
}
} }
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
@ -439,4 +366,4 @@ int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
} }
#endif #endif
#endif /* SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT */ #endif /* SDL_HAPTIC_DINPUT */

View File

@ -42,8 +42,6 @@ struct haptic_hwdata
#endif #endif
DWORD axes[3]; /* Axes to use. */ DWORD axes[3]; /* Axes to use. */
SDL_bool is_joystick; /* Device is loaded as joystick. */ SDL_bool is_joystick; /* Device is loaded as joystick. */
Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
Uint8 userid; /* XInput userid index for this joystick */
SDL_Thread *thread; SDL_Thread *thread;
SDL_Mutex *mutex; SDL_Mutex *mutex;
Uint64 stopTicks; Uint64 stopTicks;
@ -53,16 +51,11 @@ struct haptic_hwdata
/* /*
* Haptic system effect data. * Haptic system effect data.
*/ */
#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) #ifdef SDL_HAPTIC_DINPUT
struct haptic_hweffect struct haptic_hweffect
{ {
#ifdef SDL_HAPTIC_DINPUT
DIEFFECT effect; DIEFFECT effect;
LPDIRECTINPUTEFFECT ref; LPDIRECTINPUTEFFECT ref;
#endif
#ifdef SDL_HAPTIC_XINPUT
XINPUT_VIBRATION vibration;
#endif
}; };
#endif #endif
@ -71,14 +64,13 @@ struct haptic_hweffect
*/ */
typedef struct SDL_hapticlist_item typedef struct SDL_hapticlist_item
{ {
SDL_HapticID instance_id;
char *name; char *name;
SDL_Haptic *haptic; SDL_Haptic *haptic;
#ifdef SDL_HAPTIC_DINPUT #ifdef SDL_HAPTIC_DINPUT
DIDEVICEINSTANCE instance; DIDEVICEINSTANCE instance;
DIDEVCAPS capabilities; DIDEVCAPS capabilities;
#endif #endif
SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */
Uint8 userid; /* XInput userid index for this joystick */
struct SDL_hapticlist_item *next; struct SDL_hapticlist_item *next;
} SDL_hapticlist_item; } SDL_hapticlist_item;

View File

@ -1,443 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "../SDL_syshaptic.h"
#ifdef SDL_HAPTIC_XINPUT
#include "SDL_windowshaptic_c.h"
#include "SDL_xinputhaptic_c.h"
#include "../../core/windows/SDL_xinput.h"
#include "../../joystick/windows/SDL_windowsjoystick_c.h"
#include "../../thread/SDL_systhread.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Internal stuff.
*/
static SDL_bool loaded_xinput = SDL_FALSE;
int SDL_XINPUT_HapticInit(void)
{
if (SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE)) {
loaded_xinput = (WIN_LoadXInputDLL() == 0);
}
/* If the joystick subsystem is active, it will manage adding XInput haptic devices */
if (loaded_xinput && !SDL_WasInit(SDL_INIT_JOYSTICK)) {
DWORD i;
for (i = 0; i < XUSER_MAX_COUNT; i++) {
SDL_XINPUT_HapticMaybeAddDevice(i);
}
}
return 0;
}
int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid)
{
const Uint8 userid = (Uint8)dwUserid;
SDL_hapticlist_item *item;
XINPUT_VIBRATION state;
if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
return -1;
}
/* Make sure we don't already have it */
for (item = SDL_hapticlist; item; item = item->next) {
if (item->bXInputHaptic && item->userid == userid) {
return -1; /* Already added */
}
}
SDL_zero(state);
if (XINPUTSETSTATE(dwUserid, &state) != ERROR_SUCCESS) {
return -1; /* no force feedback on this device. */
}
item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item));
if (!item) {
return -1;
}
/* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */
{
char buf[64];
(void)SDL_snprintf(buf, sizeof(buf), "XInput Controller #%d", 1 + userid);
item->name = SDL_strdup(buf);
}
if (!item->name) {
SDL_free(item);
return -1;
}
/* Copy the instance over, useful for creating devices. */
item->bXInputHaptic = SDL_TRUE;
item->userid = userid;
return SDL_SYS_AddHapticDevice(item);
}
int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid)
{
const Uint8 userid = (Uint8)dwUserid;
SDL_hapticlist_item *item;
SDL_hapticlist_item *prev = NULL;
if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
return -1;
}
for (item = SDL_hapticlist; item; item = item->next) {
if (item->bXInputHaptic && item->userid == userid) {
/* found it, remove it. */
return SDL_SYS_RemoveHapticDevice(prev, item);
}
prev = item;
}
return -1;
}
/* !!! FIXME: this is a hack, remove this later. */
/* Since XInput doesn't offer a way to vibrate for X time, we hook into
* SDL_PumpEvents() to check if it's time to stop vibrating with some
* frequency.
* In practice, this works for 99% of use cases. But in an ideal world,
* we do this in a separate thread so that:
* - we aren't bound to when the app chooses to pump the event queue.
* - we aren't adding more polling to the event queue
* - we can emulate all the haptic effects correctly (start on a delay,
* mix multiple effects, etc).
*
* Mostly, this is here to get rumbling to work, and all the other features
* are absent in the XInput path for now. :(
*/
static int SDLCALL SDL_RunXInputHaptic(void *arg)
{
struct haptic_hwdata *hwdata = (struct haptic_hwdata *)arg;
while (!SDL_AtomicGet(&hwdata->stopThread)) {
SDL_Delay(50);
SDL_LockMutex(hwdata->mutex);
/* If we're currently running and need to stop... */
if (hwdata->stopTicks) {
if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_GetTicks() >= hwdata->stopTicks) {
XINPUT_VIBRATION vibration = { 0, 0 };
hwdata->stopTicks = 0;
XINPUTSETSTATE(hwdata->userid, &vibration);
}
}
SDL_UnlockMutex(hwdata->mutex);
}
return 0;
}
static int SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid)
{
char threadName[32];
XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */
XINPUTSETSTATE(userid, &vibration);
haptic->supported = SDL_HAPTIC_LEFTRIGHT;
haptic->neffects = 1;
haptic->nplaying = 1;
/* Prepare effects memory. */
haptic->effects = (struct haptic_effect *)
SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
if (!haptic->effects) {
return -1;
}
/* Clear the memory */
SDL_memset(haptic->effects, 0,
sizeof(struct haptic_effect) * haptic->neffects);
haptic->hwdata = (struct haptic_hwdata *)SDL_calloc(1, sizeof(*haptic->hwdata));
if (!haptic->hwdata) {
SDL_free(haptic->effects);
haptic->effects = NULL;
return -1;
}
haptic->hwdata->bXInputHaptic = 1;
haptic->hwdata->userid = userid;
haptic->hwdata->mutex = SDL_CreateMutex();
if (!haptic->hwdata->mutex) {
SDL_free(haptic->effects);
SDL_free(haptic->hwdata);
haptic->effects = NULL;
return SDL_SetError("Couldn't create XInput haptic mutex");
}
(void)SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%u", userid);
haptic->hwdata->thread = SDL_CreateThreadInternal(SDL_RunXInputHaptic, threadName, 64 * 1024, haptic->hwdata);
if (!haptic->hwdata->thread) {
SDL_DestroyMutex(haptic->hwdata->mutex);
SDL_free(haptic->effects);
SDL_free(haptic->hwdata);
haptic->effects = NULL;
return SDL_SetError("Couldn't create XInput haptic thread");
}
return 0;
}
int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item)
{
return SDL_XINPUT_HapticOpenFromUserIndex(haptic, item->userid);
}
int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
{
return haptic->hwdata->userid == joystick->hwdata->userid;
}
int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{
SDL_hapticlist_item *item;
Uint8 index = 0;
/* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
for (item = SDL_hapticlist; item; item = item->next) {
if (item->bXInputHaptic && item->userid == joystick->hwdata->userid) {
haptic->index = index;
return SDL_XINPUT_HapticOpenFromUserIndex(haptic, joystick->hwdata->userid);
}
++index;
}
return SDL_SetError("Couldn't find joystick in haptic device list");
}
void SDL_XINPUT_HapticClose(SDL_Haptic *haptic)
{
SDL_AtomicSet(&haptic->hwdata->stopThread, 1);
SDL_WaitThread(haptic->hwdata->thread, NULL);
SDL_DestroyMutex(haptic->hwdata->mutex);
}
void SDL_XINPUT_HapticQuit(void)
{
if (loaded_xinput) {
WIN_UnloadXInputDLL();
loaded_xinput = SDL_FALSE;
}
}
int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
{
SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
return SDL_XINPUT_HapticUpdateEffect(haptic, effect, base);
}
int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
{
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
/* SDL_HapticEffect has max magnitude of 32767, XInput expects 65535 max, so multiply */
vib->wLeftMotorSpeed = data->leftright.large_magnitude * 2;
vib->wRightMotorSpeed = data->leftright.small_magnitude * 2;
SDL_LockMutex(haptic->hwdata->mutex);
if (haptic->hwdata->stopTicks) { /* running right now? Update it. */
XINPUTSETSTATE(haptic->hwdata->userid, vib);
}
SDL_UnlockMutex(haptic->hwdata->mutex);
return 0;
}
int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
{
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
SDL_LockMutex(haptic->hwdata->mutex);
if (effect->effect.leftright.length == SDL_HAPTIC_INFINITY || iterations == SDL_HAPTIC_INFINITY) {
haptic->hwdata->stopTicks = SDL_HAPTIC_INFINITY;
} else if ((!effect->effect.leftright.length) || (!iterations)) {
/* do nothing. Effect runs for zero milliseconds. */
} else {
haptic->hwdata->stopTicks = SDL_GetTicks() + ((Uint64)effect->effect.leftright.length * iterations);
}
SDL_UnlockMutex(haptic->hwdata->mutex);
return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
}
int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{
XINPUT_VIBRATION vibration = { 0, 0 };
SDL_LockMutex(haptic->hwdata->mutex);
haptic->hwdata->stopTicks = 0;
SDL_UnlockMutex(haptic->hwdata->mutex);
return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
}
void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{
SDL_XINPUT_HapticStopEffect(haptic, effect);
}
int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticPause(SDL_Haptic *haptic)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic)
{
XINPUT_VIBRATION vibration = { 0, 0 };
SDL_LockMutex(haptic->hwdata->mutex);
haptic->hwdata->stopTicks = 0;
SDL_UnlockMutex(haptic->hwdata->mutex);
return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
}
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#else /* !SDL_HAPTIC_XINPUT */
#include "../../core/windows/SDL_windows.h"
typedef struct SDL_hapticlist_item SDL_hapticlist_item;
int SDL_XINPUT_HapticInit(void)
{
return 0;
}
int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item)
{
return SDL_Unsupported();
}
int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
{
return SDL_Unsupported();
}
void SDL_XINPUT_HapticClose(SDL_Haptic *haptic)
{
}
void SDL_XINPUT_HapticQuit(void)
{
}
int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{
return SDL_Unsupported();
}
void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
{
}
int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticPause(SDL_Haptic *haptic)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic)
{
return SDL_Unsupported();
}
int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic)
{
return SDL_Unsupported();
}
#endif /* SDL_HAPTIC_XINPUT */

View File

@ -1,53 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_windowshaptic_c.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
extern int SDL_XINPUT_HapticInit(void);
extern int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid);
extern int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid);
extern int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item);
extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick);
extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick);
extern void SDL_XINPUT_HapticClose(SDL_Haptic *haptic);
extern void SDL_XINPUT_HapticQuit(void);
extern int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base);
extern int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data);
extern int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations);
extern int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect);
extern void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect);
extern int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect);
extern int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain);
extern int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter);
extern int SDL_XINPUT_HapticPause(SDL_Haptic *haptic);
extern int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic);
extern int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif

View File

@ -564,7 +564,7 @@ static void JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender
/* Allocate an instance ID for this device */ /* Allocate an instance ID for this device */
device->instance_id = SDL_GetNextObjectID(); device->instance_id = SDL_GetNextObjectID();
/* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */ /* We have to do some storage of the io_service_t for SDL_OpenHapticFromJoystick */
ioservice = IOHIDDeviceGetService(ioHIDDeviceObject); ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) { if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
device->ffservice = ioservice; device->ffservice = ioservice;

View File

@ -46,7 +46,6 @@
#include "SDL_rawinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h"
#include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */ #include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */
#include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */
#ifndef DEVICE_NOTIFY_WINDOW_HANDLE #ifndef DEVICE_NOTIFY_WINDOW_HANDLE
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
@ -551,11 +550,7 @@ void WINDOWS_JoystickDetect(void)
while (pCurList) { while (pCurList) {
JoyStick_DeviceData *pListNext = NULL; JoyStick_DeviceData *pListNext = NULL;
if (pCurList->bXInputDevice) { if (!pCurList->bXInputDevice) {
#ifdef SDL_HAPTIC_XINPUT
SDL_XINPUT_HapticMaybeRemoveDevice(pCurList->XInputUserId);
#endif
} else {
#ifdef SDL_HAPTIC_DINPUT #ifdef SDL_HAPTIC_DINPUT
SDL_DINPUT_HapticMaybeRemoveDevice(&pCurList->dxdevice); SDL_DINPUT_HapticMaybeRemoveDevice(&pCurList->dxdevice);
#endif #endif
@ -571,11 +566,7 @@ void WINDOWS_JoystickDetect(void)
for (pCurList = SYS_Joystick; pCurList; pCurList = pCurList->pNext) { for (pCurList = SYS_Joystick; pCurList; pCurList = pCurList->pNext) {
if (pCurList->send_add_event) { if (pCurList->send_add_event) {
if (pCurList->bXInputDevice) { if (!pCurList->bXInputDevice) {
#ifdef SDL_HAPTIC_XINPUT
SDL_XINPUT_HapticMaybeAddDevice(pCurList->XInputUserId);
#endif
} else {
#ifdef SDL_HAPTIC_DINPUT #ifdef SDL_HAPTIC_DINPUT
SDL_DINPUT_HapticMaybeAddDevice(&pCurList->dxdevice); SDL_DINPUT_HapticMaybeAddDevice(&pCurList->dxdevice);
#endif #endif

View File

@ -40,6 +40,8 @@ int main(int argc, char **argv)
int id[9]; int id[9];
int nefx; int nefx;
unsigned int supported; unsigned int supported;
SDL_HapticID *haptics;
int num_haptics;
/* Initialize test framework */ /* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0); state = SDLTest_CommonCreateState(argv, 0);
@ -81,41 +83,52 @@ int main(int argc, char **argv)
/* Initialize the force feedbackness */ /* Initialize the force feedbackness */
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
SDL_INIT_HAPTIC); SDL_INIT_HAPTIC);
SDL_Log("%d Haptic devices detected:\n", SDL_NumHaptics()); haptics = SDL_GetHaptics(&num_haptics);
for (i = 0; i < SDL_NumHaptics(); ++i) { SDL_Log("%d Haptic devices detected.\n", num_haptics);
SDL_Log(" %s\n", SDL_HapticName(i)); for (i = 0; i < num_haptics; ++i) {
SDL_Log(" %s\n", SDL_GetHapticInstanceName(haptics[i]));
} }
if (SDL_NumHaptics() > 0) { if (haptics) {
if (num_haptics == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
SDL_free(haptics);
return 1;
}
/* We'll just use index or the first force feedback device found */ /* We'll just use index or the first force feedback device found */
if (!name) { if (!name) {
i = (index != -1) ? index : 0; i = (index != -1) ? index : 0;
if (i >= num_haptics) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Index out of range, aborting.\n");
SDL_free(haptics);
return 1;
}
} }
/* Try to find matching device */ /* Try to find matching device */
else { else {
for (i = 0; i < SDL_NumHaptics(); i++) { for (i = 0; i < num_haptics; i++) {
if (SDL_strstr(SDL_HapticName(i), name) != NULL) { if (SDL_strstr(SDL_GetHapticInstanceName(haptics[i]), name) != NULL) {
break; break;
} }
} }
if (i >= SDL_NumHaptics()) { if (i >= num_haptics) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", name);
name); SDL_free(haptics);
return 1; return 1;
} }
} }
haptic = SDL_HapticOpen(i); haptic = SDL_OpenHaptic(haptics[i]);
if (!haptic) { if (!haptic) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", SDL_GetError());
SDL_GetError()); SDL_free(haptics);
return 1; return 1;
} }
SDL_Log("Device: %s\n", SDL_HapticName(i)); SDL_Log("Device: %s\n", SDL_GetHapticName(haptic));
HapticPrintSupported(haptic); HapticPrintSupported(haptic);
} else { SDL_free(haptics);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
return 1;
} }
/* We only want force feedback errors. */ /* We only want force feedback errors. */
@ -124,7 +137,7 @@ int main(int argc, char **argv)
/* Create effects. */ /* Create effects. */
SDL_memset(efx, 0, sizeof(efx)); SDL_memset(efx, 0, sizeof(efx));
nefx = 0; nefx = 0;
supported = SDL_HapticQuery(haptic); supported = SDL_GetHapticFeatures(haptic);
SDL_Log("\nUploading effects\n"); SDL_Log("\nUploading effects\n");
/* First we'll try a SINE effect. */ /* First we'll try a SINE effect. */
@ -137,7 +150,7 @@ int main(int argc, char **argv)
efx[nefx].periodic.length = 5000; efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000; efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000; efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -153,7 +166,7 @@ int main(int argc, char **argv)
efx[nefx].periodic.length = 5000; efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000; efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000; efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -171,7 +184,7 @@ int main(int argc, char **argv)
efx[nefx].constant.level = 0x6000; efx[nefx].constant.level = 0x6000;
efx[nefx].constant.attack_length = 1000; efx[nefx].constant.attack_length = 1000;
efx[nefx].constant.fade_length = 1000; efx[nefx].constant.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -184,14 +197,14 @@ int main(int argc, char **argv)
SDL_Log(" effect %d: Condition Spring\n", nefx); SDL_Log(" effect %d: Condition Spring\n", nefx);
efx[nefx].type = SDL_HAPTIC_SPRING; efx[nefx].type = SDL_HAPTIC_SPRING;
efx[nefx].condition.length = 5000; efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { for (i = 0; i < SDL_GetNumHapticAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF; efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF; efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000; efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000; efx[nefx].condition.left_coeff[i] = 0x2000;
efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */ efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
} }
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -203,13 +216,13 @@ int main(int argc, char **argv)
SDL_Log(" effect %d: Condition Damper\n", nefx); SDL_Log(" effect %d: Condition Damper\n", nefx);
efx[nefx].type = SDL_HAPTIC_DAMPER; efx[nefx].type = SDL_HAPTIC_DAMPER;
efx[nefx].condition.length = 5000; efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { for (i = 0; i < SDL_GetNumHapticAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF; efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF; efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000; efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000; efx[nefx].condition.left_coeff[i] = 0x2000;
} }
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -221,14 +234,14 @@ int main(int argc, char **argv)
SDL_Log(" effect %d: Condition Inertia\n", nefx); SDL_Log(" effect %d: Condition Inertia\n", nefx);
efx[nefx].type = SDL_HAPTIC_INERTIA; efx[nefx].type = SDL_HAPTIC_INERTIA;
efx[nefx].condition.length = 5000; efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { for (i = 0; i < SDL_GetNumHapticAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF; efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF; efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000; efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000; efx[nefx].condition.left_coeff[i] = 0x2000;
efx[nefx].condition.deadband[i] = 0x1000; /* 1/16th of axis-range around the center is 'dead'. */ efx[nefx].condition.deadband[i] = 0x1000; /* 1/16th of axis-range around the center is 'dead'. */
} }
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -240,13 +253,13 @@ int main(int argc, char **argv)
SDL_Log(" effect %d: Condition Friction\n", nefx); SDL_Log(" effect %d: Condition Friction\n", nefx);
efx[nefx].type = SDL_HAPTIC_FRICTION; efx[nefx].type = SDL_HAPTIC_FRICTION;
efx[nefx].condition.length = 5000; efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { for (i = 0; i < SDL_GetNumHapticAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF; efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF; efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000; efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000; efx[nefx].condition.left_coeff[i] = 0x2000;
} }
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -266,7 +279,7 @@ int main(int argc, char **argv)
efx[nefx].ramp.end = -0x4000; efx[nefx].ramp.end = -0x4000;
efx[nefx].ramp.attack_length = 1000; efx[nefx].ramp.attack_length = 1000;
efx[nefx].ramp.fade_length = 1000; efx[nefx].ramp.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -281,7 +294,7 @@ int main(int argc, char **argv)
efx[nefx].leftright.length = 5000; efx[nefx].leftright.length = 5000;
efx[nefx].leftright.large_magnitude = 0x3000; efx[nefx].leftright.large_magnitude = 0x3000;
efx[nefx].leftright.small_magnitude = 0xFFFF; efx[nefx].leftright.small_magnitude = 0xFFFF;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); id[nefx] = SDL_CreateHapticEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) { if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
abort_execution(); abort_execution();
@ -292,13 +305,13 @@ int main(int argc, char **argv)
SDL_Log("\nNow playing effects for 5 seconds each with 1 second delay between\n"); SDL_Log("\nNow playing effects for 5 seconds each with 1 second delay between\n");
for (i = 0; i < nefx; i++) { for (i = 0; i < nefx; i++) {
SDL_Log(" Playing effect %d\n", i); SDL_Log(" Playing effect %d\n", i);
SDL_HapticRunEffect(haptic, id[i], 1); SDL_RunHapticEffect(haptic, id[i], 1);
SDL_Delay(6000); /* Effects only have length 5000 */ SDL_Delay(6000); /* Effects only have length 5000 */
} }
/* Quit */ /* Quit */
if (haptic) { if (haptic) {
SDL_HapticClose(haptic); SDL_CloseHaptic(haptic);
} }
SDL_Quit(); SDL_Quit();
SDLTest_CommonDestroyState(state); SDLTest_CommonDestroyState(state);
@ -314,7 +327,7 @@ abort_execution(void)
{ {
SDL_Log("\nAborting program execution.\n"); SDL_Log("\nAborting program execution.\n");
SDL_HapticClose(haptic); SDL_CloseHaptic(haptic);
SDL_Quit(); SDL_Quit();
SDLTest_CommonDestroyState(state); SDLTest_CommonDestroyState(state);
@ -329,9 +342,9 @@ HapticPrintSupported(SDL_Haptic *ptr)
{ {
unsigned int supported; unsigned int supported;
supported = SDL_HapticQuery(ptr); supported = SDL_GetHapticFeatures(ptr);
SDL_Log(" Supported effects [%d effects, %d playing]:\n", SDL_Log(" Supported effects [%d effects, %d playing]:\n",
SDL_HapticNumEffects(ptr), SDL_HapticNumEffectsPlaying(ptr)); SDL_GetMaxHapticEffects(ptr), SDL_GetMaxHapticEffectsPlaying(ptr));
if (supported & SDL_HAPTIC_CONSTANT) { if (supported & SDL_HAPTIC_CONSTANT) {
SDL_Log(" constant\n"); SDL_Log(" constant\n");
} }

View File

@ -81,7 +81,10 @@ int main(int argc, char *argv[])
SDL_free(SDL_GetJoysticks(&num_joysticks)); SDL_free(SDL_GetJoysticks(&num_joysticks));
SDL_Log("There are %d joysticks at startup\n", num_joysticks); SDL_Log("There are %d joysticks at startup\n", num_joysticks);
if (enable_haptic) { if (enable_haptic) {
SDL_Log("There are %d haptic devices at startup\n", SDL_NumHaptics()); int num_haptics;
SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics);
SDL_free(haptics);
SDL_Log("There are %d haptic devices at startup\n", num_haptics);
} }
while (keepGoing) { while (keepGoing) {
@ -99,13 +102,13 @@ int main(int argc, char *argv[])
instance = event.jdevice.which; instance = event.jdevice.which;
SDL_Log("Joy Added : %" SDL_PRIu32 " : %s\n", event.jdevice.which, SDL_GetJoystickName(joystick)); SDL_Log("Joy Added : %" SDL_PRIu32 " : %s\n", event.jdevice.which, SDL_GetJoystickName(joystick));
if (enable_haptic) { if (enable_haptic) {
if (SDL_JoystickIsHaptic(joystick)) { if (SDL_IsJoystickHaptic(joystick)) {
haptic = SDL_HapticOpenFromJoystick(joystick); haptic = SDL_OpenHapticFromJoystick(joystick);
if (haptic) { if (haptic) {
SDL_Log("Joy Haptic Opened\n"); SDL_Log("Joy Haptic Opened\n");
if (SDL_HapticRumbleInit(haptic) != 0) { if (SDL_InitHapticRumble(haptic) != 0) {
SDL_Log("Could not init Rumble!: %s\n", SDL_GetError()); SDL_Log("Could not init Rumble!: %s\n", SDL_GetError());
SDL_HapticClose(haptic); SDL_CloseHaptic(haptic);
haptic = NULL; haptic = NULL;
} }
} else { } else {
@ -122,7 +125,7 @@ int main(int argc, char *argv[])
SDL_Log("Joy Removed: %" SDL_PRIs32 "\n", event.jdevice.which); SDL_Log("Joy Removed: %" SDL_PRIs32 "\n", event.jdevice.which);
instance = 0; instance = 0;
if (enable_haptic && haptic) { if (enable_haptic && haptic) {
SDL_HapticClose(haptic); SDL_CloseHaptic(haptic);
haptic = NULL; haptic = NULL;
} }
SDL_CloseJoystick(joystick); SDL_CloseJoystick(joystick);
@ -136,13 +139,13 @@ int main(int argc, char *argv[])
// SDL_Log("Axis Move: %d\n", event.jaxis.axis); // SDL_Log("Axis Move: %d\n", event.jaxis.axis);
*/ */
if (enable_haptic) { if (enable_haptic) {
SDL_HapticRumblePlay(haptic, 0.25, 250); SDL_PlayHapticRumble(haptic, 0.25, 250);
} }
break; break;
case SDL_EVENT_JOYSTICK_BUTTON_DOWN: case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
SDL_Log("Button Press: %d\n", event.jbutton.button); SDL_Log("Button Press: %d\n", event.jbutton.button);
if (enable_haptic && haptic) { if (enable_haptic && haptic) {
SDL_HapticRumblePlay(haptic, 0.25, 250); SDL_PlayHapticRumble(haptic, 0.25, 250);
} }
if (event.jbutton.button == 0) { if (event.jbutton.button == 0) {
SDL_Log("Exiting due to button press of button 0\n"); SDL_Log("Exiting due to button press of button 0\n");

View File

@ -39,6 +39,8 @@ int main(int argc, char **argv)
char *name = NULL; char *name = NULL;
int index; int index;
SDLTest_CommonState *state; SDLTest_CommonState *state;
SDL_HapticID *haptics;
int num_haptics;
/* Initialize test framework */ /* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0); state = SDLTest_CommonCreateState(argv, 0);
@ -85,37 +87,48 @@ int main(int argc, char **argv)
/* Initialize the force feedbackness */ /* Initialize the force feedbackness */
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
SDL_INIT_HAPTIC); SDL_INIT_HAPTIC);
SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics()); haptics = SDL_GetHaptics(&num_haptics);
if (SDL_NumHaptics() > 0) { SDL_Log("%d Haptic devices detected.\n", num_haptics);
if (haptics) {
if (num_haptics == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
SDL_free(haptics);
return 1;
}
/* We'll just use index or the first force feedback device found */ /* We'll just use index or the first force feedback device found */
if (!name) { if (!name) {
i = (index != -1) ? index : 0; i = (index != -1) ? index : 0;
if (i >= num_haptics) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Index out of range, aborting.\n");
SDL_free(haptics);
return 1;
}
} }
/* Try to find matching device */ /* Try to find matching device */
else { else {
for (i = 0; i < SDL_NumHaptics(); i++) { for (i = 0; i < num_haptics; i++) {
if (SDL_strstr(SDL_HapticName(i), name) != NULL) { if (SDL_strstr(SDL_GetHapticInstanceName(haptics[i]), name) != NULL) {
break; break;
} }
} }
if (i >= SDL_NumHaptics()) { if (i >= num_haptics) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", name);
name); SDL_free(haptics);
return 1; return 1;
} }
} }
haptic = SDL_HapticOpen(i); haptic = SDL_OpenHaptic(haptics[i]);
if (!haptic) { if (!haptic) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", SDL_GetError());
SDL_GetError()); SDL_free(haptics);
return 1; return 1;
} }
SDL_Log("Device: %s\n", SDL_HapticName(i)); SDL_Log("Device: %s\n", SDL_GetHapticName(haptic));
} else { SDL_free(haptics);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
return 1;
} }
/* We only want force feedback errors. */ /* We only want force feedback errors. */
@ -125,21 +138,21 @@ int main(int argc, char **argv)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Rumble not supported!\n"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Rumble not supported!\n");
return 1; return 1;
} }
if (SDL_HapticRumbleInit(haptic) != 0) { if (SDL_InitHapticRumble(haptic) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize rumble: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize rumble: %s\n", SDL_GetError());
return 1; return 1;
} }
SDL_Log("Playing 2 second rumble at 0.5 magnitude.\n"); SDL_Log("Playing 2 second rumble at 0.5 magnitude.\n");
if (SDL_HapticRumblePlay(haptic, 0.5, 5000) != 0) { if (SDL_PlayHapticRumble(haptic, 0.5, 5000) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError());
return 1; return 1;
} }
SDL_Delay(2000); SDL_Delay(2000);
SDL_Log("Stopping rumble.\n"); SDL_Log("Stopping rumble.\n");
SDL_HapticRumbleStop(haptic); SDL_StopHapticRumble(haptic);
SDL_Delay(2000); SDL_Delay(2000);
SDL_Log("Playing 2 second rumble at 0.3 magnitude.\n"); SDL_Log("Playing 2 second rumble at 0.3 magnitude.\n");
if (SDL_HapticRumblePlay(haptic, 0.3f, 5000) != 0) { if (SDL_PlayHapticRumble(haptic, 0.3f, 5000) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError());
return 1; return 1;
} }
@ -147,7 +160,7 @@ int main(int argc, char **argv)
/* Quit */ /* Quit */
if (haptic) { if (haptic) {
SDL_HapticClose(haptic); SDL_CloseHaptic(haptic);
} }
SDL_Quit(); SDL_Quit();