Split the XInput and DirectInput code so Windows RT can use the existing XInput support.
authorSam Lantinga <slouken@libsdl.org>
Thu, 03 Jul 2014 15:39:55 -0700
changeset 8972dfc759d7486f
parent 8971 c30e826412d1
child 8973 47fb6a7e7f68
Split the XInput and DirectInput code so Windows RT can use the existing XInput support.
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
VisualC/SDL/SDL_VS2008.vcproj
VisualC/SDL/SDL_VS2010.vcxproj
VisualC/SDL/SDL_VS2012.vcxproj
VisualC/SDL/SDL_VS2013.vcxproj
configure
configure.in
include/SDL_config.h.in
include/SDL_config_windows.h
include/SDL_config_winrt.h
src/audio/directsound/SDL_directsound.h
src/audio/directsound/directx.h
src/core/windows/SDL_directx.h
src/core/windows/SDL_xinput.c
src/core/windows/SDL_xinput.h
src/haptic/windows/SDL_dinputhaptic.c
src/haptic/windows/SDL_dinputhaptic_c.h
src/haptic/windows/SDL_syshaptic.c
src/haptic/windows/SDL_syshaptic_c.h
src/haptic/windows/SDL_windowshaptic.c
src/haptic/windows/SDL_windowshaptic_c.h
src/haptic/windows/SDL_xinputhaptic.c
src/haptic/windows/SDL_xinputhaptic_c.h
src/joystick/SDL_gamecontroller.c
src/joystick/SDL_gamecontrollerdb.h
src/joystick/SDL_sysjoystick.h
src/joystick/windows/SDL_dinputjoystick.c
src/joystick/windows/SDL_dinputjoystick_c.h
src/joystick/windows/SDL_dxjoystick.c
src/joystick/windows/SDL_dxjoystick_c.h
src/joystick/windows/SDL_windowsjoystick.c
src/joystick/windows/SDL_windowsjoystick_c.h
src/joystick/windows/SDL_xinputjoystick.c
src/joystick/windows/SDL_xinputjoystick_c.h
src/joystick/winrt/SDL_xinputjoystick.c
     1.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Thu Jul 03 17:36:08 2014 -0300
     1.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Thu Jul 03 15:39:55 2014 -0700
     1.3 @@ -47,6 +47,7 @@
     1.4        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     1.5      </ClCompile>
     1.6      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
     1.7 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
     1.8      <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
     1.9        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    1.10        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    1.11 @@ -93,9 +94,14 @@
    1.12      <ClCompile Include="..\..\src\file\SDL_rwops.c" />
    1.13      <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
    1.14      <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
    1.15 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
    1.16 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
    1.17 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
    1.18      <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c" />
    1.19      <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
    1.20 -    <ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c" />
    1.21 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
    1.22 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
    1.23 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
    1.24      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
    1.25      <ClCompile Include="..\..\src\power\SDL_power.c" />
    1.26      <ClCompile Include="..\..\src\power\winrt\SDL_syspower.cpp" />
    1.27 @@ -278,7 +284,9 @@
    1.28      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    1.29      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
    1.30      <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
    1.31 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    1.32      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    1.33 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    1.34      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
    1.35      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
    1.36      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h" />
    1.37 @@ -297,9 +305,15 @@
    1.38      <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
    1.39      <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
    1.40      <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
    1.41 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    1.42 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    1.43 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    1.44      <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
    1.45      <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
    1.46      <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
    1.47 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
    1.48 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
    1.49 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
    1.50      <ClInclude Include="..\..\src\render\direct3d11\SDL_render_winrt.h" />
    1.51      <ClInclude Include="..\..\src\render\mmx.h" />
    1.52      <ClInclude Include="..\..\src\render\opengles2\SDL_gles2funcs.h" />
     2.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Thu Jul 03 17:36:08 2014 -0300
     2.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Thu Jul 03 15:39:55 2014 -0700
     2.3 @@ -247,9 +247,6 @@
     2.4      <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
     2.5        <Filter>Source Files</Filter>
     2.6      </ClCompile>
     2.7 -    <ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c">
     2.8 -      <Filter>Source Files</Filter>
     2.9 -    </ClCompile>
    2.10      <ClCompile Include="..\..\src\video\winrt\SDL_winrtpointerinput.cpp">
    2.11        <Filter>Source Files</Filter>
    2.12      </ClCompile>
    2.13 @@ -298,6 +295,27 @@
    2.14      <ClCompile Include="..\..\src\video\winrt\SDL_winrtmessagebox.cpp">
    2.15        <Filter>Source Files</Filter>
    2.16      </ClCompile>
    2.17 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c">
    2.18 +      <Filter>Source Files</Filter>
    2.19 +    </ClCompile>
    2.20 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c">
    2.21 +      <Filter>Source Files</Filter>
    2.22 +    </ClCompile>
    2.23 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c">
    2.24 +      <Filter>Source Files</Filter>
    2.25 +    </ClCompile>
    2.26 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c">
    2.27 +      <Filter>Source Files</Filter>
    2.28 +    </ClCompile>
    2.29 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c">
    2.30 +      <Filter>Source Files</Filter>
    2.31 +    </ClCompile>
    2.32 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c">
    2.33 +      <Filter>Source Files</Filter>
    2.34 +    </ClCompile>
    2.35 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c">
    2.36 +      <Filter>Source Files</Filter>
    2.37 +    </ClCompile>
    2.38    </ItemGroup>
    2.39    <ItemGroup>
    2.40      <ClInclude Include="..\..\include\begin_code.h">
    2.41 @@ -672,6 +690,30 @@
    2.42      <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h">
    2.43        <Filter>Source Files</Filter>
    2.44      </ClInclude>
    2.45 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h">
    2.46 +      <Filter>Source Files</Filter>
    2.47 +    </ClInclude>
    2.48 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h">
    2.49 +      <Filter>Source Files</Filter>
    2.50 +    </ClInclude>
    2.51 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h">
    2.52 +      <Filter>Source Files</Filter>
    2.53 +    </ClInclude>
    2.54 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h">
    2.55 +      <Filter>Source Files</Filter>
    2.56 +    </ClInclude>
    2.57 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h">
    2.58 +      <Filter>Source Files</Filter>
    2.59 +    </ClInclude>
    2.60 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h">
    2.61 +      <Filter>Source Files</Filter>
    2.62 +    </ClInclude>
    2.63 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h">
    2.64 +      <Filter>Source Files</Filter>
    2.65 +    </ClInclude>
    2.66 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h">
    2.67 +      <Filter>Source Files</Filter>
    2.68 +    </ClInclude>
    2.69    </ItemGroup>
    2.70    <ItemGroup>
    2.71      <Filter Include="Header Files">
     3.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Thu Jul 03 17:36:08 2014 -0300
     3.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Thu Jul 03 15:39:55 2014 -0700
     3.3 @@ -86,7 +86,9 @@
     3.4      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
     3.5      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
     3.6      <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
     3.7 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
     3.8      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
     3.9 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    3.10      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
    3.11      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
    3.12      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_xaml.h" />
    3.13 @@ -105,9 +107,15 @@
    3.14      <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
    3.15      <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
    3.16      <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
    3.17 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    3.18 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    3.19 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    3.20      <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
    3.21      <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
    3.22      <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
    3.23 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
    3.24 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
    3.25 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
    3.26      <ClInclude Include="..\..\src\render\direct3d11\SDL_render_winrt.h" />
    3.27      <ClInclude Include="..\..\src\render\mmx.h" />
    3.28      <ClInclude Include="..\..\src\render\opengles2\SDL_gles2funcs.h" />
    3.29 @@ -173,6 +181,7 @@
    3.30        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    3.31      </ClCompile>
    3.32      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
    3.33 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
    3.34      <ClCompile Include="..\..\src\core\winrt\SDL_winrtapp_common.cpp">
    3.35        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
    3.36        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    3.37 @@ -219,10 +228,15 @@
    3.38      <ClCompile Include="..\..\src\file\SDL_rwops.c" />
    3.39      <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
    3.40      <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
    3.41 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
    3.42 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
    3.43 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
    3.44      <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
    3.45      <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c" />
    3.46      <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
    3.47 -    <ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c" />
    3.48 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
    3.49 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
    3.50 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
    3.51      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
    3.52      <ClCompile Include="..\..\src\power\SDL_power.c" />
    3.53      <ClCompile Include="..\..\src\power\winrt\SDL_syspower.cpp" />
     4.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Thu Jul 03 17:36:08 2014 -0300
     4.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Thu Jul 03 15:39:55 2014 -0700
     4.3 @@ -381,6 +381,24 @@
     4.4      <ClInclude Include="..\..\src\video\winrt\SDL_winrtvideo_cpp.h">
     4.5        <Filter>Source Files</Filter>
     4.6      </ClInclude>
     4.7 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h">
     4.8 +      <Filter>Source Files</Filter>
     4.9 +    </ClInclude>
    4.10 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h">
    4.11 +      <Filter>Source Files</Filter>
    4.12 +    </ClInclude>
    4.13 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h">
    4.14 +      <Filter>Source Files</Filter>
    4.15 +    </ClInclude>
    4.16 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h">
    4.17 +      <Filter>Source Files</Filter>
    4.18 +    </ClInclude>
    4.19 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h">
    4.20 +      <Filter>Source Files</Filter>
    4.21 +    </ClInclude>
    4.22 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    4.23 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    4.24 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    4.25    </ItemGroup>
    4.26    <ItemGroup>
    4.27      <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
    4.28 @@ -485,9 +503,6 @@
    4.29      <ClCompile Include="..\..\src\joystick\SDL_joystick.c">
    4.30        <Filter>Source Files</Filter>
    4.31      </ClCompile>
    4.32 -    <ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c">
    4.33 -      <Filter>Source Files</Filter>
    4.34 -    </ClCompile>
    4.35      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c">
    4.36        <Filter>Source Files</Filter>
    4.37      </ClCompile>
    4.38 @@ -683,5 +698,20 @@
    4.39      <ClCompile Include="..\..\src\video\winrt\SDL_winrtvideo.cpp">
    4.40        <Filter>Source Files</Filter>
    4.41      </ClCompile>
    4.42 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c">
    4.43 +      <Filter>Source Files</Filter>
    4.44 +    </ClCompile>
    4.45 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c">
    4.46 +      <Filter>Source Files</Filter>
    4.47 +    </ClCompile>
    4.48 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c">
    4.49 +      <Filter>Source Files</Filter>
    4.50 +    </ClCompile>
    4.51 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c">
    4.52 +      <Filter>Source Files</Filter>
    4.53 +    </ClCompile>
    4.54 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
    4.55 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
    4.56 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
    4.57    </ItemGroup>
    4.58  </Project>
    4.59 \ No newline at end of file
     5.1 --- a/VisualC/SDL/SDL_VS2008.vcproj	Thu Jul 03 17:36:08 2014 -0300
     5.2 +++ b/VisualC/SDL/SDL_VS2008.vcproj	Thu Jul 03 15:39:55 2014 -0700
     5.3 @@ -372,6 +372,14 @@
     5.4  			Name="API Headers"
     5.5  			>
     5.6  			<File
     5.7 +				RelativePath="..\..\include\begin_code.h"
     5.8 +				>
     5.9 +			</File>
    5.10 +			<File
    5.11 +				RelativePath="..\..\include\close_code.h"
    5.12 +				>
    5.13 +			</File>
    5.14 +			<File
    5.15  				RelativePath="..\..\include\SDL.h"
    5.16  				>
    5.17  			</File>
    5.18 @@ -420,10 +428,6 @@
    5.19  				>
    5.20  			</File>
    5.21  			<File
    5.22 -				RelativePath="..\..\src\video\sdl_egl_c.h"
    5.23 -				>
    5.24 -			</File>
    5.25 -			<File
    5.26  				RelativePath="..\..\include\SDL_endian.h"
    5.27  				>
    5.28  			</File>
    5.29 @@ -500,10 +504,34 @@
    5.30  				>
    5.31  			</File>
    5.32  			<File
    5.33 +				RelativePath="..\..\include\SDL_opengl_glext.h"
    5.34 +				>
    5.35 +			</File>
    5.36 +			<File
    5.37  				RelativePath="..\..\include\SDL_opengles.h"
    5.38  				>
    5.39  			</File>
    5.40  			<File
    5.41 +				RelativePath="..\..\include\SDL_opengles2.h"
    5.42 +				>
    5.43 +			</File>
    5.44 +			<File
    5.45 +				RelativePath="..\..\include\SDL_opengles2_gl2.h"
    5.46 +				>
    5.47 +			</File>
    5.48 +			<File
    5.49 +				RelativePath="..\..\include\SDL_opengles2_gl2ext.h"
    5.50 +				>
    5.51 +			</File>
    5.52 +			<File
    5.53 +				RelativePath="..\..\include\SDL_opengles2_gl2platform.h"
    5.54 +				>
    5.55 +			</File>
    5.56 +			<File
    5.57 +				RelativePath="..\..\include\SDL_opengles2_khrplatform.h"
    5.58 +				>
    5.59 +			</File>
    5.60 +			<File
    5.61  				RelativePath="..\..\include\SDL_pixels.h"
    5.62  				>
    5.63  			</File>
    5.64 @@ -560,6 +588,54 @@
    5.65  				>
    5.66  			</File>
    5.67  			<File
    5.68 +				RelativePath="..\..\include\SDL_test.h"
    5.69 +				>
    5.70 +			</File>
    5.71 +			<File
    5.72 +				RelativePath="..\..\include\SDL_test_assert.h"
    5.73 +				>
    5.74 +			</File>
    5.75 +			<File
    5.76 +				RelativePath="..\..\include\SDL_test_common.h"
    5.77 +				>
    5.78 +			</File>
    5.79 +			<File
    5.80 +				RelativePath="..\..\include\SDL_test_compare.h"
    5.81 +				>
    5.82 +			</File>
    5.83 +			<File
    5.84 +				RelativePath="..\..\include\SDL_test_crc32.h"
    5.85 +				>
    5.86 +			</File>
    5.87 +			<File
    5.88 +				RelativePath="..\..\include\SDL_test_font.h"
    5.89 +				>
    5.90 +			</File>
    5.91 +			<File
    5.92 +				RelativePath="..\..\include\SDL_test_fuzzer.h"
    5.93 +				>
    5.94 +			</File>
    5.95 +			<File
    5.96 +				RelativePath="..\..\include\SDL_test_harness.h"
    5.97 +				>
    5.98 +			</File>
    5.99 +			<File
   5.100 +				RelativePath="..\..\include\SDL_test_images.h"
   5.101 +				>
   5.102 +			</File>
   5.103 +			<File
   5.104 +				RelativePath="..\..\include\SDL_test_log.h"
   5.105 +				>
   5.106 +			</File>
   5.107 +			<File
   5.108 +				RelativePath="..\..\include\SDL_test_md5.h"
   5.109 +				>
   5.110 +			</File>
   5.111 +			<File
   5.112 +				RelativePath="..\..\include\SDL_test_random.h"
   5.113 +				>
   5.114 +			</File>
   5.115 +			<File
   5.116  				RelativePath="..\..\include\SDL_thread.h"
   5.117  				>
   5.118  			</File>
   5.119 @@ -583,10 +659,6 @@
   5.120  				RelativePath="..\..\include\SDL_video.h"
   5.121  				>
   5.122  			</File>
   5.123 -			<File
   5.124 -				RelativePath="..\..\src\video\windows\SDL_windowsopengles.h"
   5.125 -				>
   5.126 -			</File>
   5.127  		</Filter>
   5.128  		<File
   5.129  			RelativePath="..\..\src\events\blank_cursor.h"
   5.130 @@ -597,10 +669,6 @@
   5.131  			>
   5.132  		</File>
   5.133  		<File
   5.134 -			RelativePath="..\..\src\audio\directsound\directx.h"
   5.135 -			>
   5.136 -		</File>
   5.137 -		<File
   5.138  			RelativePath="..\..\src\libm\e_atan2.c"
   5.139  			>
   5.140  		</File>
   5.141 @@ -825,6 +893,22 @@
   5.142  			>
   5.143  		</File>
   5.144  		<File
   5.145 +			RelativePath="..\..\src\haptic\windows\SDL_dinputhaptic.c"
   5.146 +			>
   5.147 +		</File>
   5.148 +		<File
   5.149 +			RelativePath="..\..\src\haptic\windows\SDL_dinputhaptic_c.h"
   5.150 +			>
   5.151 +		</File>
   5.152 +		<File
   5.153 +			RelativePath="..\..\src\joystick\windows\SDL_dinputjoystick.c"
   5.154 +			>
   5.155 +		</File>
   5.156 +		<File
   5.157 +			RelativePath="..\..\src\joystick\windows\SDL_dinputjoystick_c.h"
   5.158 +			>
   5.159 +		</File>
   5.160 +		<File
   5.161  			RelativePath="..\..\src\audio\directsound\SDL_directsound.c"
   5.162  			>
   5.163  		</File>
   5.164 @@ -833,6 +917,10 @@
   5.165  			>
   5.166  		</File>
   5.167  		<File
   5.168 +			RelativePath="..\..\src\core\windows\SDL_directx.h"
   5.169 +			>
   5.170 +		</File>
   5.171 +		<File
   5.172  			RelativePath="..\..\src\audio\disk\SDL_diskaudio.c"
   5.173  			>
   5.174  		</File>
   5.175 @@ -877,10 +965,6 @@
   5.176  			>
   5.177  		</File>
   5.178  		<File
   5.179 -			RelativePath="..\..\src\joystick\windows\SDL_dxjoystick.c"
   5.180 -			>
   5.181 -		</File>
   5.182 -		<File
   5.183  			RelativePath="..\..\src\dynapi\SDL_dynapi.c"
   5.184  			>
   5.185  		</File>
   5.186 @@ -1157,10 +1241,6 @@
   5.187  			>
   5.188  		</File>
   5.189  		<File
   5.190 -			RelativePath="..\..\src\haptic\windows\SDL_syshaptic.c"
   5.191 -			>
   5.192 -		</File>
   5.193 -		<File
   5.194  			RelativePath="..\..\src\haptic\SDL_syshaptic.h"
   5.195  			>
   5.196  		</File>
   5.197 @@ -1297,6 +1377,22 @@
   5.198  			>
   5.199  		</File>
   5.200  		<File
   5.201 +			RelativePath="..\..\src\haptic\windows\SDL_windowshaptic.c"
   5.202 +			>
   5.203 +		</File>
   5.204 +		<File
   5.205 +			RelativePath="..\..\src\haptic\windows\SDL_windowshaptic_c.h"
   5.206 +			>
   5.207 +		</File>
   5.208 +		<File
   5.209 +			RelativePath="..\..\src\joystick\windows\SDL_windowsjoystick.c"
   5.210 +			>
   5.211 +		</File>
   5.212 +		<File
   5.213 +			RelativePath="..\..\src\joystick\windows\SDL_windowsjoystick_c.h"
   5.214 +			>
   5.215 +		</File>
   5.216 +		<File
   5.217  			RelativePath="..\..\src\video\windows\SDL_windowskeyboard.c"
   5.218  			>
   5.219  		</File>
   5.220 @@ -1377,6 +1473,30 @@
   5.221  			>
   5.222  		</File>
   5.223  		<File
   5.224 +			RelativePath="..\..\src\core\windows\SDL_xinput.c"
   5.225 +			>
   5.226 +		</File>
   5.227 +		<File
   5.228 +			RelativePath="..\..\src\core\windows\SDL_xinput.h"
   5.229 +			>
   5.230 +		</File>
   5.231 +		<File
   5.232 +			RelativePath="..\..\src\haptic\windows\SDL_xinputhaptic.c"
   5.233 +			>
   5.234 +		</File>
   5.235 +		<File
   5.236 +			RelativePath="..\..\src\haptic\windows\SDL_xinputhaptic_c.h"
   5.237 +			>
   5.238 +		</File>
   5.239 +		<File
   5.240 +			RelativePath="..\..\src\joystick\windows\SDL_xinputjoystick.c"
   5.241 +			>
   5.242 +		</File>
   5.243 +		<File
   5.244 +			RelativePath="..\..\src\joystick\windows\SDL_xinputjoystick_c.h"
   5.245 +			>
   5.246 +		</File>
   5.247 +		<File
   5.248  			RelativePath="..\..\src\render\SDL_yuv_mmx.c"
   5.249  			>
   5.250  		</File>
     6.1 --- a/VisualC/SDL/SDL_VS2010.vcxproj	Thu Jul 03 17:36:08 2014 -0300
     6.2 +++ b/VisualC/SDL/SDL_VS2010.vcxproj	Thu Jul 03 15:39:55 2014 -0700
     6.3 @@ -219,6 +219,8 @@
     6.4      </Link>
     6.5    </ItemDefinitionGroup>
     6.6    <ItemGroup>
     6.7 +    <ClInclude Include="..\..\include\begin_code.h" />
     6.8 +    <ClInclude Include="..\..\include\close_code.h" />
     6.9      <ClInclude Include="..\..\include\SDL.h" />
    6.10      <ClInclude Include="..\..\include\SDL_assert.h" />
    6.11      <ClInclude Include="..\..\include\SDL_atomic.h" />
    6.12 @@ -235,6 +237,7 @@
    6.13      <ClInclude Include="..\..\include\SDL_error.h" />
    6.14      <ClInclude Include="..\..\include\SDL_events.h" />
    6.15      <ClInclude Include="..\..\include\SDL_filesystem.h" />
    6.16 +    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    6.17      <ClInclude Include="..\..\include\SDL_gesture.h" />
    6.18      <ClInclude Include="..\..\include\SDL_haptic.h" />
    6.19      <ClInclude Include="..\..\include\SDL_hints.h" />
    6.20 @@ -244,11 +247,18 @@
    6.21      <ClInclude Include="..\..\include\SDL_loadso.h" />
    6.22      <ClInclude Include="..\..\include\SDL_log.h" />
    6.23      <ClInclude Include="..\..\include\SDL_main.h" />
    6.24 +    <ClInclude Include="..\..\include\SDL_messagebox.h" />
    6.25      <ClInclude Include="..\..\include\SDL_mouse.h" />
    6.26      <ClInclude Include="..\..\include\SDL_mutex.h" />
    6.27      <ClInclude Include="..\..\include\SDL_name.h" />
    6.28      <ClInclude Include="..\..\include\SDL_opengl.h" />
    6.29      <ClInclude Include="..\..\include\SDL_opengles.h" />
    6.30 +    <ClInclude Include="..\..\include\SDL_opengles2.h" />
    6.31 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2.h" />
    6.32 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2ext.h" />
    6.33 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2platform.h" />
    6.34 +    <ClInclude Include="..\..\include\SDL_opengles2_khrplatform.h" />
    6.35 +    <ClInclude Include="..\..\include\SDL_opengl_glext.h" />
    6.36      <ClInclude Include="..\..\include\SDL_pixels.h" />
    6.37      <ClInclude Include="..\..\include\SDL_platform.h" />
    6.38      <ClInclude Include="..\..\include\SDL_power.h" />
    6.39 @@ -263,23 +273,42 @@
    6.40      <ClInclude Include="..\..\include\SDL_surface.h" />
    6.41      <ClInclude Include="..\..\include\SDL_system.h" />
    6.42      <ClInclude Include="..\..\include\SDL_syswm.h" />
    6.43 +    <ClInclude Include="..\..\include\SDL_test.h" />
    6.44 +    <ClInclude Include="..\..\include\SDL_test_assert.h" />
    6.45 +    <ClInclude Include="..\..\include\SDL_test_common.h" />
    6.46 +    <ClInclude Include="..\..\include\SDL_test_compare.h" />
    6.47 +    <ClInclude Include="..\..\include\SDL_test_crc32.h" />
    6.48 +    <ClInclude Include="..\..\include\SDL_test_font.h" />
    6.49 +    <ClInclude Include="..\..\include\SDL_test_fuzzer.h" />
    6.50 +    <ClInclude Include="..\..\include\SDL_test_harness.h" />
    6.51 +    <ClInclude Include="..\..\include\SDL_test_images.h" />
    6.52 +    <ClInclude Include="..\..\include\SDL_test_log.h" />
    6.53 +    <ClInclude Include="..\..\include\SDL_test_md5.h" />
    6.54 +    <ClInclude Include="..\..\include\SDL_test_random.h" />
    6.55      <ClInclude Include="..\..\include\SDL_thread.h" />
    6.56      <ClInclude Include="..\..\include\SDL_timer.h" />
    6.57      <ClInclude Include="..\..\include\SDL_touch.h" />
    6.58      <ClInclude Include="..\..\include\SDL_types.h" />
    6.59      <ClInclude Include="..\..\include\SDL_version.h" />
    6.60      <ClInclude Include="..\..\include\SDL_video.h" />
    6.61 -    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    6.62 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    6.63      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    6.64 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    6.65      <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
    6.66      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
    6.67      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
    6.68      <ClInclude Include="..\..\src\events\blank_cursor.h" />
    6.69      <ClInclude Include="..\..\src\events\default_cursor.h" />
    6.70 -    <ClInclude Include="..\..\src\audio\directsound\directx.h" />
    6.71      <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
    6.72      <ClInclude Include="..\..\src\events\SDL_gesture_c.h" />
    6.73      <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
    6.74 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    6.75 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    6.76 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    6.77 +    <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
    6.78 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
    6.79 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
    6.80 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
    6.81      <ClInclude Include="..\..\src\libm\math_libm.h" />
    6.82      <ClInclude Include="..\..\src\libm\math_private.h" />
    6.83      <ClInclude Include="..\..\src\render\mmx.h" />
    6.84 @@ -322,7 +351,6 @@
    6.85      <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
    6.86      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    6.87      <ClInclude Include="..\..\src\events\SDL_sysevents.h" />
    6.88 -    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
    6.89      <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
    6.90      <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
    6.91      <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
    6.92 @@ -348,10 +376,17 @@
    6.93    </ItemGroup>
    6.94    <ItemGroup>
    6.95      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
    6.96 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
    6.97      <ClCompile Include="..\..\src\dynapi\SDL_dynapi.c" />
    6.98      <ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
    6.99      <ClCompile Include="..\..\src\events\SDL_gesture.c" />
   6.100      <ClCompile Include="..\..\src\events\SDL_touch.c" />
   6.101 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
   6.102 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
   6.103 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
   6.104 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
   6.105 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
   6.106 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
   6.107      <ClCompile Include="..\..\src\libm\e_atan2.c" />
   6.108      <ClCompile Include="..\..\src\libm\e_log.c" />
   6.109      <ClCompile Include="..\..\src\libm\e_pow.c" />
   6.110 @@ -416,7 +451,6 @@
   6.111      <ClCompile Include="..\..\src\audio\directsound\SDL_directsound.c" />
   6.112      <ClCompile Include="..\..\src\events\SDL_dropevents.c" />
   6.113      <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
   6.114 -    <ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" />
   6.115      <ClCompile Include="..\..\src\SDL_error.c" />
   6.116      <ClCompile Include="..\..\src\events\SDL_events.c" />
   6.117      <ClCompile Include="..\..\src\video\SDL_fillrect.c" />
   6.118 @@ -444,7 +478,6 @@
   6.119      <ClCompile Include="..\..\src\video\SDL_surface.c" />
   6.120      <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
   6.121      <ClCompile Include="..\..\src\filesystem\windows\SDL_sysfilesystem.c" />
   6.122 -    <ClCompile Include="..\..\src\haptic\windows\SDL_syshaptic.c" />
   6.123      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
   6.124      <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />
   6.125      <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     7.1 --- a/VisualC/SDL/SDL_VS2012.vcxproj	Thu Jul 03 17:36:08 2014 -0300
     7.2 +++ b/VisualC/SDL/SDL_VS2012.vcxproj	Thu Jul 03 15:39:55 2014 -0700
     7.3 @@ -223,6 +223,8 @@
     7.4      </Link>
     7.5    </ItemDefinitionGroup>
     7.6    <ItemGroup>
     7.7 +    <ClInclude Include="..\..\include\begin_code.h" />
     7.8 +    <ClInclude Include="..\..\include\close_code.h" />
     7.9      <ClInclude Include="..\..\include\SDL.h" />
    7.10      <ClInclude Include="..\..\include\SDL_assert.h" />
    7.11      <ClInclude Include="..\..\include\SDL_atomic.h" />
    7.12 @@ -239,6 +241,7 @@
    7.13      <ClInclude Include="..\..\include\SDL_error.h" />
    7.14      <ClInclude Include="..\..\include\SDL_events.h" />
    7.15      <ClInclude Include="..\..\include\SDL_filesystem.h" />
    7.16 +    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    7.17      <ClInclude Include="..\..\include\SDL_gesture.h" />
    7.18      <ClInclude Include="..\..\include\SDL_haptic.h" />
    7.19      <ClInclude Include="..\..\include\SDL_hints.h" />
    7.20 @@ -248,11 +251,18 @@
    7.21      <ClInclude Include="..\..\include\SDL_loadso.h" />
    7.22      <ClInclude Include="..\..\include\SDL_log.h" />
    7.23      <ClInclude Include="..\..\include\SDL_main.h" />
    7.24 +    <ClInclude Include="..\..\include\SDL_messagebox.h" />
    7.25      <ClInclude Include="..\..\include\SDL_mouse.h" />
    7.26      <ClInclude Include="..\..\include\SDL_mutex.h" />
    7.27      <ClInclude Include="..\..\include\SDL_name.h" />
    7.28      <ClInclude Include="..\..\include\SDL_opengl.h" />
    7.29      <ClInclude Include="..\..\include\SDL_opengles.h" />
    7.30 +    <ClInclude Include="..\..\include\SDL_opengles2.h" />
    7.31 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2.h" />
    7.32 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2ext.h" />
    7.33 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2platform.h" />
    7.34 +    <ClInclude Include="..\..\include\SDL_opengles2_khrplatform.h" />
    7.35 +    <ClInclude Include="..\..\include\SDL_opengl_glext.h" />
    7.36      <ClInclude Include="..\..\include\SDL_pixels.h" />
    7.37      <ClInclude Include="..\..\include\SDL_platform.h" />
    7.38      <ClInclude Include="..\..\include\SDL_power.h" />
    7.39 @@ -267,23 +277,42 @@
    7.40      <ClInclude Include="..\..\include\SDL_surface.h" />
    7.41      <ClInclude Include="..\..\include\SDL_system.h" />
    7.42      <ClInclude Include="..\..\include\SDL_syswm.h" />
    7.43 +    <ClInclude Include="..\..\include\SDL_test.h" />
    7.44 +    <ClInclude Include="..\..\include\SDL_test_assert.h" />
    7.45 +    <ClInclude Include="..\..\include\SDL_test_common.h" />
    7.46 +    <ClInclude Include="..\..\include\SDL_test_compare.h" />
    7.47 +    <ClInclude Include="..\..\include\SDL_test_crc32.h" />
    7.48 +    <ClInclude Include="..\..\include\SDL_test_font.h" />
    7.49 +    <ClInclude Include="..\..\include\SDL_test_fuzzer.h" />
    7.50 +    <ClInclude Include="..\..\include\SDL_test_harness.h" />
    7.51 +    <ClInclude Include="..\..\include\SDL_test_images.h" />
    7.52 +    <ClInclude Include="..\..\include\SDL_test_log.h" />
    7.53 +    <ClInclude Include="..\..\include\SDL_test_md5.h" />
    7.54 +    <ClInclude Include="..\..\include\SDL_test_random.h" />
    7.55      <ClInclude Include="..\..\include\SDL_thread.h" />
    7.56      <ClInclude Include="..\..\include\SDL_timer.h" />
    7.57      <ClInclude Include="..\..\include\SDL_touch.h" />
    7.58      <ClInclude Include="..\..\include\SDL_types.h" />
    7.59      <ClInclude Include="..\..\include\SDL_version.h" />
    7.60      <ClInclude Include="..\..\include\SDL_video.h" />
    7.61 -    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    7.62 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    7.63      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    7.64 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    7.65      <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
    7.66      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
    7.67      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
    7.68      <ClInclude Include="..\..\src\events\blank_cursor.h" />
    7.69      <ClInclude Include="..\..\src\events\default_cursor.h" />
    7.70 -    <ClInclude Include="..\..\src\audio\directsound\directx.h" />
    7.71      <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
    7.72      <ClInclude Include="..\..\src\events\SDL_gesture_c.h" />
    7.73      <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
    7.74 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    7.75 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    7.76 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    7.77 +    <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
    7.78 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
    7.79 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
    7.80 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
    7.81      <ClInclude Include="..\..\src\libm\math_libm.h" />
    7.82      <ClInclude Include="..\..\src\libm\math_private.h" />
    7.83      <ClInclude Include="..\..\src\render\mmx.h" />
    7.84 @@ -326,7 +355,6 @@
    7.85      <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
    7.86      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    7.87      <ClInclude Include="..\..\src\events\SDL_sysevents.h" />
    7.88 -    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
    7.89      <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
    7.90      <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
    7.91      <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
    7.92 @@ -352,10 +380,17 @@
    7.93    </ItemGroup>
    7.94    <ItemGroup>
    7.95      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
    7.96 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
    7.97      <ClCompile Include="..\..\src\dynapi\SDL_dynapi.c" />
    7.98      <ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
    7.99      <ClCompile Include="..\..\src\events\SDL_gesture.c" />
   7.100      <ClCompile Include="..\..\src\events\SDL_touch.c" />
   7.101 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
   7.102 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
   7.103 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
   7.104 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
   7.105 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
   7.106 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
   7.107      <ClCompile Include="..\..\src\libm\e_atan2.c" />
   7.108      <ClCompile Include="..\..\src\libm\e_log.c" />
   7.109      <ClCompile Include="..\..\src\libm\e_pow.c" />
   7.110 @@ -420,7 +455,6 @@
   7.111      <ClCompile Include="..\..\src\audio\directsound\SDL_directsound.c" />
   7.112      <ClCompile Include="..\..\src\events\SDL_dropevents.c" />
   7.113      <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
   7.114 -    <ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" />
   7.115      <ClCompile Include="..\..\src\SDL_error.c" />
   7.116      <ClCompile Include="..\..\src\events\SDL_events.c" />
   7.117      <ClCompile Include="..\..\src\video\SDL_fillrect.c" />
   7.118 @@ -448,7 +482,6 @@
   7.119      <ClCompile Include="..\..\src\video\SDL_surface.c" />
   7.120      <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
   7.121      <ClCompile Include="..\..\src\filesystem\windows\SDL_sysfilesystem.c" />
   7.122 -    <ClCompile Include="..\..\src\haptic\windows\SDL_syshaptic.c" />
   7.123      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
   7.124      <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />
   7.125      <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     8.1 --- a/VisualC/SDL/SDL_VS2013.vcxproj	Thu Jul 03 17:36:08 2014 -0300
     8.2 +++ b/VisualC/SDL/SDL_VS2013.vcxproj	Thu Jul 03 15:39:55 2014 -0700
     8.3 @@ -223,6 +223,8 @@
     8.4      </Link>
     8.5    </ItemDefinitionGroup>
     8.6    <ItemGroup>
     8.7 +    <ClInclude Include="..\..\include\begin_code.h" />
     8.8 +    <ClInclude Include="..\..\include\close_code.h" />
     8.9      <ClInclude Include="..\..\include\SDL.h" />
    8.10      <ClInclude Include="..\..\include\SDL_assert.h" />
    8.11      <ClInclude Include="..\..\include\SDL_atomic.h" />
    8.12 @@ -239,6 +241,7 @@
    8.13      <ClInclude Include="..\..\include\SDL_error.h" />
    8.14      <ClInclude Include="..\..\include\SDL_events.h" />
    8.15      <ClInclude Include="..\..\include\SDL_filesystem.h" />
    8.16 +    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    8.17      <ClInclude Include="..\..\include\SDL_gesture.h" />
    8.18      <ClInclude Include="..\..\include\SDL_haptic.h" />
    8.19      <ClInclude Include="..\..\include\SDL_hints.h" />
    8.20 @@ -248,11 +251,18 @@
    8.21      <ClInclude Include="..\..\include\SDL_loadso.h" />
    8.22      <ClInclude Include="..\..\include\SDL_log.h" />
    8.23      <ClInclude Include="..\..\include\SDL_main.h" />
    8.24 +    <ClInclude Include="..\..\include\SDL_messagebox.h" />
    8.25      <ClInclude Include="..\..\include\SDL_mouse.h" />
    8.26      <ClInclude Include="..\..\include\SDL_mutex.h" />
    8.27      <ClInclude Include="..\..\include\SDL_name.h" />
    8.28      <ClInclude Include="..\..\include\SDL_opengl.h" />
    8.29      <ClInclude Include="..\..\include\SDL_opengles.h" />
    8.30 +    <ClInclude Include="..\..\include\SDL_opengles2.h" />
    8.31 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2.h" />
    8.32 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2ext.h" />
    8.33 +    <ClInclude Include="..\..\include\SDL_opengles2_gl2platform.h" />
    8.34 +    <ClInclude Include="..\..\include\SDL_opengles2_khrplatform.h" />
    8.35 +    <ClInclude Include="..\..\include\SDL_opengl_glext.h" />
    8.36      <ClInclude Include="..\..\include\SDL_pixels.h" />
    8.37      <ClInclude Include="..\..\include\SDL_platform.h" />
    8.38      <ClInclude Include="..\..\include\SDL_power.h" />
    8.39 @@ -267,23 +277,42 @@
    8.40      <ClInclude Include="..\..\include\SDL_surface.h" />
    8.41      <ClInclude Include="..\..\include\SDL_system.h" />
    8.42      <ClInclude Include="..\..\include\SDL_syswm.h" />
    8.43 +    <ClInclude Include="..\..\include\SDL_test.h" />
    8.44 +    <ClInclude Include="..\..\include\SDL_test_assert.h" />
    8.45 +    <ClInclude Include="..\..\include\SDL_test_common.h" />
    8.46 +    <ClInclude Include="..\..\include\SDL_test_compare.h" />
    8.47 +    <ClInclude Include="..\..\include\SDL_test_crc32.h" />
    8.48 +    <ClInclude Include="..\..\include\SDL_test_font.h" />
    8.49 +    <ClInclude Include="..\..\include\SDL_test_fuzzer.h" />
    8.50 +    <ClInclude Include="..\..\include\SDL_test_harness.h" />
    8.51 +    <ClInclude Include="..\..\include\SDL_test_images.h" />
    8.52 +    <ClInclude Include="..\..\include\SDL_test_log.h" />
    8.53 +    <ClInclude Include="..\..\include\SDL_test_md5.h" />
    8.54 +    <ClInclude Include="..\..\include\SDL_test_random.h" />
    8.55      <ClInclude Include="..\..\include\SDL_thread.h" />
    8.56      <ClInclude Include="..\..\include\SDL_timer.h" />
    8.57      <ClInclude Include="..\..\include\SDL_touch.h" />
    8.58      <ClInclude Include="..\..\include\SDL_types.h" />
    8.59      <ClInclude Include="..\..\include\SDL_version.h" />
    8.60      <ClInclude Include="..\..\include\SDL_video.h" />
    8.61 -    <ClInclude Include="..\..\include\SDL_gamecontroller.h" />
    8.62 +    <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    8.63      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    8.64 +    <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    8.65      <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
    8.66      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
    8.67      <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
    8.68      <ClInclude Include="..\..\src\events\blank_cursor.h" />
    8.69      <ClInclude Include="..\..\src\events\default_cursor.h" />
    8.70 -    <ClInclude Include="..\..\src\audio\directsound\directx.h" />
    8.71      <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
    8.72      <ClInclude Include="..\..\src\events\SDL_gesture_c.h" />
    8.73      <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
    8.74 +    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    8.75 +    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    8.76 +    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    8.77 +    <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
    8.78 +    <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
    8.79 +    <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
    8.80 +    <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
    8.81      <ClInclude Include="..\..\src\libm\math_libm.h" />
    8.82      <ClInclude Include="..\..\src\libm\math_private.h" />
    8.83      <ClInclude Include="..\..\src\render\mmx.h" />
    8.84 @@ -326,7 +355,6 @@
    8.85      <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
    8.86      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    8.87      <ClInclude Include="..\..\src\events\SDL_sysevents.h" />
    8.88 -    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
    8.89      <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
    8.90      <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
    8.91      <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
    8.92 @@ -352,10 +380,17 @@
    8.93    </ItemGroup>
    8.94    <ItemGroup>
    8.95      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
    8.96 +    <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
    8.97      <ClCompile Include="..\..\src\dynapi\SDL_dynapi.c" />
    8.98      <ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
    8.99      <ClCompile Include="..\..\src\events\SDL_gesture.c" />
   8.100      <ClCompile Include="..\..\src\events\SDL_touch.c" />
   8.101 +    <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
   8.102 +    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
   8.103 +    <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
   8.104 +    <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
   8.105 +    <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
   8.106 +    <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
   8.107      <ClCompile Include="..\..\src\libm\e_atan2.c" />
   8.108      <ClCompile Include="..\..\src\libm\e_log.c" />
   8.109      <ClCompile Include="..\..\src\libm\e_pow.c" />
   8.110 @@ -420,7 +455,6 @@
   8.111      <ClCompile Include="..\..\src\audio\directsound\SDL_directsound.c" />
   8.112      <ClCompile Include="..\..\src\events\SDL_dropevents.c" />
   8.113      <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
   8.114 -    <ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" />
   8.115      <ClCompile Include="..\..\src\SDL_error.c" />
   8.116      <ClCompile Include="..\..\src\events\SDL_events.c" />
   8.117      <ClCompile Include="..\..\src\video\SDL_fillrect.c" />
   8.118 @@ -448,7 +482,6 @@
   8.119      <ClCompile Include="..\..\src\video\SDL_surface.c" />
   8.120      <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
   8.121      <ClCompile Include="..\..\src\filesystem\windows\SDL_sysfilesystem.c" />
   8.122 -    <ClCompile Include="..\..\src\haptic\windows\SDL_syshaptic.c" />
   8.123      <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
   8.124      <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />
   8.125      <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     9.1 --- a/configure	Thu Jul 03 17:36:08 2014 -0300
     9.2 +++ b/configure	Thu Jul 03 15:39:55 2014 -0700
     9.3 @@ -22112,18 +22112,50 @@
     9.4  fi
     9.5  
     9.6  
     9.7 +        ac_fn_c_check_header_mongrel "$LINENO" "dxgi.h" "ac_cv_header_dxgi_h" "$ac_includes_default"
     9.8 +if test "x$ac_cv_header_dxgi_h" = xyes; then :
     9.9 +  have_dxgi=yes
    9.10 +fi
    9.11 +
    9.12 +
    9.13          ac_fn_c_check_header_mongrel "$LINENO" "xaudio2.h" "ac_cv_header_xaudio2_h" "$ac_includes_default"
    9.14  if test "x$ac_cv_header_xaudio2_h" = xyes; then :
    9.15    have_xaudio2=yes
    9.16  fi
    9.17  
    9.18  
    9.19 -        ac_fn_c_check_header_mongrel "$LINENO" "dxgi.h" "ac_cv_header_dxgi_h" "$ac_includes_default"
    9.20 -if test "x$ac_cv_header_dxgi_h" = xyes; then :
    9.21 -  have_dxgi=yes
    9.22 -fi
    9.23 -
    9.24 -
    9.25 +        ac_fn_c_check_header_mongrel "$LINENO" "xinput.h" "ac_cv_header_xinput_h" "$ac_includes_default"
    9.26 +if test "x$ac_cv_header_xinput_h" = xyes; then :
    9.27 +  have_xinput=yes
    9.28 +fi
    9.29 +
    9.30 +
    9.31 +
    9.32 +        if test x$have_ddraw = xyes; then
    9.33 +
    9.34 +$as_echo "#define HAVE_DDRAW_H 1" >>confdefs.h
    9.35 +
    9.36 +        fi
    9.37 +        if test x$have_dinput = xyes; then
    9.38 +
    9.39 +$as_echo "#define HAVE_DINPUT_H 1" >>confdefs.h
    9.40 +
    9.41 +        fi
    9.42 +        if test x$have_dsound = xyes; then
    9.43 +
    9.44 +$as_echo "#define HAVE_DSOUND_H 1" >>confdefs.h
    9.45 +
    9.46 +        fi
    9.47 +        if test x$have_dxgi = xyes; then
    9.48 +
    9.49 +$as_echo "#define HAVE_DXGI_H 1" >>confdefs.h
    9.50 +
    9.51 +        fi
    9.52 +        if test x$have_xinput = xyes; then
    9.53 +
    9.54 +$as_echo "#define HAVE_XINPUT_H 1" >>confdefs.h
    9.55 +
    9.56 +        fi
    9.57  
    9.58          SUMMARY_video="${SUMMARY_video} directx"
    9.59          SUMMARY_audio="${SUMMARY_audio} directx"
    9.60 @@ -22981,11 +23013,6 @@
    9.61  
    9.62              fi
    9.63          fi
    9.64 -        if test x$have_dxgi = xyes; then
    9.65 -
    9.66 -$as_echo "#define HAVE_DXGI_H 1" >>confdefs.h
    9.67 -
    9.68 -        fi
    9.69          # Set up files for the audio library
    9.70          if test x$enable_audio = xyes; then
    9.71  
    9.72 @@ -23008,25 +23035,38 @@
    9.73          fi
    9.74          # Set up files for the joystick library
    9.75          if test x$enable_joystick = xyes; then
    9.76 -            if test x$have_dinput = xyes; then
    9.77 +            if test x$have_dinput = xyes -o x$have_xinput = xyes; then
    9.78 +                if test x$have_xinput = xyes; then
    9.79 +
    9.80 +$as_echo "#define SDL_JOYSTICK_XINPUT 1" >>confdefs.h
    9.81 +
    9.82 +                fi
    9.83 +                if test x$have_dinput = xyes; then
    9.84  
    9.85  $as_echo "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h
    9.86  
    9.87 -                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_dxjoystick.c"
    9.88 -                EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
    9.89 +                    EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
    9.90 +                fi
    9.91              else
    9.92  
    9.93  $as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h
    9.94  
    9.95 -                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_mmjoystick.c"
    9.96 -            fi
    9.97 +            fi
    9.98 +            SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
    9.99              have_joystick=yes
   9.100          fi
   9.101          if test x$enable_haptic = xyes; then
   9.102 -            if test x$have_dinput = xyes; then
   9.103 +            if test x$have_dinput = xyes -o x$have_xinput = xyes; then
   9.104 +                if test x$have_xinput = xyes; then
   9.105 +
   9.106 +$as_echo "#define SDL_HAPTIC_XINPUT 1" >>confdefs.h
   9.107 +
   9.108 +                fi
   9.109 +                if test x$have_dinput = xyes; then
   9.110  
   9.111  $as_echo "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h
   9.112  
   9.113 +                fi
   9.114                  SOURCES="$SOURCES $srcdir/src/haptic/windows/SDL_syshaptic.c"
   9.115                  have_haptic=yes
   9.116              fi
    10.1 --- a/configure.in	Thu Jul 03 17:36:08 2014 -0300
    10.2 +++ b/configure.in	Thu Jul 03 15:39:55 2014 -0700
    10.3 @@ -2496,8 +2496,25 @@
    10.4          AC_CHECK_HEADER(ddraw.h, have_ddraw=yes)
    10.5          AC_CHECK_HEADER(dsound.h, have_dsound=yes)
    10.6          AC_CHECK_HEADER(dinput.h, have_dinput=yes)
    10.7 +        AC_CHECK_HEADER(dxgi.h, have_dxgi=yes)
    10.8          AC_CHECK_HEADER(xaudio2.h, have_xaudio2=yes)
    10.9 -        AC_CHECK_HEADER(dxgi.h, have_dxgi=yes)
   10.10 +        AC_CHECK_HEADER(xinput.h, have_xinput=yes)
   10.11 +
   10.12 +        if test x$have_ddraw = xyes; then
   10.13 +            AC_DEFINE(HAVE_DDRAW_H, 1, [ ])
   10.14 +        fi
   10.15 +        if test x$have_dinput = xyes; then
   10.16 +            AC_DEFINE(HAVE_DINPUT_H, 1, [ ])
   10.17 +        fi
   10.18 +        if test x$have_dsound = xyes; then
   10.19 +            AC_DEFINE(HAVE_DSOUND_H, 1, [ ])
   10.20 +        fi
   10.21 +        if test x$have_dxgi = xyes; then
   10.22 +            AC_DEFINE(HAVE_DXGI_H, 1, [ ])
   10.23 +        fi
   10.24 +        if test x$have_xinput = xyes; then
   10.25 +            AC_DEFINE(HAVE_XINPUT_H, 1, [ ])
   10.26 +        fi
   10.27  
   10.28          SUMMARY_video="${SUMMARY_video} directx"
   10.29          SUMMARY_audio="${SUMMARY_audio} directx"
   10.30 @@ -2927,9 +2944,6 @@
   10.31                  AC_DEFINE(SDL_VIDEO_RENDER_D3D11, 1, [ ])
   10.32              fi
   10.33          fi
   10.34 -        if test x$have_dxgi = xyes; then
   10.35 -            AC_DEFINE(HAVE_DXGI_H, 1, [ ])
   10.36 -        fi
   10.37          # Set up files for the audio library
   10.38          if test x$enable_audio = xyes; then
   10.39              AC_DEFINE(SDL_AUDIO_DRIVER_WINMM, 1, [ ])
   10.40 @@ -2946,19 +2960,28 @@
   10.41          fi
   10.42          # Set up files for the joystick library
   10.43          if test x$enable_joystick = xyes; then
   10.44 -            if test x$have_dinput = xyes; then
   10.45 -                AC_DEFINE(SDL_JOYSTICK_DINPUT, 1, [ ])
   10.46 -                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_dxjoystick.c"
   10.47 -                EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
   10.48 +            if test x$have_dinput = xyes -o x$have_xinput = xyes; then
   10.49 +                if test x$have_xinput = xyes; then
   10.50 +                    AC_DEFINE(SDL_JOYSTICK_XINPUT, 1, [ ])
   10.51 +                fi
   10.52 +                if test x$have_dinput = xyes; then
   10.53 +                    AC_DEFINE(SDL_JOYSTICK_DINPUT, 1, [ ])
   10.54 +                    EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
   10.55 +                fi
   10.56              else
   10.57                  AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ])
   10.58 -                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_mmjoystick.c"
   10.59              fi
   10.60 +            SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
   10.61              have_joystick=yes
   10.62          fi
   10.63          if test x$enable_haptic = xyes; then
   10.64 -            if test x$have_dinput = xyes; then
   10.65 -                AC_DEFINE(SDL_HAPTIC_DINPUT, 1, [ ])
   10.66 +            if test x$have_dinput = xyes -o x$have_xinput = xyes; then
   10.67 +                if test x$have_xinput = xyes; then
   10.68 +                    AC_DEFINE(SDL_HAPTIC_XINPUT, 1, [ ])
   10.69 +                fi
   10.70 +                if test x$have_dinput = xyes; then
   10.71 +                    AC_DEFINE(SDL_HAPTIC_DINPUT, 1, [ ])
   10.72 +                fi
   10.73                  SOURCES="$SOURCES $srcdir/src/haptic/windows/SDL_syshaptic.c"
   10.74                  have_haptic=yes
   10.75              fi
    11.1 --- a/include/SDL_config.h.in	Thu Jul 03 17:36:08 2014 -0300
    11.2 +++ b/include/SDL_config.h.in	Thu Jul 03 15:39:55 2014 -0700
    11.3 @@ -51,7 +51,11 @@
    11.4  #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    11.5  #undef HAVE_PTHREAD_SPINLOCK
    11.6  
    11.7 +#undef HAVE_DDRAW_H
    11.8 +#undef HAVE_DINPUT_H
    11.9 +#undef HAVE_DSOUND_H
   11.10  #undef HAVE_DXGI_H
   11.11 +#undef HAVE_XINPUT_H
   11.12  
   11.13  /* Comment this if you want to build without any C library requirements */
   11.14  #undef HAVE_LIBC
   11.15 @@ -232,6 +236,7 @@
   11.16  #undef SDL_INPUT_TSLIB
   11.17  #undef SDL_JOYSTICK_HAIKU
   11.18  #undef SDL_JOYSTICK_DINPUT
   11.19 +#undef SDL_JOYSTICK_XINPUT
   11.20  #undef SDL_JOYSTICK_DUMMY
   11.21  #undef SDL_JOYSTICK_IOKIT
   11.22  #undef SDL_JOYSTICK_LINUX
   11.23 @@ -243,6 +248,7 @@
   11.24  #undef SDL_HAPTIC_LINUX
   11.25  #undef SDL_HAPTIC_IOKIT
   11.26  #undef SDL_HAPTIC_DINPUT
   11.27 +#undef SDL_HAPTIC_XINPUT
   11.28  
   11.29  /* Enable various shared object loading systems */
   11.30  #undef SDL_LOADSO_HAIKU
    12.1 --- a/include/SDL_config_windows.h	Thu Jul 03 17:36:08 2014 -0300
    12.2 +++ b/include/SDL_config_windows.h	Thu Jul 03 15:39:55 2014 -0700
    12.3 @@ -76,7 +76,11 @@
    12.4  # define SIZEOF_VOIDP 4
    12.5  #endif
    12.6  
    12.7 +#define HAVE_DDRAW_H 1
    12.8 +#define HAVE_DINPUT_H 1
    12.9 +#define HAVE_DSOUND_H 1
   12.10  #define HAVE_DXGI_H 1
   12.11 +#define HAVE_XINPUT_H 1
   12.12  
   12.13  /* This is disabled by default to avoid C runtime dependencies and manifest requirements */
   12.14  #ifdef HAVE_LIBC
   12.15 @@ -158,7 +162,9 @@
   12.16  
   12.17  /* Enable various input drivers */
   12.18  #define SDL_JOYSTICK_DINPUT 1
   12.19 +#define SDL_JOYSTICK_XINPUT 1
   12.20  #define SDL_HAPTIC_DINPUT   1
   12.21 +#define SDL_HAPTIC_XINPUT   1
   12.22  
   12.23  /* Enable various shared object loading systems */
   12.24  #define SDL_LOADSO_WINDOWS  1
    13.1 --- a/include/SDL_config_winrt.h	Thu Jul 03 17:36:08 2014 -0300
    13.2 +++ b/include/SDL_config_winrt.h	Thu Jul 03 15:39:55 2014 -0700
    13.3 @@ -78,6 +78,7 @@
    13.4  
    13.5  /* Useful headers */
    13.6  #define HAVE_DXGI_H 1
    13.7 +#define HAVE_XINPUT_H 1
    13.8  #define HAVE_LIBC 1
    13.9  #define HAVE_STDIO_H 1
   13.10  #define STDC_HEADERS 1
   13.11 @@ -148,13 +149,12 @@
   13.12  #define SDL_AUDIO_DRIVER_DUMMY	1
   13.13  
   13.14  /* Enable various input drivers */
   13.15 -// TODO, WinRT: Get haptic support working
   13.16 -#define SDL_HAPTIC_DISABLED	1
   13.17 -
   13.18  #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   13.19  #define SDL_JOYSTICK_DISABLED 1
   13.20 +#define SDL_HAPTIC_DISABLED	1
   13.21  #else
   13.22  #define SDL_JOYSTICK_XINPUT 1
   13.23 +#define SDL_HAPTIC_XINPUT   1
   13.24  #endif
   13.25  
   13.26  /* Enable various shared object loading systems */
    14.1 --- a/src/audio/directsound/SDL_directsound.h	Thu Jul 03 17:36:08 2014 -0300
    14.2 +++ b/src/audio/directsound/SDL_directsound.h	Thu Jul 03 15:39:55 2014 -0700
    14.3 @@ -23,7 +23,7 @@
    14.4  #ifndef _SDL_directsound_h
    14.5  #define _SDL_directsound_h
    14.6  
    14.7 -#include "directx.h"
    14.8 +#include "../../core/windows/SDL_directx.h"
    14.9  
   14.10  #include "../SDL_sysaudio.h"
   14.11  
    15.1 --- a/src/audio/directsound/directx.h	Thu Jul 03 17:36:08 2014 -0300
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,102 +0,0 @@
    15.4 -/*
    15.5 -  Simple DirectMedia Layer
    15.6 -  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    15.7 -
    15.8 -  This software is provided 'as-is', without any express or implied
    15.9 -  warranty.  In no event will the authors be held liable for any damages
   15.10 -  arising from the use of this software.
   15.11 -
   15.12 -  Permission is granted to anyone to use this software for any purpose,
   15.13 -  including commercial applications, and to alter it and redistribute it
   15.14 -  freely, subject to the following restrictions:
   15.15 -
   15.16 -  1. The origin of this software must not be misrepresented; you must not
   15.17 -     claim that you wrote the original software. If you use this software
   15.18 -     in a product, an acknowledgment in the product documentation would be
   15.19 -     appreciated but is not required.
   15.20 -  2. Altered source versions must be plainly marked as such, and must not be
   15.21 -     misrepresented as being the original software.
   15.22 -  3. This notice may not be removed or altered from any source distribution.
   15.23 -*/
   15.24 -
   15.25 -#ifndef _directx_h
   15.26 -#define _directx_h
   15.27 -
   15.28 -/* Include all of the DirectX 8.0 headers and adds any necessary tweaks */
   15.29 -
   15.30 -#include "../../core/windows/SDL_windows.h"
   15.31 -#include <mmsystem.h>
   15.32 -#ifndef WIN32
   15.33 -#define WIN32
   15.34 -#endif
   15.35 -#undef  WINNT
   15.36 -
   15.37 -/* Far pointers don't exist in 32-bit code */
   15.38 -#ifndef FAR
   15.39 -#define FAR
   15.40 -#endif
   15.41 -
   15.42 -/* Error codes not yet included in Win32 API header files */
   15.43 -#ifndef MAKE_HRESULT
   15.44 -#define MAKE_HRESULT(sev,fac,code) \
   15.45 -    ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
   15.46 -#endif
   15.47 -
   15.48 -#ifndef S_OK
   15.49 -#define S_OK        (HRESULT)0x00000000L
   15.50 -#endif
   15.51 -
   15.52 -#ifndef SUCCEEDED
   15.53 -#define SUCCEEDED(x)    ((HRESULT)(x) >= 0)
   15.54 -#endif
   15.55 -#ifndef FAILED
   15.56 -#define FAILED(x)   ((HRESULT)(x)<0)
   15.57 -#endif
   15.58 -
   15.59 -#ifndef E_FAIL
   15.60 -#define E_FAIL      (HRESULT)0x80000008L
   15.61 -#endif
   15.62 -#ifndef E_NOINTERFACE
   15.63 -#define E_NOINTERFACE   (HRESULT)0x80004002L
   15.64 -#endif
   15.65 -#ifndef E_OUTOFMEMORY
   15.66 -#define E_OUTOFMEMORY   (HRESULT)0x8007000EL
   15.67 -#endif
   15.68 -#ifndef E_INVALIDARG
   15.69 -#define E_INVALIDARG    (HRESULT)0x80070057L
   15.70 -#endif
   15.71 -#ifndef E_NOTIMPL
   15.72 -#define E_NOTIMPL   (HRESULT)0x80004001L
   15.73 -#endif
   15.74 -#ifndef REGDB_E_CLASSNOTREG
   15.75 -#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
   15.76 -#endif
   15.77 -
   15.78 -/* Severity codes */
   15.79 -#ifndef SEVERITY_ERROR
   15.80 -#define SEVERITY_ERROR  1
   15.81 -#endif
   15.82 -
   15.83 -/* Error facility codes */
   15.84 -#ifndef FACILITY_WIN32
   15.85 -#define FACILITY_WIN32  7
   15.86 -#endif
   15.87 -
   15.88 -#ifndef FIELD_OFFSET
   15.89 -#define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
   15.90 -#endif
   15.91 -
   15.92 -/* DirectX headers (if it isn't included, I haven't tested it yet)
   15.93 - */
   15.94 -/* We need these defines to mark what version of DirectX API we use */
   15.95 -#define DIRECTDRAW_VERSION  0x0700
   15.96 -#define DIRECTSOUND_VERSION 0x0800
   15.97 -#define DIRECTINPUT_VERSION 0x0500
   15.98 -
   15.99 -#include <ddraw.h>
  15.100 -#include <dsound.h>
  15.101 -#include <dinput.h>
  15.102 -
  15.103 -#endif /* _directx_h */
  15.104 -
  15.105 -/* vi: set ts=4 sw=4 expandtab: */
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/core/windows/SDL_directx.h	Thu Jul 03 15:39:55 2014 -0700
    16.3 @@ -0,0 +1,111 @@
    16.4 +/*
    16.5 +  Simple DirectMedia Layer
    16.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    16.7 +
    16.8 +  This software is provided 'as-is', without any express or implied
    16.9 +  warranty.  In no event will the authors be held liable for any damages
   16.10 +  arising from the use of this software.
   16.11 +
   16.12 +  Permission is granted to anyone to use this software for any purpose,
   16.13 +  including commercial applications, and to alter it and redistribute it
   16.14 +  freely, subject to the following restrictions:
   16.15 +
   16.16 +  1. The origin of this software must not be misrepresented; you must not
   16.17 +     claim that you wrote the original software. If you use this software
   16.18 +     in a product, an acknowledgment in the product documentation would be
   16.19 +     appreciated but is not required.
   16.20 +  2. Altered source versions must be plainly marked as such, and must not be
   16.21 +     misrepresented as being the original software.
   16.22 +  3. This notice may not be removed or altered from any source distribution.
   16.23 +*/
   16.24 +#include "../../SDL_internal.h"
   16.25 +
   16.26 +#ifndef _SDL_directx_h
   16.27 +#define _SDL_directx_h
   16.28 +
   16.29 +/* Include all of the DirectX 8.0 headers and adds any necessary tweaks */
   16.30 +
   16.31 +#include "SDL_windows.h"
   16.32 +#include <mmsystem.h>
   16.33 +#ifndef WIN32
   16.34 +#define WIN32
   16.35 +#endif
   16.36 +#undef  WINNT
   16.37 +
   16.38 +/* Far pointers don't exist in 32-bit code */
   16.39 +#ifndef FAR
   16.40 +#define FAR
   16.41 +#endif
   16.42 +
   16.43 +/* Error codes not yet included in Win32 API header files */
   16.44 +#ifndef MAKE_HRESULT
   16.45 +#define MAKE_HRESULT(sev,fac,code) \
   16.46 +    ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
   16.47 +#endif
   16.48 +
   16.49 +#ifndef S_OK
   16.50 +#define S_OK        (HRESULT)0x00000000L
   16.51 +#endif
   16.52 +
   16.53 +#ifndef SUCCEEDED
   16.54 +#define SUCCEEDED(x)    ((HRESULT)(x) >= 0)
   16.55 +#endif
   16.56 +#ifndef FAILED
   16.57 +#define FAILED(x)   ((HRESULT)(x)<0)
   16.58 +#endif
   16.59 +
   16.60 +#ifndef E_FAIL
   16.61 +#define E_FAIL      (HRESULT)0x80000008L
   16.62 +#endif
   16.63 +#ifndef E_NOINTERFACE
   16.64 +#define E_NOINTERFACE   (HRESULT)0x80004002L
   16.65 +#endif
   16.66 +#ifndef E_OUTOFMEMORY
   16.67 +#define E_OUTOFMEMORY   (HRESULT)0x8007000EL
   16.68 +#endif
   16.69 +#ifndef E_INVALIDARG
   16.70 +#define E_INVALIDARG    (HRESULT)0x80070057L
   16.71 +#endif
   16.72 +#ifndef E_NOTIMPL
   16.73 +#define E_NOTIMPL   (HRESULT)0x80004001L
   16.74 +#endif
   16.75 +#ifndef REGDB_E_CLASSNOTREG
   16.76 +#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
   16.77 +#endif
   16.78 +
   16.79 +/* Severity codes */
   16.80 +#ifndef SEVERITY_ERROR
   16.81 +#define SEVERITY_ERROR  1
   16.82 +#endif
   16.83 +
   16.84 +/* Error facility codes */
   16.85 +#ifndef FACILITY_WIN32
   16.86 +#define FACILITY_WIN32  7
   16.87 +#endif
   16.88 +
   16.89 +#ifndef FIELD_OFFSET
   16.90 +#define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
   16.91 +#endif
   16.92 +
   16.93 +/* DirectX headers (if it isn't included, I haven't tested it yet)
   16.94 + */
   16.95 +/* We need these defines to mark what version of DirectX API we use */
   16.96 +#define DIRECTDRAW_VERSION  0x0700
   16.97 +#define DIRECTSOUND_VERSION 0x0800
   16.98 +#define DIRECTINPUT_VERSION 0x0800 /* Need version 7 for force feedback. Need version 8 so IDirectInput8_EnumDevices doesn't leak like a sieve... */
   16.99 +
  16.100 +#ifdef HAVE_DDRAW_H
  16.101 +#include <ddraw.h>
  16.102 +#endif
  16.103 +#ifdef HAVE_DSOUND_H
  16.104 +#include <dsound.h>
  16.105 +#endif
  16.106 +#ifdef HAVE_DINPUT_H
  16.107 +#include <dinput.h>
  16.108 +#else
  16.109 +typedef struct { int unused; } DIDEVICEINSTANCE;
  16.110 +#endif
  16.111 +
  16.112 +#endif /* _SDL_directx_h */
  16.113 +
  16.114 +/* vi: set ts=4 sw=4 expandtab: */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/core/windows/SDL_xinput.c	Thu Jul 03 15:39:55 2014 -0700
    17.3 @@ -0,0 +1,94 @@
    17.4 +/*
    17.5 +  Simple DirectMedia Layer
    17.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    17.7 +
    17.8 +  This software is provided 'as-is', without any express or implied
    17.9 +  warranty.  In no event will the authors be held liable for any damages
   17.10 +  arising from the use of this software.
   17.11 +
   17.12 +  Permission is granted to anyone to use this software for any purpose,
   17.13 +  including commercial applications, and to alter it and redistribute it
   17.14 +  freely, subject to the following restrictions:
   17.15 +
   17.16 +  1. The origin of this software must not be misrepresented; you must not
   17.17 +     claim that you wrote the original software. If you use this software
   17.18 +     in a product, an acknowledgment in the product documentation would be
   17.19 +     appreciated but is not required.
   17.20 +  2. Altered source versions must be plainly marked as such, and must not be
   17.21 +     misrepresented as being the original software.
   17.22 +  3. This notice may not be removed or altered from any source distribution.
   17.23 +*/
   17.24 +#include "../../SDL_internal.h"
   17.25 +
   17.26 +#include "SDL_assert.h"
   17.27 +#include "SDL_xinput.h"
   17.28 +
   17.29 +
   17.30 +#ifdef HAVE_XINPUT_H
   17.31 +
   17.32 +XInputGetState_t SDL_XInputGetState = NULL;
   17.33 +XInputSetState_t SDL_XInputSetState = NULL;
   17.34 +XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;
   17.35 +DWORD SDL_XInputVersion = 0;
   17.36 +
   17.37 +static HANDLE s_pXInputDLL = 0;
   17.38 +static int s_XInputDLLRefCount = 0;
   17.39 +
   17.40 +
   17.41 +int
   17.42 +WIN_LoadXInputDLL(void)
   17.43 +{
   17.44 +    DWORD version = 0;
   17.45 +
   17.46 +    if (s_pXInputDLL) {
   17.47 +        SDL_assert(s_XInputDLLRefCount > 0);
   17.48 +        s_XInputDLLRefCount++;
   17.49 +        return 0;  /* already loaded */
   17.50 +    }
   17.51 +
   17.52 +    version = (1 << 16) | 4;
   17.53 +    s_pXInputDLL = LoadLibrary(L"XInput1_4.dll");  /* 1.4 Ships with Windows 8. */
   17.54 +    if (!s_pXInputDLL) {
   17.55 +        version = (1 << 16) | 3;
   17.56 +        s_pXInputDLL = LoadLibrary(L"XInput1_3.dll");  /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */
   17.57 +    }
   17.58 +    if (!s_pXInputDLL) {
   17.59 +        s_pXInputDLL = LoadLibrary(L"bin\\XInput1_3.dll");
   17.60 +    }
   17.61 +    if (!s_pXInputDLL) {
   17.62 +        return -1;
   17.63 +    }
   17.64 +
   17.65 +    SDL_assert(s_XInputDLLRefCount == 0);
   17.66 +    SDL_XInputVersion = version;
   17.67 +    s_XInputDLLRefCount = 1;
   17.68 +
   17.69 +    /* 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... */
   17.70 +    SDL_XInputGetState = (XInputGetState_t)GetProcAddress((HMODULE)s_pXInputDLL, (LPCSTR)100);
   17.71 +    SDL_XInputSetState = (XInputSetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputSetState");
   17.72 +    SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetCapabilities");
   17.73 +    if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) {
   17.74 +        WIN_UnloadXInputDLL();
   17.75 +        return -1;
   17.76 +    }
   17.77 +
   17.78 +    return 0;
   17.79 +}
   17.80 +
   17.81 +void
   17.82 +WIN_UnloadXInputDLL(void)
   17.83 +{
   17.84 +    if (s_pXInputDLL) {
   17.85 +        SDL_assert(s_XInputDLLRefCount > 0);
   17.86 +        if (--s_XInputDLLRefCount == 0) {
   17.87 +            FreeLibrary(s_pXInputDLL);
   17.88 +            s_pXInputDLL = NULL;
   17.89 +        }
   17.90 +    } else {
   17.91 +        SDL_assert(s_XInputDLLRefCount == 0);
   17.92 +    }
   17.93 +}
   17.94 +
   17.95 +#endif /* HAVE_XINPUT_H */
   17.96 +
   17.97 +/* vi: set ts=4 sw=4 expandtab: */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/core/windows/SDL_xinput.h	Thu Jul 03 15:39:55 2014 -0700
    18.3 @@ -0,0 +1,134 @@
    18.4 +/*
    18.5 +  Simple DirectMedia Layer
    18.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    18.7 +
    18.8 +  This software is provided 'as-is', without any express or implied
    18.9 +  warranty.  In no event will the authors be held liable for any damages
   18.10 +  arising from the use of this software.
   18.11 +
   18.12 +  Permission is granted to anyone to use this software for any purpose,
   18.13 +  including commercial applications, and to alter it and redistribute it
   18.14 +  freely, subject to the following restrictions:
   18.15 +
   18.16 +  1. The origin of this software must not be misrepresented; you must not
   18.17 +     claim that you wrote the original software. If you use this software
   18.18 +     in a product, an acknowledgment in the product documentation would be
   18.19 +     appreciated but is not required.
   18.20 +  2. Altered source versions must be plainly marked as such, and must not be
   18.21 +     misrepresented as being the original software.
   18.22 +  3. This notice may not be removed or altered from any source distribution.
   18.23 +*/
   18.24 +#include "../../SDL_internal.h"
   18.25 +
   18.26 +#ifndef _SDL_xinput_h
   18.27 +#define _SDL_xinput_h
   18.28 +
   18.29 +#ifdef HAVE_XINPUT_H
   18.30 +
   18.31 +#include "SDL_windows.h"
   18.32 +#include <xinput.h>
   18.33 +
   18.34 +#ifndef XUSER_MAX_COUNT
   18.35 +#define XUSER_MAX_COUNT 4
   18.36 +#endif
   18.37 +#ifndef XUSER_INDEX_ANY
   18.38 +#define XUSER_INDEX_ANY     0x000000FF
   18.39 +#endif
   18.40 +#ifndef XINPUT_CAPS_FFB_SUPPORTED
   18.41 +#define XINPUT_CAPS_FFB_SUPPORTED 0x0001
   18.42 +#endif
   18.43 +
   18.44 +#ifndef XINPUT_DEVSUBTYPE_UNKNOWN
   18.45 +#define XINPUT_DEVSUBTYPE_UNKNOWN 0x00
   18.46 +#endif
   18.47 +#ifndef XINPUT_DEVSUBTYPE_GAMEPAD
   18.48 +#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
   18.49 +#endif
   18.50 +#ifndef XINPUT_DEVSUBTYPE_WHEEL
   18.51 +#define XINPUT_DEVSUBTYPE_WHEEL 0x02
   18.52 +#endif
   18.53 +#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
   18.54 +#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
   18.55 +#endif
   18.56 +#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
   18.57 +#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
   18.58 +#endif
   18.59 +#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
   18.60 +#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
   18.61 +#endif
   18.62 +#ifndef XINPUT_DEVSUBTYPE_GUITAR
   18.63 +#define XINPUT_DEVSUBTYPE_GUITAR 0x06
   18.64 +#endif
   18.65 +#ifndef XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE
   18.66 +#define XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE 0x07
   18.67 +#endif
   18.68 +#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
   18.69 +#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
   18.70 +#endif
   18.71 +#ifndef XINPUT_DEVSUBTYPE_GUITAR_BASS
   18.72 +#define XINPUT_DEVSUBTYPE_GUITAR_BASS 0x0B
   18.73 +#endif
   18.74 +#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
   18.75 +#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
   18.76 +#endif
   18.77 +
   18.78 +#ifndef XINPUT_GAMEPAD_GUIDE
   18.79 +#define XINPUT_GAMEPAD_GUIDE 0x0400
   18.80 +#endif
   18.81 +
   18.82 +/* typedef's for XInput structs we use */
   18.83 +typedef struct
   18.84 +{
   18.85 +    WORD wButtons;
   18.86 +    BYTE bLeftTrigger;
   18.87 +    BYTE bRightTrigger;
   18.88 +    SHORT sThumbLX;
   18.89 +    SHORT sThumbLY;
   18.90 +    SHORT sThumbRX;
   18.91 +    SHORT sThumbRY;
   18.92 +    DWORD dwPaddingReserved;
   18.93 +} XINPUT_GAMEPAD_EX;
   18.94 +
   18.95 +typedef struct
   18.96 +{
   18.97 +    DWORD dwPacketNumber;
   18.98 +    XINPUT_GAMEPAD_EX Gamepad;
   18.99 +} XINPUT_STATE_EX;
  18.100 +
  18.101 +/* Forward decl's for XInput API's we load dynamically and use if available */
  18.102 +typedef DWORD (WINAPI *XInputGetState_t)
  18.103 +    (
  18.104 +    DWORD         dwUserIndex,  /* [in] Index of the gamer associated with the device */
  18.105 +    XINPUT_STATE_EX* pState     /* [out] Receives the current state */
  18.106 +    );
  18.107 +
  18.108 +typedef DWORD (WINAPI *XInputSetState_t)
  18.109 +    (
  18.110 +    DWORD             dwUserIndex,  /* [in] Index of the gamer associated with the device */
  18.111 +    XINPUT_VIBRATION* pVibration    /* [in, out] The vibration information to send to the controller */
  18.112 +    );
  18.113 +
  18.114 +typedef DWORD (WINAPI *XInputGetCapabilities_t)
  18.115 +    (
  18.116 +    DWORD                dwUserIndex,   /* [in] Index of the gamer associated with the device */
  18.117 +    DWORD                dwFlags,       /* [in] Input flags that identify the device type */
  18.118 +    XINPUT_CAPABILITIES* pCapabilities  /* [out] Receives the capabilities */
  18.119 +    );
  18.120 +
  18.121 +extern int WIN_LoadXInputDLL(void);
  18.122 +extern void WIN_UnloadXInputDLL(void);
  18.123 +
  18.124 +extern XInputGetState_t SDL_XInputGetState;
  18.125 +extern XInputSetState_t SDL_XInputSetState;
  18.126 +extern XInputGetCapabilities_t SDL_XInputGetCapabilities;
  18.127 +extern DWORD SDL_XInputVersion;  /* ((major << 16) & 0xFF00) | (minor & 0xFF) */
  18.128 +
  18.129 +#define XINPUTGETSTATE          SDL_XInputGetState
  18.130 +#define XINPUTSETSTATE          SDL_XInputSetState
  18.131 +#define XINPUTGETCAPABILITIES   SDL_XInputGetCapabilities
  18.132 +
  18.133 +#endif /* HAVE_XINPUT_H */
  18.134 +
  18.135 +#endif /* _SDL_xinput_h */
  18.136 +
  18.137 +/* vi: set ts=4 sw=4 expandtab: */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/haptic/windows/SDL_dinputhaptic.c	Thu Jul 03 15:39:55 2014 -0700
    19.3 @@ -0,0 +1,1293 @@
    19.4 +/*
    19.5 +  Simple DirectMedia Layer
    19.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    19.7 +
    19.8 +  This software is provided 'as-is', without any express or implied
    19.9 +  warranty.  In no event will the authors be held liable for any damages
   19.10 +  arising from the use of this software.
   19.11 +
   19.12 +  Permission is granted to anyone to use this software for any purpose,
   19.13 +  including commercial applications, and to alter it and redistribute it
   19.14 +  freely, subject to the following restrictions:
   19.15 +
   19.16 +  1. The origin of this software must not be misrepresented; you must not
   19.17 +     claim that you wrote the original software. If you use this software
   19.18 +     in a product, an acknowledgment in the product documentation would be
   19.19 +     appreciated but is not required.
   19.20 +  2. Altered source versions must be plainly marked as such, and must not be
   19.21 +     misrepresented as being the original software.
   19.22 +  3. This notice may not be removed or altered from any source distribution.
   19.23 +*/
   19.24 +#include "../../SDL_internal.h"
   19.25 +
   19.26 +#include "SDL_error.h"
   19.27 +#include "SDL_haptic.h"
   19.28 +#include "SDL_timer.h"
   19.29 +#include "SDL_windowshaptic_c.h"
   19.30 +#include "SDL_dinputhaptic_c.h"
   19.31 +#include "../SDL_syshaptic.h"
   19.32 +#include "../../joystick/windows/SDL_windowsjoystick_c.h"
   19.33 +
   19.34 +
   19.35 +#if SDL_HAPTIC_DINPUT
   19.36 +
   19.37 +/*
   19.38 + * External stuff.
   19.39 + */
   19.40 +extern HWND SDL_HelperWindow;
   19.41 +
   19.42 +
   19.43 +/*
   19.44 + * Internal stuff.
   19.45 + */
   19.46 +static SDL_bool coinitialized = SDL_FALSE;
   19.47 +static LPDIRECTINPUT8 dinput = NULL;
   19.48 +
   19.49 +
   19.50 +/*
   19.51 + * Like SDL_SetError but for DX error codes.
   19.52 + */
   19.53 +static int
   19.54 +DI_SetError(const char *str, HRESULT err)
   19.55 +{
   19.56 +    /*
   19.57 +       SDL_SetError("Haptic: %s - %s: %s", str,
   19.58 +       DXGetErrorString8A(err), DXGetErrorDescription8A(err));
   19.59 +     */
   19.60 +    return SDL_SetError("Haptic error %s", str);
   19.61 +}
   19.62 +
   19.63 +/*
   19.64 + * Checks to see if two GUID are the same.
   19.65 + */
   19.66 +static int
   19.67 +DI_GUIDIsSame(const GUID * a, const GUID * b)
   19.68 +{
   19.69 +    return (SDL_memcmp(a, b, sizeof (GUID)) == 0);
   19.70 +}
   19.71 +
   19.72 +/*
   19.73 + * Callback to find the haptic devices.
   19.74 + */
   19.75 +static BOOL CALLBACK
   19.76 +EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
   19.77 +{
   19.78 +    (void) pContext;
   19.79 +    SDL_DINPUT_MaybeAddDevice(pdidInstance);
   19.80 +    return DIENUM_CONTINUE;  /* continue enumerating */
   19.81 +}
   19.82 +
   19.83 +int
   19.84 +SDL_DINPUT_HapticInit(void)
   19.85 +{
   19.86 +    HRESULT ret;
   19.87 +    HINSTANCE instance;
   19.88 +
   19.89 +    if (dinput != NULL) {       /* Already open. */
   19.90 +        return SDL_SetError("Haptic: SubSystem already open.");
   19.91 +    }
   19.92 +
   19.93 +    ret = WIN_CoInitialize();
   19.94 +    if (FAILED(ret)) {
   19.95 +        return DI_SetError("Coinitialize", ret);
   19.96 +    }
   19.97 +
   19.98 +    coinitialized = SDL_TRUE;
   19.99 +
  19.100 +    ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
  19.101 +        &IID_IDirectInput8, (LPVOID)& dinput);
  19.102 +    if (FAILED(ret)) {
  19.103 +        SDL_SYS_HapticQuit();
  19.104 +        return DI_SetError("CoCreateInstance", ret);
  19.105 +    }
  19.106 +
  19.107 +    /* Because we used CoCreateInstance, we need to Initialize it, first. */
  19.108 +    instance = GetModuleHandle(NULL);
  19.109 +    if (instance == NULL) {
  19.110 +        SDL_SYS_HapticQuit();
  19.111 +        return SDL_SetError("GetModuleHandle() failed with error code %d.",
  19.112 +            GetLastError());
  19.113 +    }
  19.114 +    ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
  19.115 +    if (FAILED(ret)) {
  19.116 +        SDL_SYS_HapticQuit();
  19.117 +        return DI_SetError("Initializing DirectInput device", ret);
  19.118 +    }
  19.119 +
  19.120 +    /* Look for haptic devices. */
  19.121 +    ret = IDirectInput8_EnumDevices(dinput,
  19.122 +        0,
  19.123 +        EnumHapticsCallback,
  19.124 +        NULL,
  19.125 +        DIEDFL_FORCEFEEDBACK |
  19.126 +        DIEDFL_ATTACHEDONLY);
  19.127 +    if (FAILED(ret)) {
  19.128 +        SDL_SYS_HapticQuit();
  19.129 +        return DI_SetError("Enumerating DirectInput devices", ret);
  19.130 +    }
  19.131 +    return 0;
  19.132 +}
  19.133 +
  19.134 +int
  19.135 +SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
  19.136 +{
  19.137 +    HRESULT ret;
  19.138 +    LPDIRECTINPUTDEVICE8 device;
  19.139 +    const DWORD needflags = DIDC_ATTACHED | DIDC_FORCEFEEDBACK;
  19.140 +    DIDEVCAPS capabilities;
  19.141 +    SDL_hapticlist_item *item = NULL;
  19.142 +
  19.143 +    if (dinput == NULL) {
  19.144 +        return -1;  /* not initialized. We'll pick these up on enumeration if we init later. */
  19.145 +    }
  19.146 +
  19.147 +    /* Make sure we don't already have it */
  19.148 +    for (item = SDL_hapticlist; item; item = item->next) {
  19.149 +        if ((!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0)) {
  19.150 +            return -1;  /* Already added */
  19.151 +        }
  19.152 +    }
  19.153 +
  19.154 +    /* Open the device */
  19.155 +    ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL);
  19.156 +    if (FAILED(ret)) {
  19.157 +        /* DI_SetError("Creating DirectInput device",ret); */
  19.158 +        return -1;
  19.159 +    }
  19.160 +
  19.161 +    /* Get capabilities. */
  19.162 +    SDL_zero(capabilities);
  19.163 +    capabilities.dwSize = sizeof(DIDEVCAPS);
  19.164 +    ret = IDirectInputDevice8_GetCapabilities(device, &capabilities);
  19.165 +    IDirectInputDevice8_Release(device);
  19.166 +    if (FAILED(ret)) {
  19.167 +        /* DI_SetError("Getting device capabilities",ret); */
  19.168 +        return -1;
  19.169 +    }
  19.170 +
  19.171 +    if ((capabilities.dwFlags & needflags) != needflags) {
  19.172 +        return -1;  /* not a device we can use. */
  19.173 +    }
  19.174 +
  19.175 +    item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item));
  19.176 +    if (item == NULL) {
  19.177 +        return SDL_OutOfMemory();
  19.178 +    }
  19.179 +
  19.180 +    item->name = WIN_StringToUTF8(pdidInstance->tszProductName);
  19.181 +    if (!item->name) {
  19.182 +        SDL_free(item);
  19.183 +        return -1;
  19.184 +    }
  19.185 +
  19.186 +    /* Copy the instance over, useful for creating devices. */
  19.187 +    SDL_memcpy(&item->instance, pdidInstance, sizeof(DIDEVICEINSTANCE));
  19.188 +    SDL_memcpy(&item->capabilities, &capabilities, sizeof(capabilities));
  19.189 +
  19.190 +    return SDL_SYS_AddHapticDevice(item);
  19.191 +}
  19.192 +
  19.193 +int
  19.194 +SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
  19.195 +{
  19.196 +    SDL_hapticlist_item *item;
  19.197 +    SDL_hapticlist_item *prev = NULL;
  19.198 +
  19.199 +    if (dinput == NULL) {
  19.200 +        return -1;  /* not initialized, ignore this. */
  19.201 +    }
  19.202 +
  19.203 +    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  19.204 +        if (!item->bXInputHaptic && SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) {
  19.205 +            /* found it, remove it. */
  19.206 +            return SDL_SYS_RemoveHapticDevice(prev, item);
  19.207 +        }
  19.208 +        prev = item;
  19.209 +    }
  19.210 +    return -1;
  19.211 +}
  19.212 +
  19.213 +/*
  19.214 + * Callback to get supported axes.
  19.215 + */
  19.216 +static BOOL CALLBACK
  19.217 +DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
  19.218 +{
  19.219 +    SDL_Haptic *haptic = (SDL_Haptic *) pvRef;
  19.220 +
  19.221 +    if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) {
  19.222 +        const GUID *guid = &dev->guidType;
  19.223 +        DWORD offset = 0;
  19.224 +        if (DI_GUIDIsSame(guid, &GUID_XAxis)) {
  19.225 +            offset = DIJOFS_X;
  19.226 +        } else if (DI_GUIDIsSame(guid, &GUID_YAxis)) {
  19.227 +            offset = DIJOFS_Y;
  19.228 +        } else if (DI_GUIDIsSame(guid, &GUID_ZAxis)) {
  19.229 +            offset = DIJOFS_Z;
  19.230 +        } else if (DI_GUIDIsSame(guid, &GUID_RxAxis)) {
  19.231 +            offset = DIJOFS_RX;
  19.232 +        } else if (DI_GUIDIsSame(guid, &GUID_RyAxis)) {
  19.233 +            offset = DIJOFS_RY;
  19.234 +        } else if (DI_GUIDIsSame(guid, &GUID_RzAxis)) {
  19.235 +            offset = DIJOFS_RZ;
  19.236 +        } else {
  19.237 +            return DIENUM_CONTINUE;   /* can't use this, go on. */
  19.238 +        }
  19.239 +
  19.240 +        haptic->hwdata->axes[haptic->naxes] = offset;
  19.241 +        haptic->naxes++;
  19.242 +
  19.243 +        /* Currently using the artificial limit of 3 axes. */
  19.244 +        if (haptic->naxes >= 3) {
  19.245 +            return DIENUM_STOP;
  19.246 +        }
  19.247 +    }
  19.248 +
  19.249 +    return DIENUM_CONTINUE;
  19.250 +}
  19.251 +
  19.252 +/*
  19.253 + * Callback to get all supported effects.
  19.254 + */
  19.255 +#define EFFECT_TEST(e,s)               \
  19.256 +if (DI_GUIDIsSame(&pei->guid, &(e)))   \
  19.257 +   haptic->supported |= (s)
  19.258 +static BOOL CALLBACK
  19.259 +DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
  19.260 +{
  19.261 +    /* Prepare the haptic device. */
  19.262 +    SDL_Haptic *haptic = (SDL_Haptic *) pv;
  19.263 +
  19.264 +    /* Get supported. */
  19.265 +    EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING);
  19.266 +    EFFECT_TEST(GUID_Damper, SDL_HAPTIC_DAMPER);
  19.267 +    EFFECT_TEST(GUID_Inertia, SDL_HAPTIC_INERTIA);
  19.268 +    EFFECT_TEST(GUID_Friction, SDL_HAPTIC_FRICTION);
  19.269 +    EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
  19.270 +    EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
  19.271 +    EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
  19.272 +    /* !!! FIXME: put this back when we have more bits in 2.1 */
  19.273 +    /* EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE); */
  19.274 +    EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
  19.275 +    EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
  19.276 +    EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
  19.277 +    EFFECT_TEST(GUID_RampForce, SDL_HAPTIC_RAMP);
  19.278 +
  19.279 +    /* Check for more. */
  19.280 +    return DIENUM_CONTINUE;
  19.281 +}
  19.282 +
  19.283 +/*
  19.284 + * Opens the haptic device.
  19.285 + *
  19.286 + *    Steps:
  19.287 + *       - Set cooperative level.
  19.288 + *       - Set data format.
  19.289 + *       - Acquire exclusiveness.
  19.290 + *       - Reset actuators.
  19.291 + *       - Get supported features.
  19.292 + */
  19.293 +static int
  19.294 +SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick)
  19.295 +{
  19.296 +    HRESULT ret;
  19.297 +    DIPROPDWORD dipdw;
  19.298 +
  19.299 +    /* Allocate the hwdata */
  19.300 +    haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata));
  19.301 +    if (haptic->hwdata == NULL) {
  19.302 +        return SDL_OutOfMemory();
  19.303 +    }
  19.304 +    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
  19.305 +
  19.306 +    /* We'll use the device8 from now on. */
  19.307 +    haptic->hwdata->device = device8;
  19.308 +    haptic->hwdata->is_joystick = is_joystick;
  19.309 +
  19.310 +    /* !!! FIXME: opening a haptic device here first will make an attempt to
  19.311 +       !!! FIXME:  SDL_JoystickOpen() that same device fail later, since we
  19.312 +       !!! FIXME:  have it open in exclusive mode. But this will allow
  19.313 +       !!! FIXME:  SDL_JoystickOpen() followed by SDL_HapticOpenFromJoystick()
  19.314 +       !!! FIXME:  to work, and that's probably the common case. Still,
  19.315 +       !!! FIXME:  ideally, We need to unify the opening code. */
  19.316 +
  19.317 +    if (!is_joystick) {  /* if is_joystick, we already set this up elsewhere. */
  19.318 +        /* Grab it exclusively to use force feedback stuff. */
  19.319 +        ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device,
  19.320 +                                                      SDL_HelperWindow,
  19.321 +                                                      DISCL_EXCLUSIVE |
  19.322 +                                                      DISCL_BACKGROUND);
  19.323 +        if (FAILED(ret)) {
  19.324 +            DI_SetError("Setting cooperative level to exclusive", ret);
  19.325 +            goto acquire_err;
  19.326 +        }
  19.327 +
  19.328 +        /* Set data format. */
  19.329 +        ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device,
  19.330 +                                                &c_dfDIJoystick2);
  19.331 +        if (FAILED(ret)) {
  19.332 +            DI_SetError("Setting data format", ret);
  19.333 +            goto acquire_err;
  19.334 +        }
  19.335 +
  19.336 +        /* Get number of axes. */
  19.337 +        ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device,
  19.338 +                                              DI_DeviceObjectCallback,
  19.339 +                                              haptic, DIDFT_AXIS);
  19.340 +        if (FAILED(ret)) {
  19.341 +            DI_SetError("Getting device axes", ret);
  19.342 +            goto acquire_err;
  19.343 +        }
  19.344 +
  19.345 +        /* Acquire the device. */
  19.346 +        ret = IDirectInputDevice8_Acquire(haptic->hwdata->device);
  19.347 +        if (FAILED(ret)) {
  19.348 +            DI_SetError("Acquiring DirectInput device", ret);
  19.349 +            goto acquire_err;
  19.350 +        }
  19.351 +    }
  19.352 +
  19.353 +    /* Reset all actuators - just in case. */
  19.354 +    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
  19.355 +                                                       DISFFC_RESET);
  19.356 +    if (FAILED(ret)) {
  19.357 +        DI_SetError("Resetting device", ret);
  19.358 +        goto acquire_err;
  19.359 +    }
  19.360 +
  19.361 +    /* Enabling actuators. */
  19.362 +    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
  19.363 +                                                       DISFFC_SETACTUATORSON);
  19.364 +    if (FAILED(ret)) {
  19.365 +        DI_SetError("Enabling actuators", ret);
  19.366 +        goto acquire_err;
  19.367 +    }
  19.368 +
  19.369 +    /* Get supported effects. */
  19.370 +    ret = IDirectInputDevice8_EnumEffects(haptic->hwdata->device,
  19.371 +                                          DI_EffectCallback, haptic,
  19.372 +                                          DIEFT_ALL);
  19.373 +    if (FAILED(ret)) {
  19.374 +        DI_SetError("Enumerating supported effects", ret);
  19.375 +        goto acquire_err;
  19.376 +    }
  19.377 +    if (haptic->supported == 0) {       /* Error since device supports nothing. */
  19.378 +        SDL_SetError("Haptic: Internal error on finding supported effects.");
  19.379 +        goto acquire_err;
  19.380 +    }
  19.381 +
  19.382 +    /* Check autogain and autocenter. */
  19.383 +    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  19.384 +    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  19.385 +    dipdw.diph.dwObj = 0;
  19.386 +    dipdw.diph.dwHow = DIPH_DEVICE;
  19.387 +    dipdw.dwData = 10000;
  19.388 +    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
  19.389 +                                          DIPROP_FFGAIN, &dipdw.diph);
  19.390 +    if (!FAILED(ret)) {         /* Gain is supported. */
  19.391 +        haptic->supported |= SDL_HAPTIC_GAIN;
  19.392 +    }
  19.393 +    dipdw.diph.dwObj = 0;
  19.394 +    dipdw.diph.dwHow = DIPH_DEVICE;
  19.395 +    dipdw.dwData = DIPROPAUTOCENTER_OFF;
  19.396 +    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
  19.397 +                                          DIPROP_AUTOCENTER, &dipdw.diph);
  19.398 +    if (!FAILED(ret)) {         /* Autocenter is supported. */
  19.399 +        haptic->supported |= SDL_HAPTIC_AUTOCENTER;
  19.400 +    }
  19.401 +
  19.402 +    /* Status is always supported. */
  19.403 +    haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;
  19.404 +
  19.405 +    /* Check maximum effects. */
  19.406 +    haptic->neffects = 128;     /* This is not actually supported as thus under windows,
  19.407 +                                   there is no way to tell the number of EFFECTS that a
  19.408 +                                   device can hold, so we'll just use a "random" number
  19.409 +                                   instead and put warnings in SDL_haptic.h */
  19.410 +    haptic->nplaying = 128;     /* Even more impossible to get this then neffects. */
  19.411 +
  19.412 +    /* Prepare effects memory. */
  19.413 +    haptic->effects = (struct haptic_effect *)
  19.414 +        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
  19.415 +    if (haptic->effects == NULL) {
  19.416 +        SDL_OutOfMemory();
  19.417 +        goto acquire_err;
  19.418 +    }
  19.419 +    /* Clear the memory */
  19.420 +    SDL_memset(haptic->effects, 0,
  19.421 +               sizeof(struct haptic_effect) * haptic->neffects);
  19.422 +
  19.423 +    return 0;
  19.424 +
  19.425 +    /* Error handling */
  19.426 +  acquire_err:
  19.427 +    IDirectInputDevice8_Unacquire(haptic->hwdata->device);
  19.428 +    return -1;
  19.429 +}
  19.430 +
  19.431 +int
  19.432 +SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
  19.433 +{
  19.434 +    HRESULT ret;
  19.435 +    LPDIRECTINPUTDEVICE8 device;
  19.436 +    LPDIRECTINPUTDEVICE8 device8;
  19.437 +
  19.438 +    /* Open the device */
  19.439 +    ret = IDirectInput8_CreateDevice(dinput, &item->instance.guidInstance,
  19.440 +        &device, NULL);
  19.441 +    if (FAILED(ret)) {
  19.442 +        DI_SetError("Creating DirectInput device", ret);
  19.443 +        return -1;
  19.444 +    }
  19.445 +
  19.446 +    /* Now get the IDirectInputDevice8 interface, instead. */
  19.447 +    ret = IDirectInputDevice8_QueryInterface(device,
  19.448 +        &IID_IDirectInputDevice8,
  19.449 +        (LPVOID *)&device8);
  19.450 +    /* Done with the temporary one now. */
  19.451 +    IDirectInputDevice8_Release(device);
  19.452 +    if (FAILED(ret)) {
  19.453 +        DI_SetError("Querying DirectInput interface", ret);
  19.454 +        return -1;
  19.455 +    }
  19.456 +
  19.457 +    if (SDL_DINPUT_HapticOpenFromDevice(haptic, device8, SDL_FALSE) < 0) {
  19.458 +        IDirectInputDevice8_Release(device8);
  19.459 +        return -1;
  19.460 +    }
  19.461 +    return 0;
  19.462 +}
  19.463 +
  19.464 +int
  19.465 +SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
  19.466 +{
  19.467 +    HRESULT ret;
  19.468 +    DIDEVICEINSTANCE hap_instance, joy_instance;
  19.469 +
  19.470 +    hap_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  19.471 +    joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  19.472 +
  19.473 +    /* Get the device instances. */
  19.474 +    ret = IDirectInputDevice8_GetDeviceInfo(haptic->hwdata->device,
  19.475 +        &hap_instance);
  19.476 +    if (FAILED(ret)) {
  19.477 +        return 0;
  19.478 +    }
  19.479 +    ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice,
  19.480 +        &joy_instance);
  19.481 +    if (FAILED(ret)) {
  19.482 +        return 0;
  19.483 +    }
  19.484 +
  19.485 +    return DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance);
  19.486 +}
  19.487 +
  19.488 +int
  19.489 +SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
  19.490 +{
  19.491 +    SDL_hapticlist_item *item;
  19.492 +    int index = 0;
  19.493 +    HRESULT ret;
  19.494 +    DIDEVICEINSTANCE joy_instance;
  19.495 +
  19.496 +    joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  19.497 +    ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
  19.498 +    if (FAILED(ret)) {
  19.499 +        return -1;
  19.500 +    }
  19.501 +
  19.502 +    /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
  19.503 +    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  19.504 +        if (!item->bXInputHaptic && DI_GUIDIsSame(&item->instance.guidInstance, &joy_instance.guidInstance)) {
  19.505 +            haptic->index = index;
  19.506 +            return SDL_DINPUT_HapticOpenFromDevice(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
  19.507 +        }
  19.508 +        ++index;
  19.509 +    }
  19.510 +
  19.511 +    SDL_SetError("Couldn't find joystick in haptic device list");
  19.512 +    return -1;
  19.513 +}
  19.514 +
  19.515 +void
  19.516 +SDL_DINPUT_HapticClose(SDL_Haptic * haptic)
  19.517 +{
  19.518 +    IDirectInputDevice8_Unacquire(haptic->hwdata->device);
  19.519 +
  19.520 +    /* Only release if isn't grabbed by a joystick. */
  19.521 +    if (haptic->hwdata->is_joystick == 0) {
  19.522 +        IDirectInputDevice8_Release(haptic->hwdata->device);
  19.523 +    }
  19.524 +}
  19.525 +
  19.526 +void
  19.527 +SDL_DINPUT_HapticQuit(void)
  19.528 +{
  19.529 +    if (dinput != NULL) {
  19.530 +        IDirectInput8_Release(dinput);
  19.531 +        dinput = NULL;
  19.532 +    }
  19.533 +
  19.534 +    if (coinitialized) {
  19.535 +        WIN_CoUninitialize();
  19.536 +        coinitialized = SDL_FALSE;
  19.537 +    }
  19.538 +}
  19.539 +
  19.540 +/*
  19.541 + * Converts an SDL trigger button to an DIEFFECT trigger button.
  19.542 + */
  19.543 +static DWORD
  19.544 +DIGetTriggerButton(Uint16 button)
  19.545 +{
  19.546 +    DWORD dwTriggerButton;
  19.547 +
  19.548 +    dwTriggerButton = DIEB_NOTRIGGER;
  19.549 +
  19.550 +    if (button != 0) {
  19.551 +        dwTriggerButton = DIJOFS_BUTTON(button - 1);
  19.552 +    }
  19.553 +
  19.554 +    return dwTriggerButton;
  19.555 +}
  19.556 +
  19.557 +
  19.558 +/*
  19.559 + * Sets the direction.
  19.560 + */
  19.561 +static int
  19.562 +SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes)
  19.563 +{
  19.564 +    LONG *rglDir;
  19.565 +
  19.566 +    /* Handle no axes a part. */
  19.567 +    if (naxes == 0) {
  19.568 +        effect->dwFlags |= DIEFF_SPHERICAL;     /* Set as default. */
  19.569 +        effect->rglDirection = NULL;
  19.570 +        return 0;
  19.571 +    }
  19.572 +
  19.573 +    /* Has axes. */
  19.574 +    rglDir = SDL_malloc(sizeof(LONG) * naxes);
  19.575 +    if (rglDir == NULL) {
  19.576 +        return SDL_OutOfMemory();
  19.577 +    }
  19.578 +    SDL_memset(rglDir, 0, sizeof(LONG) * naxes);
  19.579 +    effect->rglDirection = rglDir;
  19.580 +
  19.581 +    switch (dir->type) {
  19.582 +    case SDL_HAPTIC_POLAR:
  19.583 +        effect->dwFlags |= DIEFF_POLAR;
  19.584 +        rglDir[0] = dir->dir[0];
  19.585 +        return 0;
  19.586 +    case SDL_HAPTIC_CARTESIAN:
  19.587 +        effect->dwFlags |= DIEFF_CARTESIAN;
  19.588 +        rglDir[0] = dir->dir[0];
  19.589 +        if (naxes > 1)
  19.590 +            rglDir[1] = dir->dir[1];
  19.591 +        if (naxes > 2)
  19.592 +            rglDir[2] = dir->dir[2];
  19.593 +        return 0;
  19.594 +    case SDL_HAPTIC_SPHERICAL:
  19.595 +        effect->dwFlags |= DIEFF_SPHERICAL;
  19.596 +        rglDir[0] = dir->dir[0];
  19.597 +        if (naxes > 1)
  19.598 +            rglDir[1] = dir->dir[1];
  19.599 +        if (naxes > 2)
  19.600 +            rglDir[2] = dir->dir[2];
  19.601 +        return 0;
  19.602 +
  19.603 +    default:
  19.604 +        return SDL_SetError("Haptic: Unknown direction type.");
  19.605 +    }
  19.606 +}
  19.607 +
  19.608 +#define CONVERT(x)   (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF)
  19.609 +/*
  19.610 + * Creates the DIEFFECT from a SDL_HapticEffect.
  19.611 + */
  19.612 +static int
  19.613 +SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
  19.614 +                   SDL_HapticEffect * src)
  19.615 +{
  19.616 +    int i;
  19.617 +    DICONSTANTFORCE *constant;
  19.618 +    DIPERIODIC *periodic;
  19.619 +    DICONDITION *condition;     /* Actually an array of conditions - one per axis. */
  19.620 +    DIRAMPFORCE *ramp;
  19.621 +    DICUSTOMFORCE *custom;
  19.622 +    DIENVELOPE *envelope;
  19.623 +    SDL_HapticConstant *hap_constant;
  19.624 +    SDL_HapticPeriodic *hap_periodic;
  19.625 +    SDL_HapticCondition *hap_condition;
  19.626 +    SDL_HapticRamp *hap_ramp;
  19.627 +    SDL_HapticCustom *hap_custom;
  19.628 +    DWORD *axes;
  19.629 +
  19.630 +    /* Set global stuff. */
  19.631 +    SDL_memset(dest, 0, sizeof(DIEFFECT));
  19.632 +    dest->dwSize = sizeof(DIEFFECT);    /* Set the structure size. */
  19.633 +    dest->dwSamplePeriod = 0;   /* Not used by us. */
  19.634 +    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
  19.635 +    dest->dwFlags = DIEFF_OBJECTOFFSETS;        /* Seems obligatory. */
  19.636 +
  19.637 +    /* Envelope. */
  19.638 +    envelope = SDL_malloc(sizeof(DIENVELOPE));
  19.639 +    if (envelope == NULL) {
  19.640 +        return SDL_OutOfMemory();
  19.641 +    }
  19.642 +    SDL_memset(envelope, 0, sizeof(DIENVELOPE));
  19.643 +    dest->lpEnvelope = envelope;
  19.644 +    envelope->dwSize = sizeof(DIENVELOPE);      /* Always should be this. */
  19.645 +
  19.646 +    /* Axes. */
  19.647 +    dest->cAxes = haptic->naxes;
  19.648 +    if (dest->cAxes > 0) {
  19.649 +        axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
  19.650 +        if (axes == NULL) {
  19.651 +            return SDL_OutOfMemory();
  19.652 +        }
  19.653 +        axes[0] = haptic->hwdata->axes[0];      /* Always at least one axis. */
  19.654 +        if (dest->cAxes > 1) {
  19.655 +            axes[1] = haptic->hwdata->axes[1];
  19.656 +        }
  19.657 +        if (dest->cAxes > 2) {
  19.658 +            axes[2] = haptic->hwdata->axes[2];
  19.659 +        }
  19.660 +        dest->rgdwAxes = axes;
  19.661 +    }
  19.662 +
  19.663 +    /* The big type handling switch, even bigger than Linux's version. */
  19.664 +    switch (src->type) {
  19.665 +    case SDL_HAPTIC_CONSTANT:
  19.666 +        hap_constant = &src->constant;
  19.667 +        constant = SDL_malloc(sizeof(DICONSTANTFORCE));
  19.668 +        if (constant == NULL) {
  19.669 +            return SDL_OutOfMemory();
  19.670 +        }
  19.671 +        SDL_memset(constant, 0, sizeof(DICONSTANTFORCE));
  19.672 +
  19.673 +        /* Specifics */
  19.674 +        constant->lMagnitude = CONVERT(hap_constant->level);
  19.675 +        dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
  19.676 +        dest->lpvTypeSpecificParams = constant;
  19.677 +
  19.678 +        /* Generics */
  19.679 +        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
  19.680 +        dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button);
  19.681 +        dest->dwTriggerRepeatInterval = hap_constant->interval;
  19.682 +        dest->dwStartDelay = hap_constant->delay * 1000;        /* In microseconds. */
  19.683 +
  19.684 +        /* Direction. */
  19.685 +        if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) {
  19.686 +            return -1;
  19.687 +        }
  19.688 +
  19.689 +        /* Envelope */
  19.690 +        if ((hap_constant->attack_length == 0)
  19.691 +            && (hap_constant->fade_length == 0)) {
  19.692 +            SDL_free(dest->lpEnvelope);
  19.693 +            dest->lpEnvelope = NULL;
  19.694 +        } else {
  19.695 +            envelope->dwAttackLevel = CONVERT(hap_constant->attack_level);
  19.696 +            envelope->dwAttackTime = hap_constant->attack_length * 1000;
  19.697 +            envelope->dwFadeLevel = CONVERT(hap_constant->fade_level);
  19.698 +            envelope->dwFadeTime = hap_constant->fade_length * 1000;
  19.699 +        }
  19.700 +
  19.701 +        break;
  19.702 +
  19.703 +    case SDL_HAPTIC_SINE:
  19.704 +    /* !!! FIXME: put this back when we have more bits in 2.1 */
  19.705 +    /* case SDL_HAPTIC_SQUARE: */
  19.706 +    case SDL_HAPTIC_TRIANGLE:
  19.707 +    case SDL_HAPTIC_SAWTOOTHUP:
  19.708 +    case SDL_HAPTIC_SAWTOOTHDOWN:
  19.709 +        hap_periodic = &src->periodic;
  19.710 +        periodic = SDL_malloc(sizeof(DIPERIODIC));
  19.711 +        if (periodic == NULL) {
  19.712 +            return SDL_OutOfMemory();
  19.713 +        }
  19.714 +        SDL_memset(periodic, 0, sizeof(DIPERIODIC));
  19.715 +
  19.716 +        /* Specifics */
  19.717 +        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
  19.718 +        periodic->lOffset = CONVERT(hap_periodic->offset);
  19.719 +        periodic->dwPhase = hap_periodic->phase;
  19.720 +        periodic->dwPeriod = hap_periodic->period * 1000;
  19.721 +        dest->cbTypeSpecificParams = sizeof(DIPERIODIC);
  19.722 +        dest->lpvTypeSpecificParams = periodic;
  19.723 +
  19.724 +        /* Generics */
  19.725 +        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
  19.726 +        dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button);
  19.727 +        dest->dwTriggerRepeatInterval = hap_periodic->interval;
  19.728 +        dest->dwStartDelay = hap_periodic->delay * 1000;        /* In microseconds. */
  19.729 +
  19.730 +        /* Direction. */
  19.731 +        if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
  19.732 +            < 0) {
  19.733 +            return -1;
  19.734 +        }
  19.735 +
  19.736 +        /* Envelope */
  19.737 +        if ((hap_periodic->attack_length == 0)
  19.738 +            && (hap_periodic->fade_length == 0)) {
  19.739 +            SDL_free(dest->lpEnvelope);
  19.740 +            dest->lpEnvelope = NULL;
  19.741 +        } else {
  19.742 +            envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level);
  19.743 +            envelope->dwAttackTime = hap_periodic->attack_length * 1000;
  19.744 +            envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level);
  19.745 +            envelope->dwFadeTime = hap_periodic->fade_length * 1000;
  19.746 +        }
  19.747 +
  19.748 +        break;
  19.749 +
  19.750 +    case SDL_HAPTIC_SPRING:
  19.751 +    case SDL_HAPTIC_DAMPER:
  19.752 +    case SDL_HAPTIC_INERTIA:
  19.753 +    case SDL_HAPTIC_FRICTION:
  19.754 +        hap_condition = &src->condition;
  19.755 +        condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes);
  19.756 +        if (condition == NULL) {
  19.757 +            return SDL_OutOfMemory();
  19.758 +        }
  19.759 +        SDL_memset(condition, 0, sizeof(DICONDITION));
  19.760 +
  19.761 +        /* Specifics */
  19.762 +        for (i = 0; i < (int) dest->cAxes; i++) {
  19.763 +            condition[i].lOffset = CONVERT(hap_condition->center[i]);
  19.764 +            condition[i].lPositiveCoefficient =
  19.765 +                CONVERT(hap_condition->right_coeff[i]);
  19.766 +            condition[i].lNegativeCoefficient =
  19.767 +                CONVERT(hap_condition->left_coeff[i]);
  19.768 +            condition[i].dwPositiveSaturation =
  19.769 +                CONVERT(hap_condition->right_sat[i]);
  19.770 +            condition[i].dwNegativeSaturation =
  19.771 +                CONVERT(hap_condition->left_sat[i]);
  19.772 +            condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]);
  19.773 +        }
  19.774 +        dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes;
  19.775 +        dest->lpvTypeSpecificParams = condition;
  19.776 +
  19.777 +        /* Generics */
  19.778 +        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
  19.779 +        dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button);
  19.780 +        dest->dwTriggerRepeatInterval = hap_condition->interval;
  19.781 +        dest->dwStartDelay = hap_condition->delay * 1000;       /* In microseconds. */
  19.782 +
  19.783 +        /* Direction. */
  19.784 +        if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
  19.785 +            < 0) {
  19.786 +            return -1;
  19.787 +        }
  19.788 +
  19.789 +        /* Envelope - Not actually supported by most CONDITION implementations. */
  19.790 +        SDL_free(dest->lpEnvelope);
  19.791 +        dest->lpEnvelope = NULL;
  19.792 +
  19.793 +        break;
  19.794 +
  19.795 +    case SDL_HAPTIC_RAMP:
  19.796 +        hap_ramp = &src->ramp;
  19.797 +        ramp = SDL_malloc(sizeof(DIRAMPFORCE));
  19.798 +        if (ramp == NULL) {
  19.799 +            return SDL_OutOfMemory();
  19.800 +        }
  19.801 +        SDL_memset(ramp, 0, sizeof(DIRAMPFORCE));
  19.802 +
  19.803 +        /* Specifics */
  19.804 +        ramp->lStart = CONVERT(hap_ramp->start);
  19.805 +        ramp->lEnd = CONVERT(hap_ramp->end);
  19.806 +        dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE);
  19.807 +        dest->lpvTypeSpecificParams = ramp;
  19.808 +
  19.809 +        /* Generics */
  19.810 +        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
  19.811 +        dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button);
  19.812 +        dest->dwTriggerRepeatInterval = hap_ramp->interval;
  19.813 +        dest->dwStartDelay = hap_ramp->delay * 1000;    /* In microseconds. */
  19.814 +
  19.815 +        /* Direction. */
  19.816 +        if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
  19.817 +            return -1;
  19.818 +        }
  19.819 +
  19.820 +        /* Envelope */
  19.821 +        if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
  19.822 +            SDL_free(dest->lpEnvelope);
  19.823 +            dest->lpEnvelope = NULL;
  19.824 +        } else {
  19.825 +            envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level);
  19.826 +            envelope->dwAttackTime = hap_ramp->attack_length * 1000;
  19.827 +            envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level);
  19.828 +            envelope->dwFadeTime = hap_ramp->fade_length * 1000;
  19.829 +        }
  19.830 +
  19.831 +        break;
  19.832 +
  19.833 +    case SDL_HAPTIC_CUSTOM:
  19.834 +        hap_custom = &src->custom;
  19.835 +        custom = SDL_malloc(sizeof(DICUSTOMFORCE));
  19.836 +        if (custom == NULL) {
  19.837 +            return SDL_OutOfMemory();
  19.838 +        }
  19.839 +        SDL_memset(custom, 0, sizeof(DICUSTOMFORCE));
  19.840 +
  19.841 +        /* Specifics */
  19.842 +        custom->cChannels = hap_custom->channels;
  19.843 +        custom->dwSamplePeriod = hap_custom->period * 1000;
  19.844 +        custom->cSamples = hap_custom->samples;
  19.845 +        custom->rglForceData =
  19.846 +            SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
  19.847 +        for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) {      /* Copy data. */
  19.848 +            custom->rglForceData[i] = CONVERT(hap_custom->data[i]);
  19.849 +        }
  19.850 +        dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE);
  19.851 +        dest->lpvTypeSpecificParams = custom;
  19.852 +
  19.853 +        /* Generics */
  19.854 +        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
  19.855 +        dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button);
  19.856 +        dest->dwTriggerRepeatInterval = hap_custom->interval;
  19.857 +        dest->dwStartDelay = hap_custom->delay * 1000;  /* In microseconds. */
  19.858 +
  19.859 +        /* Direction. */
  19.860 +        if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) {
  19.861 +            return -1;
  19.862 +        }
  19.863 +
  19.864 +        /* Envelope */
  19.865 +        if ((hap_custom->attack_length == 0)
  19.866 +            && (hap_custom->fade_length == 0)) {
  19.867 +            SDL_free(dest->lpEnvelope);
  19.868 +            dest->lpEnvelope = NULL;
  19.869 +        } else {
  19.870 +            envelope->dwAttackLevel = CONVERT(hap_custom->attack_level);
  19.871 +            envelope->dwAttackTime = hap_custom->attack_length * 1000;
  19.872 +            envelope->dwFadeLevel = CONVERT(hap_custom->fade_level);
  19.873 +            envelope->dwFadeTime = hap_custom->fade_length * 1000;
  19.874 +        }
  19.875 +
  19.876 +        break;
  19.877 +
  19.878 +    default:
  19.879 +        return SDL_SetError("Haptic: Unknown effect type.");
  19.880 +    }
  19.881 +
  19.882 +    return 0;
  19.883 +}
  19.884 +
  19.885 +
  19.886 +/*
  19.887 + * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT.
  19.888 + */
  19.889 +static void
  19.890 +SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type)
  19.891 +{
  19.892 +    DICUSTOMFORCE *custom;
  19.893 +
  19.894 +    SDL_free(effect->lpEnvelope);
  19.895 +    effect->lpEnvelope = NULL;
  19.896 +    SDL_free(effect->rgdwAxes);
  19.897 +    effect->rgdwAxes = NULL;
  19.898 +    if (effect->lpvTypeSpecificParams != NULL) {
  19.899 +        if (type == SDL_HAPTIC_CUSTOM) {        /* Must free the custom data. */
  19.900 +            custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams;
  19.901 +            SDL_free(custom->rglForceData);
  19.902 +            custom->rglForceData = NULL;
  19.903 +        }
  19.904 +        SDL_free(effect->lpvTypeSpecificParams);
  19.905 +        effect->lpvTypeSpecificParams = NULL;
  19.906 +    }
  19.907 +    SDL_free(effect->rglDirection);
  19.908 +    effect->rglDirection = NULL;
  19.909 +}
  19.910 +
  19.911 +/*
  19.912 + * Gets the effect type from the generic SDL haptic effect wrapper.
  19.913 + */
  19.914 +static REFGUID
  19.915 +SDL_SYS_HapticEffectType(SDL_HapticEffect * effect)
  19.916 +{
  19.917 +    switch (effect->type) {
  19.918 +    case SDL_HAPTIC_CONSTANT:
  19.919 +        return &GUID_ConstantForce;
  19.920 +
  19.921 +    case SDL_HAPTIC_RAMP:
  19.922 +        return &GUID_RampForce;
  19.923 +
  19.924 +    /* !!! FIXME: put this back when we have more bits in 2.1 */
  19.925 +    /* case SDL_HAPTIC_SQUARE:
  19.926 +        return &GUID_Square; */
  19.927 +
  19.928 +    case SDL_HAPTIC_SINE:
  19.929 +        return &GUID_Sine;
  19.930 +
  19.931 +    case SDL_HAPTIC_TRIANGLE:
  19.932 +        return &GUID_Triangle;
  19.933 +
  19.934 +    case SDL_HAPTIC_SAWTOOTHUP:
  19.935 +        return &GUID_SawtoothUp;
  19.936 +
  19.937 +    case SDL_HAPTIC_SAWTOOTHDOWN:
  19.938 +        return &GUID_SawtoothDown;
  19.939 +
  19.940 +    case SDL_HAPTIC_SPRING:
  19.941 +        return &GUID_Spring;
  19.942 +
  19.943 +    case SDL_HAPTIC_DAMPER:
  19.944 +        return &GUID_Damper;
  19.945 +
  19.946 +    case SDL_HAPTIC_INERTIA:
  19.947 +        return &GUID_Inertia;
  19.948 +
  19.949 +    case SDL_HAPTIC_FRICTION:
  19.950 +        return &GUID_Friction;
  19.951 +
  19.952 +    case SDL_HAPTIC_CUSTOM:
  19.953 +        return &GUID_CustomForce;
  19.954 +
  19.955 +    default:
  19.956 +        return NULL;
  19.957 +    }
  19.958 +}
  19.959 +int
  19.960 +SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
  19.961 +{
  19.962 +    HRESULT ret;
  19.963 +    REFGUID type = SDL_SYS_HapticEffectType(base);
  19.964 +
  19.965 +    if (type == NULL) {
  19.966 +        SDL_SetError("Haptic: Unknown effect type.");
  19.967 +        return -1;
  19.968 +    }
  19.969 +
  19.970 +    /* Get the effect. */
  19.971 +    if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) {
  19.972 +        goto err_effectdone;
  19.973 +    }
  19.974 +
  19.975 +    /* Create the actual effect. */
  19.976 +    ret = IDirectInputDevice8_CreateEffect(haptic->hwdata->device, type,
  19.977 +        &effect->hweffect->effect,
  19.978 +        &effect->hweffect->ref, NULL);
  19.979 +    if (FAILED(ret)) {
  19.980 +        DI_SetError("Unable to create effect", ret);
  19.981 +        goto err_effectdone;
  19.982 +    }
  19.983 +
  19.984 +    return 0;
  19.985 +
  19.986 +err_effectdone:
  19.987 +    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type);
  19.988 +    return -1;
  19.989 +}
  19.990 +
  19.991 +int
  19.992 +SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
  19.993 +{
  19.994 +    HRESULT ret;
  19.995 +    DWORD flags;
  19.996 +    DIEFFECT temp;
  19.997 +
  19.998 +    /* Get the effect. */
  19.999 +    SDL_memset(&temp, 0, sizeof(DIEFFECT));
 19.1000 +    if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) {
 19.1001 +        goto err_update;
 19.1002 +    }
 19.1003 +
 19.1004 +    /* Set the flags.  Might be worthwhile to diff temp with loaded effect and
 19.1005 +    *  only change those parameters. */
 19.1006 +    flags = DIEP_DIRECTION |
 19.1007 +        DIEP_DURATION |
 19.1008 +        DIEP_ENVELOPE |
 19.1009 +        DIEP_STARTDELAY |
 19.1010 +        DIEP_TRIGGERBUTTON |
 19.1011 +        DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS;
 19.1012 +
 19.1013 +    /* Create the actual effect. */
 19.1014 +    ret =
 19.1015 +        IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags);
 19.1016 +    if (FAILED(ret)) {
 19.1017 +        DI_SetError("Unable to update effect", ret);
 19.1018 +        goto err_update;
 19.1019 +    }
 19.1020 +
 19.1021 +    /* Copy it over. */
 19.1022 +    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type);
 19.1023 +    SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT));
 19.1024 +
 19.1025 +    return 0;
 19.1026 +
 19.1027 +err_update:
 19.1028 +    SDL_SYS_HapticFreeDIEFFECT(&temp, data->type);
 19.1029 +    return -1;
 19.1030 +}
 19.1031 +
 19.1032 +int
 19.1033 +SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
 19.1034 +{
 19.1035 +    HRESULT ret;
 19.1036 +    DWORD iter;
 19.1037 +
 19.1038 +    /* Check if it's infinite. */
 19.1039 +    if (iterations == SDL_HAPTIC_INFINITY) {
 19.1040 +        iter = INFINITE;
 19.1041 +    } else {
 19.1042 +        iter = iterations;
 19.1043 +    }
 19.1044 +
 19.1045 +    /* Run the effect. */
 19.1046 +    ret = IDirectInputEffect_Start(effect->hweffect->ref, iter, 0);
 19.1047 +    if (FAILED(ret)) {
 19.1048 +        return DI_SetError("Running the effect", ret);
 19.1049 +    }
 19.1050 +    return 0;
 19.1051 +}
 19.1052 +
 19.1053 +int
 19.1054 +SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1055 +{
 19.1056 +    HRESULT ret;
 19.1057 +
 19.1058 +    ret = IDirectInputEffect_Stop(effect->hweffect->ref);
 19.1059 +    if (FAILED(ret)) {
 19.1060 +        return DI_SetError("Unable to stop effect", ret);
 19.1061 +    }
 19.1062 +    return 0;
 19.1063 +}
 19.1064 +
 19.1065 +void
 19.1066 +SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1067 +{
 19.1068 +    HRESULT ret;
 19.1069 +
 19.1070 +    ret = IDirectInputEffect_Unload(effect->hweffect->ref);
 19.1071 +    if (FAILED(ret)) {
 19.1072 +        DI_SetError("Removing effect from the device", ret);
 19.1073 +    }
 19.1074 +    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, effect->effect.type);
 19.1075 +}
 19.1076 +
 19.1077 +int
 19.1078 +SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1079 +{
 19.1080 +    HRESULT ret;
 19.1081 +    DWORD status;
 19.1082 +
 19.1083 +    ret = IDirectInputEffect_GetEffectStatus(effect->hweffect->ref, &status);
 19.1084 +    if (FAILED(ret)) {
 19.1085 +        return DI_SetError("Getting effect status", ret);
 19.1086 +    }
 19.1087 +
 19.1088 +    if (status == 0)
 19.1089 +        return SDL_FALSE;
 19.1090 +    return SDL_TRUE;
 19.1091 +}
 19.1092 +
 19.1093 +int
 19.1094 +SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
 19.1095 +{
 19.1096 +    HRESULT ret;
 19.1097 +    DIPROPDWORD dipdw;
 19.1098 +
 19.1099 +    /* Create the weird structure thingy. */
 19.1100 +    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
 19.1101 +    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
 19.1102 +    dipdw.diph.dwObj = 0;
 19.1103 +    dipdw.diph.dwHow = DIPH_DEVICE;
 19.1104 +    dipdw.dwData = gain * 100;  /* 0 to 10,000 */
 19.1105 +
 19.1106 +    /* Try to set the autocenter. */
 19.1107 +    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
 19.1108 +        DIPROP_FFGAIN, &dipdw.diph);
 19.1109 +    if (FAILED(ret)) {
 19.1110 +        return DI_SetError("Setting gain", ret);
 19.1111 +    }
 19.1112 +    return 0;
 19.1113 +}
 19.1114 +
 19.1115 +int
 19.1116 +SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
 19.1117 +{
 19.1118 +    HRESULT ret;
 19.1119 +    DIPROPDWORD dipdw;
 19.1120 +
 19.1121 +    /* Create the weird structure thingy. */
 19.1122 +    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
 19.1123 +    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
 19.1124 +    dipdw.diph.dwObj = 0;
 19.1125 +    dipdw.diph.dwHow = DIPH_DEVICE;
 19.1126 +    dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF :
 19.1127 +        DIPROPAUTOCENTER_ON;
 19.1128 +
 19.1129 +    /* Try to set the autocenter. */
 19.1130 +    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
 19.1131 +        DIPROP_AUTOCENTER, &dipdw.diph);
 19.1132 +    if (FAILED(ret)) {
 19.1133 +        return DI_SetError("Setting autocenter", ret);
 19.1134 +    }
 19.1135 +    return 0;
 19.1136 +}
 19.1137 +
 19.1138 +int
 19.1139 +SDL_DINPUT_HapticPause(SDL_Haptic * haptic)
 19.1140 +{
 19.1141 +    HRESULT ret;
 19.1142 +
 19.1143 +    /* Pause the device. */
 19.1144 +    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 19.1145 +        DISFFC_PAUSE);
 19.1146 +    if (FAILED(ret)) {
 19.1147 +        return DI_SetError("Pausing the device", ret);
 19.1148 +    }
 19.1149 +    return 0;
 19.1150 +}
 19.1151 +
 19.1152 +int
 19.1153 +SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic)
 19.1154 +{
 19.1155 +    HRESULT ret;
 19.1156 +
 19.1157 +    /* Unpause the device. */
 19.1158 +    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 19.1159 +        DISFFC_CONTINUE);
 19.1160 +    if (FAILED(ret)) {
 19.1161 +        return DI_SetError("Pausing the device", ret);
 19.1162 +    }
 19.1163 +    return 0;
 19.1164 +}
 19.1165 +
 19.1166 +int
 19.1167 +SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic)
 19.1168 +{
 19.1169 +    HRESULT ret;
 19.1170 +
 19.1171 +    /* Try to stop the effects. */
 19.1172 +    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 19.1173 +        DISFFC_STOPALL);
 19.1174 +    if (FAILED(ret)) {
 19.1175 +        return DI_SetError("Stopping the device", ret);
 19.1176 +    }
 19.1177 +    return 0;
 19.1178 +}
 19.1179 +
 19.1180 +#else /* !SDL_HAPTIC_DINPUT */
 19.1181 +
 19.1182 +
 19.1183 +int
 19.1184 +SDL_DINPUT_HapticInit(void)
 19.1185 +{
 19.1186 +    return 0;
 19.1187 +}
 19.1188 +
 19.1189 +int
 19.1190 +SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
 19.1191 +{
 19.1192 +    return SDL_Unsupported();
 19.1193 +}
 19.1194 +
 19.1195 +int
 19.1196 +SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
 19.1197 +{
 19.1198 +    return SDL_Unsupported();
 19.1199 +}
 19.1200 +
 19.1201 +int
 19.1202 +SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
 19.1203 +{
 19.1204 +    return SDL_Unsupported();
 19.1205 +}
 19.1206 +
 19.1207 +int
 19.1208 +SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
 19.1209 +{
 19.1210 +    return SDL_Unsupported();
 19.1211 +}
 19.1212 +
 19.1213 +int
 19.1214 +SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
 19.1215 +{
 19.1216 +    return SDL_Unsupported();
 19.1217 +}
 19.1218 +
 19.1219 +void
 19.1220 +SDL_DINPUT_HapticClose(SDL_Haptic * haptic)
 19.1221 +{
 19.1222 +}
 19.1223 +
 19.1224 +void
 19.1225 +SDL_DINPUT_HapticQuit(void)
 19.1226 +{
 19.1227 +}
 19.1228 +
 19.1229 +int
 19.1230 +SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
 19.1231 +{
 19.1232 +    return SDL_Unsupported();
 19.1233 +}
 19.1234 +
 19.1235 +int
 19.1236 +SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
 19.1237 +{
 19.1238 +    return SDL_Unsupported();
 19.1239 +}
 19.1240 +
 19.1241 +int
 19.1242 +SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
 19.1243 +{
 19.1244 +    return SDL_Unsupported();
 19.1245 +}
 19.1246 +
 19.1247 +int
 19.1248 +SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1249 +{
 19.1250 +    return SDL_Unsupported();
 19.1251 +}
 19.1252 +
 19.1253 +void
 19.1254 +SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1255 +{
 19.1256 +}
 19.1257 +
 19.1258 +int
 19.1259 +SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
 19.1260 +{
 19.1261 +    return SDL_Unsupported();
 19.1262 +}
 19.1263 +
 19.1264 +int
 19.1265 +SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
 19.1266 +{
 19.1267 +    return SDL_Unsupported();
 19.1268 +}
 19.1269 +
 19.1270 +int
 19.1271 +SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
 19.1272 +{
 19.1273 +    return SDL_Unsupported();
 19.1274 +}
 19.1275 +
 19.1276 +int
 19.1277 +SDL_DINPUT_HapticPause(SDL_Haptic * haptic)
 19.1278 +{
 19.1279 +    return SDL_Unsupported();
 19.1280 +}
 19.1281 +
 19.1282 +int
 19.1283 +SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic)
 19.1284 +{
 19.1285 +    return SDL_Unsupported();
 19.1286 +}
 19.1287 +
 19.1288 +int
 19.1289 +SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic)
 19.1290 +{
 19.1291 +    return SDL_Unsupported();
 19.1292 +}
 19.1293 +
 19.1294 +#endif /* SDL_HAPTIC_DINPUT */
 19.1295 +
 19.1296 +/* vi: set ts=4 sw=4 expandtab: */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/haptic/windows/SDL_dinputhaptic_c.h	Thu Jul 03 15:39:55 2014 -0700
    20.3 @@ -0,0 +1,47 @@
    20.4 +/*
    20.5 +  Simple DirectMedia Layer
    20.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    20.7 +
    20.8 +  This software is provided 'as-is', without any express or implied
    20.9 +  warranty.  In no event will the authors be held liable for any damages
   20.10 +  arising from the use of this software.
   20.11 +
   20.12 +  Permission is granted to anyone to use this software for any purpose,
   20.13 +  including commercial applications, and to alter it and redistribute it
   20.14 +  freely, subject to the following restrictions:
   20.15 +
   20.16 +  1. The origin of this software must not be misrepresented; you must not
   20.17 +     claim that you wrote the original software. If you use this software
   20.18 +     in a product, an acknowledgment in the product documentation would be
   20.19 +     appreciated but is not required.
   20.20 +  2. Altered source versions must be plainly marked as such, and must not be
   20.21 +     misrepresented as being the original software.
   20.22 +  3. This notice may not be removed or altered from any source distribution.
   20.23 +*/
   20.24 +#include "../../SDL_internal.h"
   20.25 +
   20.26 +#include "SDL_haptic.h"
   20.27 +#include "SDL_windowshaptic_c.h"
   20.28 +
   20.29 +
   20.30 +extern int SDL_DINPUT_HapticInit(void);
   20.31 +extern int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
   20.32 +extern int SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
   20.33 +extern int SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
   20.34 +extern int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
   20.35 +extern int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
   20.36 +extern void SDL_DINPUT_HapticClose(SDL_Haptic * haptic);
   20.37 +extern void SDL_DINPUT_HapticQuit(void);
   20.38 +extern int SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base);
   20.39 +extern int SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data);
   20.40 +extern int SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations);
   20.41 +extern int SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
   20.42 +extern void SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
   20.43 +extern int SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect);
   20.44 +extern int SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain);
   20.45 +extern int SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
   20.46 +extern int SDL_DINPUT_HapticPause(SDL_Haptic * haptic);
   20.47 +extern int SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic);
   20.48 +extern int SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic);
   20.49 +
   20.50 +/* vi: set ts=4 sw=4 expandtab: */
    21.1 --- a/src/haptic/windows/SDL_syshaptic.c	Thu Jul 03 17:36:08 2014 -0300
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,1812 +0,0 @@
    21.4 -/*
    21.5 -  Simple DirectMedia Layer
    21.6 -  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    21.7 -
    21.8 -  This software is provided 'as-is', without any express or implied
    21.9 -  warranty.  In no event will the authors be held liable for any damages
   21.10 -  arising from the use of this software.
   21.11 -
   21.12 -  Permission is granted to anyone to use this software for any purpose,
   21.13 -  including commercial applications, and to alter it and redistribute it
   21.14 -  freely, subject to the following restrictions:
   21.15 -
   21.16 -  1. The origin of this software must not be misrepresented; you must not
   21.17 -     claim that you wrote the original software. If you use this software
   21.18 -     in a product, an acknowledgment in the product documentation would be
   21.19 -     appreciated but is not required.
   21.20 -  2. Altered source versions must be plainly marked as such, and must not be
   21.21 -     misrepresented as being the original software.
   21.22 -  3. This notice may not be removed or altered from any source distribution.
   21.23 -*/
   21.24 -#include "../../SDL_internal.h"
   21.25 -
   21.26 -#ifdef SDL_HAPTIC_DINPUT
   21.27 -
   21.28 -#include "SDL_assert.h"
   21.29 -#include "SDL_thread.h"
   21.30 -#include "SDL_mutex.h"
   21.31 -#include "SDL_timer.h"
   21.32 -#include "SDL_hints.h"
   21.33 -#include "SDL_haptic.h"
   21.34 -#include "../SDL_syshaptic.h"
   21.35 -#include "SDL_joystick.h"
   21.36 -#include "../../joystick/SDL_sysjoystick.h"     /* For the real SDL_Joystick */
   21.37 -#include "../../joystick/windows/SDL_dxjoystick_c.h"      /* For joystick hwdata */
   21.38 -
   21.39 -#include "SDL_syshaptic_c.h"
   21.40 -
   21.41 -/*
   21.42 - * List of available haptic devices.
   21.43 - */
   21.44 -typedef struct SDL_hapticlist_item
   21.45 -{
   21.46 -    DIDEVICEINSTANCE instance;
   21.47 -    char *name;
   21.48 -    SDL_Haptic *haptic;
   21.49 -    DIDEVCAPS capabilities;
   21.50 -    Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
   21.51 -    Uint8 userid; /* XInput userid index for this joystick */
   21.52 -    struct SDL_hapticlist_item *next;
   21.53 -} SDL_hapticlist_item;
   21.54 -
   21.55 -
   21.56 -/*
   21.57 - * Haptic system hardware data.
   21.58 - */
   21.59 -struct haptic_hwdata
   21.60 -{
   21.61 -    LPDIRECTINPUTDEVICE8 device;
   21.62 -    DWORD axes[3];              /* Axes to use. */
   21.63 -    SDL_bool is_joystick;       /* Device is loaded as joystick. */
   21.64 -    Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
   21.65 -    Uint8 userid; /* XInput userid index for this joystick */
   21.66 -    SDL_Thread *thread;
   21.67 -    SDL_mutex *mutex;
   21.68 -    volatile Uint32 stopTicks;
   21.69 -    volatile int stopThread;
   21.70 -};
   21.71 -
   21.72 -
   21.73 -/*
   21.74 - * Haptic system effect data.
   21.75 - */
   21.76 -struct haptic_hweffect
   21.77 -{
   21.78 -    DIEFFECT effect;
   21.79 -    LPDIRECTINPUTEFFECT ref;
   21.80 -    XINPUT_VIBRATION vibration;
   21.81 -};
   21.82 -
   21.83 -
   21.84 -/*
   21.85 - * Internal stuff.
   21.86 - */
   21.87 -static SDL_bool coinitialized = SDL_FALSE;
   21.88 -static LPDIRECTINPUT8 dinput = NULL;
   21.89 -static SDL_bool loaded_xinput = SDL_FALSE;
   21.90 -static SDL_hapticlist_item *SDL_hapticlist = NULL;
   21.91 -static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
   21.92 -static int numhaptics = 0;
   21.93 -
   21.94 -/*
   21.95 - * External stuff.
   21.96 - */
   21.97 -extern HWND SDL_HelperWindow;
   21.98 -
   21.99 -
  21.100 -/*
  21.101 - * Prototypes.
  21.102 - */
  21.103 -static int DI_SetError(const char *str, HRESULT err);
  21.104 -static int DI_GUIDIsSame(const GUID * a, const GUID * b);
  21.105 -static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic,
  21.106 -                                          DIDEVICEINSTANCE instance);
  21.107 -static int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
  21.108 -                                         LPDIRECTINPUTDEVICE8 device8,
  21.109 -                                         SDL_bool is_joystick);
  21.110 -static int SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, const Uint8 userid);
  21.111 -static DWORD DIGetTriggerButton(Uint16 button);
  21.112 -static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir,
  21.113 -                                int naxes);
  21.114 -static int SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
  21.115 -                              SDL_HapticEffect * src);
  21.116 -static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type);
  21.117 -static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect * effect);
  21.118 -static int SDLCALL SDL_RunXInputHaptic(void *arg);
  21.119 -
  21.120 -/* Callbacks. */
  21.121 -static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE *
  21.122 -                                         pdidInstance, VOID * pContext);
  21.123 -static BOOL CALLBACK DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv);
  21.124 -
  21.125 -
  21.126 -/*
  21.127 - * Like SDL_SetError but for DX error codes.
  21.128 - */
  21.129 -static int
  21.130 -DI_SetError(const char *str, HRESULT err)
  21.131 -{
  21.132 -    /*
  21.133 -       SDL_SetError("Haptic: %s - %s: %s", str,
  21.134 -       DXGetErrorString8A(err), DXGetErrorDescription8A(err));
  21.135 -     */
  21.136 -    return SDL_SetError("Haptic error %s", str);
  21.137 -}
  21.138 -
  21.139 -
  21.140 -/*
  21.141 - * Checks to see if two GUID are the same.
  21.142 - */
  21.143 -static int
  21.144 -DI_GUIDIsSame(const GUID * a, const GUID * b)
  21.145 -{
  21.146 -    return (SDL_memcmp(a, b, sizeof (GUID)) == 0);
  21.147 -}
  21.148 -
  21.149 -
  21.150 -/*
  21.151 - * Initializes the haptic subsystem.
  21.152 - */
  21.153 -int
  21.154 -SDL_SYS_HapticInit(void)
  21.155 -{
  21.156 -    const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
  21.157 -    HRESULT ret;
  21.158 -    HINSTANCE instance;
  21.159 -
  21.160 -    if (dinput != NULL) {       /* Already open. */
  21.161 -        return SDL_SetError("Haptic: SubSystem already open.");
  21.162 -    }
  21.163 -
  21.164 -    ret = WIN_CoInitialize();
  21.165 -    if (FAILED(ret)) {
  21.166 -        return DI_SetError("Coinitialize", ret);
  21.167 -    }
  21.168 -
  21.169 -    coinitialized = SDL_TRUE;
  21.170 -
  21.171 -    ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
  21.172 -                           &IID_IDirectInput8, (LPVOID) & dinput);
  21.173 -    if (FAILED(ret)) {
  21.174 -        SDL_SYS_HapticQuit();
  21.175 -        return DI_SetError("CoCreateInstance", ret);
  21.176 -    }
  21.177 -
  21.178 -    /* Because we used CoCreateInstance, we need to Initialize it, first. */
  21.179 -    instance = GetModuleHandle(NULL);
  21.180 -    if (instance == NULL) {
  21.181 -        SDL_SYS_HapticQuit();
  21.182 -        return SDL_SetError("GetModuleHandle() failed with error code %d.",
  21.183 -                            GetLastError());
  21.184 -    }
  21.185 -    ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
  21.186 -    if (FAILED(ret)) {
  21.187 -        SDL_SYS_HapticQuit();
  21.188 -        return DI_SetError("Initializing DirectInput device", ret);
  21.189 -    }
  21.190 -
  21.191 -    /* Look for haptic devices. */
  21.192 -    ret = IDirectInput8_EnumDevices(dinput,
  21.193 -                                   0,
  21.194 -                                   EnumHapticsCallback,
  21.195 -                                   NULL,
  21.196 -                                   DIEDFL_FORCEFEEDBACK |
  21.197 -                                   DIEDFL_ATTACHEDONLY);
  21.198 -    if (FAILED(ret)) {
  21.199 -        SDL_SYS_HapticQuit();
  21.200 -        return DI_SetError("Enumerating DirectInput devices", ret);
  21.201 -    }
  21.202 -
  21.203 -    if (!env || SDL_atoi(env)) {
  21.204 -        loaded_xinput = (WIN_LoadXInputDLL() == 0);
  21.205 -    }
  21.206 -
  21.207 -    if (loaded_xinput) {
  21.208 -        DWORD i;
  21.209 -        for (i = 0; i < SDL_XINPUT_MAX_DEVICES; i++) {
  21.210 -            XInputHaptic_MaybeAddDevice(i);
  21.211 -        }
  21.212 -    }
  21.213 -
  21.214 -    return numhaptics;
  21.215 -}
  21.216 -
  21.217 -
  21.218 -int
  21.219 -DirectInputHaptic_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
  21.220 -{
  21.221 -    HRESULT ret;
  21.222 -    LPDIRECTINPUTDEVICE8 device;
  21.223 -    const DWORD needflags = DIDC_ATTACHED | DIDC_FORCEFEEDBACK;
  21.224 -    DIDEVCAPS capabilities;
  21.225 -    SDL_hapticlist_item *item = NULL;
  21.226 -
  21.227 -    if (dinput == NULL) {
  21.228 -        return -1;  /* not initialized. We'll pick these up on enumeration if we init later. */
  21.229 -    }
  21.230 -
  21.231 -    /* Make sure we don't already have it */
  21.232 -    for (item = SDL_hapticlist; item; item = item->next) {
  21.233 -        if ( (!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof (*pdidInstance)) == 0) ) {
  21.234 -            return -1;  /* Already added */
  21.235 -        }
  21.236 -    }
  21.237 -
  21.238 -    /* Open the device */
  21.239 -    ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL);
  21.240 -    if (FAILED(ret)) {
  21.241 -        /* DI_SetError("Creating DirectInput device",ret); */
  21.242 -        return -1;
  21.243 -    }
  21.244 -
  21.245 -    /* Get capabilities. */
  21.246 -    SDL_zero(capabilities);
  21.247 -    capabilities.dwSize = sizeof (DIDEVCAPS);
  21.248 -    ret = IDirectInputDevice8_GetCapabilities(device, &capabilities);
  21.249 -    IDirectInputDevice8_Release(device);
  21.250 -    if (FAILED(ret)) {
  21.251 -        /* DI_SetError("Getting device capabilities",ret); */
  21.252 -        return -1;
  21.253 -    }
  21.254 -
  21.255 -    if ((capabilities.dwFlags & needflags) != needflags) {
  21.256 -        return -1;  /* not a device we can use. */
  21.257 -    }
  21.258 -
  21.259 -    item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item));
  21.260 -    if (item == NULL) {
  21.261 -        return SDL_OutOfMemory();
  21.262 -    }
  21.263 -
  21.264 -    item->name = WIN_StringToUTF8(pdidInstance->tszProductName);
  21.265 -    if (!item->name) {
  21.266 -        SDL_free(item);
  21.267 -        return -1;
  21.268 -    }
  21.269 -
  21.270 -    /* Copy the instance over, useful for creating devices. */
  21.271 -    SDL_memcpy(&item->instance, pdidInstance, sizeof (DIDEVICEINSTANCE));
  21.272 -    SDL_memcpy(&item->capabilities, &capabilities, sizeof (capabilities));
  21.273 -
  21.274 -    if (SDL_hapticlist_tail == NULL) {
  21.275 -        SDL_hapticlist = SDL_hapticlist_tail = item;
  21.276 -    } else {
  21.277 -        SDL_hapticlist_tail->next = item;
  21.278 -        SDL_hapticlist_tail = item;
  21.279 -    }
  21.280 -
  21.281 -    /* Device has been added. */
  21.282 -    ++numhaptics;
  21.283 -
  21.284 -    return numhaptics;
  21.285 -}
  21.286 -
  21.287 -
  21.288 -int
  21.289 -DirectInputHaptic_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
  21.290 -{
  21.291 -    SDL_hapticlist_item *item;
  21.292 -    SDL_hapticlist_item *prev = NULL;
  21.293 -
  21.294 -    if (dinput == NULL) {
  21.295 -        return -1;  /* not initialized, ignore this. */
  21.296 -    }
  21.297 -
  21.298 -    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  21.299 -        if ( (!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof (*pdidInstance)) == 0) ) {
  21.300 -            /* found it, remove it. */
  21.301 -            const int retval = item->haptic ? item->haptic->index : -1;
  21.302 -            if (prev != NULL) {
  21.303 -                prev->next = item->next;
  21.304 -            } else {
  21.305 -                SDL_assert(SDL_hapticlist == item);
  21.306 -                SDL_hapticlist = item->next;
  21.307 -            }
  21.308 -            if (item == SDL_hapticlist_tail) {
  21.309 -                SDL_hapticlist_tail = prev;
  21.310 -            }
  21.311 -            --numhaptics;
  21.312 -            /* !!! TODO: Send a haptic remove event? */
  21.313 -            SDL_free(item);
  21.314 -            return retval;
  21.315 -        }
  21.316 -        prev = item;
  21.317 -    }
  21.318 -
  21.319 -    return -1;
  21.320 -}
  21.321 -
  21.322 -
  21.323 -int
  21.324 -XInputHaptic_MaybeAddDevice(const DWORD dwUserid)
  21.325 -{
  21.326 -    const Uint8 userid = (Uint8) dwUserid;
  21.327 -    SDL_hapticlist_item *item;
  21.328 -    XINPUT_VIBRATION state;
  21.329 -
  21.330 -    if ((!loaded_xinput) || (dwUserid >= SDL_XINPUT_MAX_DEVICES)) {
  21.331 -        return -1;
  21.332 -    }
  21.333 -
  21.334 -    /* Make sure we don't already have it */
  21.335 -    for (item = SDL_hapticlist; item; item = item->next) {
  21.336 -        if ((item->bXInputHaptic) && (item->userid == userid)) {
  21.337 -            return -1;  /* Already added */
  21.338 -        }
  21.339 -    }
  21.340 -
  21.341 -    SDL_zero(state);
  21.342 -    if (XINPUTSETSTATE(dwUserid, &state) != ERROR_SUCCESS) {
  21.343 -        return -1;  /* no force feedback on this device. */
  21.344 -    }
  21.345 -
  21.346 -    item = (SDL_hapticlist_item *)SDL_malloc( sizeof(SDL_hapticlist_item));
  21.347 -    if (item == NULL) {
  21.348 -        return SDL_OutOfMemory();
  21.349 -    }
  21.350 -
  21.351 -    SDL_zerop(item);
  21.352 -
  21.353 -    /* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */
  21.354 -    {
  21.355 -        char buf[64];
  21.356 -        SDL_snprintf(buf, sizeof (buf), "XInput Controller #%u", (unsigned int) (userid+1));
  21.357 -        item->name = SDL_strdup(buf);
  21.358 -    }
  21.359 -
  21.360 -    if (!item->name) {
  21.361 -        SDL_free(item);
  21.362 -        return -1;
  21.363 -    }
  21.364 -
  21.365 -    /* Copy the instance over, useful for creating devices. */
  21.366 -    item->bXInputHaptic = 1;
  21.367 -    item->userid = userid;
  21.368 -
  21.369 -    if (SDL_hapticlist_tail == NULL) {
  21.370 -        SDL_hapticlist = SDL_hapticlist_tail = item;
  21.371 -    } else {
  21.372 -        SDL_hapticlist_tail->next = item;
  21.373 -        SDL_hapticlist_tail = item;
  21.374 -    }
  21.375 -
  21.376 -    /* Device has been added. */
  21.377 -    ++numhaptics;
  21.378 -
  21.379 -    return numhaptics;
  21.380 -}
  21.381 -
  21.382 -
  21.383 -int
  21.384 -XInputHaptic_MaybeRemoveDevice(const DWORD dwUserid)
  21.385 -{
  21.386 -    const Uint8 userid = (Uint8) dwUserid;
  21.387 -    SDL_hapticlist_item *item;
  21.388 -    SDL_hapticlist_item *prev = NULL;
  21.389 -
  21.390 -    if ((!loaded_xinput) || (dwUserid >= SDL_XINPUT_MAX_DEVICES)) {
  21.391 -        return -1;
  21.392 -    }
  21.393 -
  21.394 -    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  21.395 -        if ((item->bXInputHaptic) && (item->userid == userid)) {
  21.396 -            /* found it, remove it. */
  21.397 -            const int retval = item->haptic ? item->haptic->index : -1;
  21.398 -            if (prev != NULL) {
  21.399 -                prev->next = item->next;
  21.400 -            } else {
  21.401 -                SDL_assert(SDL_hapticlist == item);
  21.402 -                SDL_hapticlist = item->next;
  21.403 -            }
  21.404 -            if (item == SDL_hapticlist_tail) {
  21.405 -                SDL_hapticlist_tail = prev;
  21.406 -            }
  21.407 -            --numhaptics;
  21.408 -            /* !!! TODO: Send a haptic remove event? */
  21.409 -            SDL_free(item);
  21.410 -            return retval;
  21.411 -        }
  21.412 -        prev = item;
  21.413 -    }
  21.414 -
  21.415 -    return -1;
  21.416 -}
  21.417 -
  21.418 -
  21.419 -/*
  21.420 - * Callback to find the haptic devices.
  21.421 - */
  21.422 -static BOOL CALLBACK
  21.423 -EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
  21.424 -{
  21.425 -    (void) pContext;
  21.426 -    DirectInputHaptic_MaybeAddDevice(pdidInstance);
  21.427 -    return DIENUM_CONTINUE;  /* continue enumerating */
  21.428 -}
  21.429 -
  21.430 -
  21.431 -int
  21.432 -SDL_SYS_NumHaptics()
  21.433 -{
  21.434 -    return numhaptics;
  21.435 -}
  21.436 -
  21.437 -static SDL_hapticlist_item *
  21.438 -HapticByDevIndex(int device_index)
  21.439 -{
  21.440 -    SDL_hapticlist_item *item = SDL_hapticlist;
  21.441 -
  21.442 -    if ((device_index < 0) || (device_index >= numhaptics)) {
  21.443 -        return NULL;
  21.444 -    }
  21.445 -
  21.446 -    while (device_index > 0) {
  21.447 -        SDL_assert(item != NULL);
  21.448 -        --device_index;
  21.449 -        item = item->next;
  21.450 -    }
  21.451 -
  21.452 -    return item;
  21.453 -}
  21.454 -
  21.455 -/*
  21.456 - * Return the name of a haptic device, does not need to be opened.
  21.457 - */
  21.458 -const char *
  21.459 -SDL_SYS_HapticName(int index)
  21.460 -{
  21.461 -    SDL_hapticlist_item *item = HapticByDevIndex(index);
  21.462 -    return item->name;
  21.463 -}
  21.464 -
  21.465 -
  21.466 -/*
  21.467 - * Callback to get all supported effects.
  21.468 - */
  21.469 -#define EFFECT_TEST(e,s)               \
  21.470 -if (DI_GUIDIsSame(&pei->guid, &(e)))   \
  21.471 -   haptic->supported |= (s)
  21.472 -static BOOL CALLBACK
  21.473 -DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
  21.474 -{
  21.475 -    /* Prepare the haptic device. */
  21.476 -    SDL_Haptic *haptic = (SDL_Haptic *) pv;
  21.477 -
  21.478 -    /* Get supported. */
  21.479 -    EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING);
  21.480 -    EFFECT_TEST(GUID_Damper, SDL_HAPTIC_DAMPER);
  21.481 -    EFFECT_TEST(GUID_Inertia, SDL_HAPTIC_INERTIA);
  21.482 -    EFFECT_TEST(GUID_Friction, SDL_HAPTIC_FRICTION);
  21.483 -    EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
  21.484 -    EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
  21.485 -    EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
  21.486 -    /* !!! FIXME: put this back when we have more bits in 2.1 */
  21.487 -    /* EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE); */
  21.488 -    EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
  21.489 -    EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
  21.490 -    EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
  21.491 -    EFFECT_TEST(GUID_RampForce, SDL_HAPTIC_RAMP);
  21.492 -
  21.493 -    /* Check for more. */
  21.494 -    return DIENUM_CONTINUE;
  21.495 -}
  21.496 -
  21.497 -
  21.498 -/*
  21.499 - * Callback to get supported axes.
  21.500 - */
  21.501 -static BOOL CALLBACK
  21.502 -DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
  21.503 -{
  21.504 -    SDL_Haptic *haptic = (SDL_Haptic *) pvRef;
  21.505 -
  21.506 -    if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) {
  21.507 -        const GUID *guid = &dev->guidType;
  21.508 -        DWORD offset = 0;
  21.509 -        if (DI_GUIDIsSame(guid, &GUID_XAxis)) {
  21.510 -            offset = DIJOFS_X;
  21.511 -        } else if (DI_GUIDIsSame(guid, &GUID_YAxis)) {
  21.512 -            offset = DIJOFS_Y;
  21.513 -        } else if (DI_GUIDIsSame(guid, &GUID_ZAxis)) {
  21.514 -            offset = DIJOFS_Z;
  21.515 -        } else if (DI_GUIDIsSame(guid, &GUID_RxAxis)) {
  21.516 -            offset = DIJOFS_RX;
  21.517 -        } else if (DI_GUIDIsSame(guid, &GUID_RyAxis)) {
  21.518 -            offset = DIJOFS_RY;
  21.519 -        } else if (DI_GUIDIsSame(guid, &GUID_RzAxis)) {
  21.520 -            offset = DIJOFS_RZ;
  21.521 -        } else {
  21.522 -            return DIENUM_CONTINUE;   /* can't use this, go on. */
  21.523 -        }
  21.524 -
  21.525 -        haptic->hwdata->axes[haptic->naxes] = offset;
  21.526 -        haptic->naxes++;
  21.527 -
  21.528 -        /* Currently using the artificial limit of 3 axes. */
  21.529 -        if (haptic->naxes >= 3) {
  21.530 -            return DIENUM_STOP;
  21.531 -        }
  21.532 -    }
  21.533 -
  21.534 -    return DIENUM_CONTINUE;
  21.535 -}
  21.536 -
  21.537 -
  21.538 -/*
  21.539 - * Opens the haptic device from the file descriptor.
  21.540 - *
  21.541 - *    Steps:
  21.542 - *       - Open temporary DirectInputDevice interface.
  21.543 - *       - Create DirectInputDevice8 interface.
  21.544 - *       - Release DirectInputDevice interface.
  21.545 - *       - Call SDL_SYS_HapticOpenFromDevice8
  21.546 - */
  21.547 -static int
  21.548 -SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
  21.549 -{
  21.550 -    HRESULT ret;
  21.551 -    int ret2;
  21.552 -    LPDIRECTINPUTDEVICE8 device;
  21.553 -    LPDIRECTINPUTDEVICE8 device8;
  21.554 -
  21.555 -    /* Open the device */
  21.556 -    ret = IDirectInput8_CreateDevice(dinput, &instance.guidInstance,
  21.557 -                                    &device, NULL);
  21.558 -    if (FAILED(ret)) {
  21.559 -        DI_SetError("Creating DirectInput device", ret);
  21.560 -        return -1;
  21.561 -    }
  21.562 -
  21.563 -    /* Now get the IDirectInputDevice8 interface, instead. */
  21.564 -    ret = IDirectInputDevice8_QueryInterface(device,
  21.565 -                                            &IID_IDirectInputDevice8,
  21.566 -                                            (LPVOID *) &device8);
  21.567 -    /* Done with the temporary one now. */
  21.568 -    IDirectInputDevice8_Release(device);
  21.569 -    if (FAILED(ret)) {
  21.570 -        DI_SetError("Querying DirectInput interface", ret);
  21.571 -        return -1;
  21.572 -    }
  21.573 -
  21.574 -    ret2 = SDL_SYS_HapticOpenFromDevice8(haptic, device8, SDL_FALSE);
  21.575 -    if (ret2 < 0) {
  21.576 -        IDirectInputDevice8_Release(device8);
  21.577 -        return -1;
  21.578 -    }
  21.579 -
  21.580 -    return 0;
  21.581 -}
  21.582 -
  21.583 -static int
  21.584 -SDL_SYS_HapticOpenFromXInput(SDL_Haptic *haptic, const Uint8 userid)
  21.585 -{
  21.586 -    char threadName[32];
  21.587 -    XINPUT_VIBRATION vibration = { 0, 0 };  /* stop any current vibration */
  21.588 -    XINPUTSETSTATE(userid, &vibration);
  21.589 -
  21.590 -    haptic->supported = SDL_HAPTIC_LEFTRIGHT;
  21.591 -
  21.592 -    haptic->neffects = 1;
  21.593 -    haptic->nplaying = 1;
  21.594 -
  21.595 -    /* Prepare effects memory. */
  21.596 -    haptic->effects = (struct haptic_effect *)
  21.597 -        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
  21.598 -    if (haptic->effects == NULL) {
  21.599 -        return SDL_OutOfMemory();
  21.600 -    }
  21.601 -    /* Clear the memory */
  21.602 -    SDL_memset(haptic->effects, 0,
  21.603 -               sizeof(struct haptic_effect) * haptic->neffects);
  21.604 -
  21.605 -    haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata));
  21.606 -    if (haptic->hwdata == NULL) {
  21.607 -        SDL_free(haptic->effects);
  21.608 -        haptic->effects = NULL;
  21.609 -        return SDL_OutOfMemory();
  21.610 -    }
  21.611 -    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
  21.612 -
  21.613 -    haptic->hwdata->bXInputHaptic = 1;
  21.614 -    haptic->hwdata->userid = userid;
  21.615 -
  21.616 -    haptic->hwdata->mutex = SDL_CreateMutex();
  21.617 -    if (haptic->hwdata->mutex == NULL) {
  21.618 -        SDL_free(haptic->effects);
  21.619 -        SDL_free(haptic->hwdata);
  21.620 -        haptic->effects = NULL;
  21.621 -        return SDL_SetError("Couldn't create XInput haptic mutex");
  21.622 -    }
  21.623 -
  21.624 -    SDL_snprintf(threadName, sizeof (threadName), "SDLXInputDev%d", (int) userid);
  21.625 -
  21.626 -#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
  21.627 -    #undef SDL_CreateThread
  21.628 -    #if SDL_DYNAMIC_API
  21.629 -    haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
  21.630 -    #else
  21.631 -    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
  21.632 -    #endif
  21.633 -#else
  21.634 -    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
  21.635 -#endif
  21.636 -    if (haptic->hwdata->thread == NULL) {
  21.637 -        SDL_DestroyMutex(haptic->hwdata->mutex);
  21.638 -        SDL_free(haptic->effects);
  21.639 -        SDL_free(haptic->hwdata);
  21.640 -        haptic->effects = NULL;
  21.641 -        return SDL_SetError("Couldn't create XInput haptic thread");
  21.642 -    }
  21.643 -
  21.644 -    return 0;
  21.645 - }
  21.646 -
  21.647 -/*
  21.648 - * Opens the haptic device from the file descriptor.
  21.649 - *
  21.650 - *    Steps:
  21.651 - *       - Set cooperative level.
  21.652 - *       - Set data format.
  21.653 - *       - Acquire exclusiveness.
  21.654 - *       - Reset actuators.
  21.655 - *       - Get supported features.
  21.656 - */
  21.657 -static int
  21.658 -SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
  21.659 -                              LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick)
  21.660 -{
  21.661 -    HRESULT ret;
  21.662 -    DIPROPDWORD dipdw;
  21.663 -
  21.664 -    /* Allocate the hwdata */
  21.665 -    haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata));
  21.666 -    if (haptic->hwdata == NULL) {
  21.667 -        return SDL_OutOfMemory();
  21.668 -    }
  21.669 -    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
  21.670 -
  21.671 -    /* We'll use the device8 from now on. */
  21.672 -    haptic->hwdata->device = device8;
  21.673 -    haptic->hwdata->is_joystick = is_joystick;
  21.674 -
  21.675 -    /* !!! FIXME: opening a haptic device here first will make an attempt to
  21.676 -       !!! FIXME:  SDL_JoystickOpen() that same device fail later, since we
  21.677 -       !!! FIXME:  have it open in exclusive mode. But this will allow
  21.678 -       !!! FIXME:  SDL_JoystickOpen() followed by SDL_HapticOpenFromJoystick()
  21.679 -       !!! FIXME:  to work, and that's probably the common case. Still,
  21.680 -       !!! FIXME:  ideally, We need to unify the opening code. */
  21.681 -
  21.682 -    if (!is_joystick) {  /* if is_joystick, we already set this up elsewhere. */
  21.683 -        /* Grab it exclusively to use force feedback stuff. */
  21.684 -        ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device,
  21.685 -                                                      SDL_HelperWindow,
  21.686 -                                                      DISCL_EXCLUSIVE |
  21.687 -                                                      DISCL_BACKGROUND);
  21.688 -        if (FAILED(ret)) {
  21.689 -            DI_SetError("Setting cooperative level to exclusive", ret);
  21.690 -            goto acquire_err;
  21.691 -        }
  21.692 -
  21.693 -        /* Set data format. */
  21.694 -        ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device,
  21.695 -                                                &c_dfDIJoystick2);
  21.696 -        if (FAILED(ret)) {
  21.697 -            DI_SetError("Setting data format", ret);
  21.698 -            goto acquire_err;
  21.699 -        }
  21.700 -
  21.701 -        /* Get number of axes. */
  21.702 -        ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device,
  21.703 -                                              DI_DeviceObjectCallback,
  21.704 -                                              haptic, DIDFT_AXIS);
  21.705 -        if (FAILED(ret)) {
  21.706 -            DI_SetError("Getting device axes", ret);
  21.707 -            goto acquire_err;
  21.708 -        }
  21.709 -
  21.710 -        /* Acquire the device. */
  21.711 -        ret = IDirectInputDevice8_Acquire(haptic->hwdata->device);
  21.712 -        if (FAILED(ret)) {
  21.713 -            DI_SetError("Acquiring DirectInput device", ret);
  21.714 -            goto acquire_err;
  21.715 -        }
  21.716 -    }
  21.717 -
  21.718 -    /* Reset all actuators - just in case. */
  21.719 -    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
  21.720 -                                                       DISFFC_RESET);
  21.721 -    if (FAILED(ret)) {
  21.722 -        DI_SetError("Resetting device", ret);
  21.723 -        goto acquire_err;
  21.724 -    }
  21.725 -
  21.726 -    /* Enabling actuators. */
  21.727 -    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
  21.728 -                                                       DISFFC_SETACTUATORSON);
  21.729 -    if (FAILED(ret)) {
  21.730 -        DI_SetError("Enabling actuators", ret);
  21.731 -        goto acquire_err;
  21.732 -    }
  21.733 -
  21.734 -    /* Get supported effects. */
  21.735 -    ret = IDirectInputDevice8_EnumEffects(haptic->hwdata->device,
  21.736 -                                          DI_EffectCallback, haptic,
  21.737 -                                          DIEFT_ALL);
  21.738 -    if (FAILED(ret)) {
  21.739 -        DI_SetError("Enumerating supported effects", ret);
  21.740 -        goto acquire_err;
  21.741 -    }
  21.742 -    if (haptic->supported == 0) {       /* Error since device supports nothing. */
  21.743 -        SDL_SetError("Haptic: Internal error on finding supported effects.");
  21.744 -        goto acquire_err;
  21.745 -    }
  21.746 -
  21.747 -    /* Check autogain and autocenter. */
  21.748 -    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  21.749 -    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  21.750 -    dipdw.diph.dwObj = 0;
  21.751 -    dipdw.diph.dwHow = DIPH_DEVICE;
  21.752 -    dipdw.dwData = 10000;
  21.753 -    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
  21.754 -                                          DIPROP_FFGAIN, &dipdw.diph);
  21.755 -    if (!FAILED(ret)) {         /* Gain is supported. */
  21.756 -        haptic->supported |= SDL_HAPTIC_GAIN;
  21.757 -    }
  21.758 -    dipdw.diph.dwObj = 0;
  21.759 -    dipdw.diph.dwHow = DIPH_DEVICE;
  21.760 -    dipdw.dwData = DIPROPAUTOCENTER_OFF;
  21.761 -    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
  21.762 -                                          DIPROP_AUTOCENTER, &dipdw.diph);
  21.763 -    if (!FAILED(ret)) {         /* Autocenter is supported. */
  21.764 -        haptic->supported |= SDL_HAPTIC_AUTOCENTER;
  21.765 -    }
  21.766 -
  21.767 -    /* Status is always supported. */
  21.768 -    haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;
  21.769 -
  21.770 -    /* Check maximum effects. */
  21.771 -    haptic->neffects = 128;     /* This is not actually supported as thus under windows,
  21.772 -                                   there is no way to tell the number of EFFECTS that a
  21.773 -                                   device can hold, so we'll just use a "random" number
  21.774 -                                   instead and put warnings in SDL_haptic.h */
  21.775 -    haptic->nplaying = 128;     /* Even more impossible to get this then neffects. */
  21.776 -
  21.777 -    /* Prepare effects memory. */
  21.778 -    haptic->effects = (struct haptic_effect *)
  21.779 -        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
  21.780 -    if (haptic->effects == NULL) {
  21.781 -        SDL_OutOfMemory();
  21.782 -        goto acquire_err;
  21.783 -    }
  21.784 -    /* Clear the memory */
  21.785 -    SDL_memset(haptic->effects, 0,
  21.786 -               sizeof(struct haptic_effect) * haptic->neffects);
  21.787 -
  21.788 -    return 0;
  21.789 -
  21.790 -    /* Error handling */
  21.791 -  acquire_err:
  21.792 -    IDirectInputDevice8_Unacquire(haptic->hwdata->device);
  21.793 -    return -1;
  21.794 -
  21.795 -}
  21.796 -
  21.797 -
  21.798 -/*
  21.799 - * Opens a haptic device for usage.
  21.800 - */
  21.801 -int
  21.802 -SDL_SYS_HapticOpen(SDL_Haptic * haptic)
  21.803 -{
  21.804 -    SDL_hapticlist_item *item = HapticByDevIndex(haptic->index);
  21.805 -    return (item->bXInputHaptic) ? SDL_SYS_HapticOpenFromXInput(haptic, item->userid) : SDL_SYS_HapticOpenFromInstance(haptic, item->instance);
  21.806 -}
  21.807 -
  21.808 -
  21.809 -/*
  21.810 - * Opens a haptic device from first mouse it finds for usage.
  21.811 - */
  21.812 -int
  21.813 -SDL_SYS_HapticMouse(void)
  21.814 -{
  21.815 -    SDL_hapticlist_item *item;
  21.816 -    int index = 0;
  21.817 -
  21.818 -    /* Grab the first mouse haptic device we find. */
  21.819 -    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  21.820 -        SDL_assert(index >= 0);
  21.821 -        if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
  21.822 -            return index;
  21.823 -        }
  21.824 -        ++index;
  21.825 -    }
  21.826 -
  21.827 -    return -1;
  21.828 -}
  21.829 -
  21.830 -
  21.831 -/*
  21.832 - * Checks to see if a joystick has haptic features.
  21.833 - */
  21.834 -int
  21.835 -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
  21.836 -{
  21.837 -    const struct joystick_hwdata *hwdata = joystick->hwdata;
  21.838 -    return ( (hwdata->bXInputHaptic) ||
  21.839 -             ((hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) != 0) );
  21.840 -}
  21.841 -
  21.842 -
  21.843 -/*
  21.844 - * Checks to see if the haptic device and joystick are in reality the same.
  21.845 - */
  21.846 -int
  21.847 -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
  21.848 -{
  21.849 -    if (joystick->hwdata->bXInputHaptic != haptic->hwdata->bXInputHaptic) {
  21.850 -        return 0;  /* one is XInput, one is not; not the same device. */
  21.851 -    } else if (joystick->hwdata->bXInputHaptic) {  /* XInput */
  21.852 -        return (haptic->hwdata->userid == joystick->hwdata->userid);
  21.853 -    } else {  /* DirectInput */
  21.854 -        HRESULT ret;
  21.855 -        DIDEVICEINSTANCE hap_instance, joy_instance;
  21.856 -
  21.857 -        hap_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  21.858 -        joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  21.859 -
  21.860 -        /* Get the device instances. */
  21.861 -        ret = IDirectInputDevice8_GetDeviceInfo(haptic->hwdata->device,
  21.862 -                                            &hap_instance);
  21.863 -        if (FAILED(ret)) {
  21.864 -            return 0;
  21.865 -        }
  21.866 -        ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice,
  21.867 -                                                &joy_instance);
  21.868 -        if (FAILED(ret)) {
  21.869 -            return 0;
  21.870 -        }
  21.871 -
  21.872 -        if (DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance))
  21.873 -            return 1;
  21.874 -    }
  21.875 -
  21.876 -    return 0;
  21.877 -}
  21.878 -
  21.879 -
  21.880 -/*
  21.881 - * Opens a SDL_Haptic from a SDL_Joystick.
  21.882 - */
  21.883 -int
  21.884 -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
  21.885 -{
  21.886 -    SDL_hapticlist_item *item;
  21.887 -    int index = 0;
  21.888 -
  21.889 -    /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
  21.890 -    if (joystick->hwdata->bXInputDevice) {
  21.891 -        const Uint8 userid = joystick->hwdata->userid;
  21.892 -        for (item = SDL_hapticlist; item != NULL; item = item->next) {
  21.893 -            if ((item->bXInputHaptic) && (item->userid == userid)) {
  21.894 -                SDL_assert(joystick->hwdata->bXInputHaptic);
  21.895 -                haptic->index = index;
  21.896 -                return SDL_SYS_HapticOpenFromXInput(haptic, userid);
  21.897 -            }
  21.898 -            ++index;
  21.899 -        }
  21.900 -    } else {
  21.901 -        HRESULT idret;
  21.902 -        DIDEVICEINSTANCE joy_instance;
  21.903 -
  21.904 -        joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
  21.905 -        idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
  21.906 -        if (FAILED(idret)) {
  21.907 -            return -1;
  21.908 -        }
  21.909 -
  21.910 -        for (item = SDL_hapticlist; item != NULL; item = item->next) {
  21.911 -            if (DI_GUIDIsSame(&item->instance.guidInstance, &joy_instance.guidInstance)) {
  21.912 -                haptic->index = index;
  21.913 -                return SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
  21.914 -            }
  21.915 -            ++index;
  21.916 -        }
  21.917 -    }
  21.918 -
  21.919 -    /* No match to our haptic list */
  21.920 -    return -1;
  21.921 -}
  21.922 -
  21.923 -
  21.924 -/*
  21.925 - * Closes the haptic device.
  21.926 - */
  21.927 -void
  21.928 -SDL_SYS_HapticClose(SDL_Haptic * haptic)
  21.929 -{
  21.930 -    if (haptic->hwdata) {
  21.931 -
  21.932 -        /* Free effects. */
  21.933 -        SDL_free(haptic->effects);
  21.934 -        haptic->effects = NULL;
  21.935 -        haptic->neffects = 0;
  21.936 -
  21.937 -        /* Clean up */
  21.938 -        if (haptic->hwdata->bXInputHaptic) {
  21.939 -            haptic->hwdata->stopThread = 1;
  21.940 -            SDL_WaitThread(haptic->hwdata->thread, NULL);
  21.941 -            SDL_DestroyMutex(haptic->hwdata->mutex);
  21.942 -        } else {
  21.943 -            IDirectInputDevice8_Unacquire(haptic->hwdata->device);
  21.944 -            /* Only release if isn't grabbed by a joystick. */
  21.945 -            if (haptic->hwdata->is_joystick == 0) {
  21.946 -                IDirectInputDevice8_Release(haptic->hwdata->device);
  21.947 -            }
  21.948 -        }
  21.949 -
  21.950 -        /* Free */
  21.951 -        SDL_free(haptic->hwdata);
  21.952 -        haptic->hwdata = NULL;
  21.953 -    }
  21.954 -}
  21.955 -
  21.956 -
  21.957 -/*
  21.958 - * Clean up after system specific haptic stuff
  21.959 - */
  21.960 -void
  21.961 -SDL_SYS_HapticQuit(void)
  21.962 -{
  21.963 -    SDL_hapticlist_item *item;
  21.964 -    SDL_hapticlist_item *next = NULL;
  21.965 -    SDL_Haptic *hapticitem = NULL;
  21.966 -
  21.967 -    extern SDL_Haptic *SDL_haptics;
  21.968 -    for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
  21.969 -        if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
  21.970 -            /* we _have_ to stop the thread before we free the XInput DLL! */
  21.971 -            hapticitem->hwdata->stopThread = 1;
  21.972 -            SDL_WaitThread(hapticitem->hwdata->thread, NULL);
  21.973 -            hapticitem->hwdata->thread = NULL;
  21.974 -        }
  21.975 -    }
  21.976 -
  21.977 -    for (item = SDL_hapticlist; item; item = next) {
  21.978 -        /* Opened and not closed haptics are leaked, this is on purpose.
  21.979 -         * Close your haptic devices after usage. */
  21.980 -        /* !!! FIXME: (...is leaking on purpose a good idea?) */
  21.981 -        next = item->next;
  21.982 -        SDL_free(item->name);
  21.983 -        SDL_free(item);
  21.984 -    }
  21.985 -
  21.986 -    if (loaded_xinput) {
  21.987 -        WIN_UnloadXInputDLL();
  21.988 -        loaded_xinput = SDL_FALSE;
  21.989 -    }
  21.990 -
  21.991 -    if (dinput != NULL) {
  21.992 -        IDirectInput8_Release(dinput);
  21.993 -        dinput = NULL;
  21.994 -    }
  21.995 -
  21.996 -    if (coinitialized) {
  21.997 -        WIN_CoUninitialize();
  21.998 -        coinitialized = SDL_FALSE;
  21.999 -    }
 21.1000 -}
 21.1001 -
 21.1002 -
 21.1003 -/*
 21.1004 - * Converts an SDL trigger button to an DIEFFECT trigger button.
 21.1005 - */
 21.1006 -static DWORD
 21.1007 -DIGetTriggerButton(Uint16 button)
 21.1008 -{
 21.1009 -    DWORD dwTriggerButton;
 21.1010 -
 21.1011 -    dwTriggerButton = DIEB_NOTRIGGER;
 21.1012 -
 21.1013 -    if (button != 0) {
 21.1014 -        dwTriggerButton = DIJOFS_BUTTON(button - 1);
 21.1015 -    }
 21.1016 -
 21.1017 -    return dwTriggerButton;
 21.1018 -}
 21.1019 -
 21.1020 -
 21.1021 -/*
 21.1022 - * Sets the direction.
 21.1023 - */
 21.1024 -static int
 21.1025 -SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes)
 21.1026 -{
 21.1027 -    LONG *rglDir;
 21.1028 -
 21.1029 -    /* Handle no axes a part. */
 21.1030 -    if (naxes == 0) {
 21.1031 -        effect->dwFlags |= DIEFF_SPHERICAL;     /* Set as default. */
 21.1032 -        effect->rglDirection = NULL;
 21.1033 -        return 0;
 21.1034 -    }
 21.1035 -
 21.1036 -    /* Has axes. */
 21.1037 -    rglDir = SDL_malloc(sizeof(LONG) * naxes);
 21.1038 -    if (rglDir == NULL) {
 21.1039 -        return SDL_OutOfMemory();
 21.1040 -    }
 21.1041 -    SDL_memset(rglDir, 0, sizeof(LONG) * naxes);
 21.1042 -    effect->rglDirection = rglDir;
 21.1043 -
 21.1044 -    switch (dir->type) {
 21.1045 -    case SDL_HAPTIC_POLAR:
 21.1046 -        effect->dwFlags |= DIEFF_POLAR;
 21.1047 -        rglDir[0] = dir->dir[0];
 21.1048 -        return 0;
 21.1049 -    case SDL_HAPTIC_CARTESIAN:
 21.1050 -        effect->dwFlags |= DIEFF_CARTESIAN;
 21.1051 -        rglDir[0] = dir->dir[0];
 21.1052 -        if (naxes > 1)
 21.1053 -            rglDir[1] = dir->dir[1];
 21.1054 -        if (naxes > 2)
 21.1055 -            rglDir[2] = dir->dir[2];
 21.1056 -        return 0;
 21.1057 -    case SDL_HAPTIC_SPHERICAL:
 21.1058 -        effect->dwFlags |= DIEFF_SPHERICAL;
 21.1059 -        rglDir[0] = dir->dir[0];
 21.1060 -        if (naxes > 1)
 21.1061 -            rglDir[1] = dir->dir[1];
 21.1062 -        if (naxes > 2)
 21.1063 -            rglDir[2] = dir->dir[2];
 21.1064 -        return 0;
 21.1065 -
 21.1066 -    default:
 21.1067 -        return SDL_SetError("Haptic: Unknown direction type.");
 21.1068 -    }
 21.1069 -}
 21.1070 -
 21.1071 -#define CONVERT(x)   (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF)
 21.1072 -/*
 21.1073 - * Creates the DIEFFECT from a SDL_HapticEffect.
 21.1074 - */
 21.1075 -static int
 21.1076 -SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
 21.1077 -                   SDL_HapticEffect * src)
 21.1078 -{
 21.1079 -    int i;
 21.1080 -    DICONSTANTFORCE *constant;
 21.1081 -    DIPERIODIC *periodic;
 21.1082 -    DICONDITION *condition;     /* Actually an array of conditions - one per axis. */
 21.1083 -    DIRAMPFORCE *ramp;
 21.1084 -    DICUSTOMFORCE *custom;
 21.1085 -    DIENVELOPE *envelope;
 21.1086 -    SDL_HapticConstant *hap_constant;
 21.1087 -    SDL_HapticPeriodic *hap_periodic;
 21.1088 -    SDL_HapticCondition *hap_condition;
 21.1089 -    SDL_HapticRamp *hap_ramp;
 21.1090 -    SDL_HapticCustom *hap_custom;
 21.1091 -    DWORD *axes;
 21.1092 -
 21.1093 -    /* Set global stuff. */
 21.1094 -    SDL_memset(dest, 0, sizeof(DIEFFECT));
 21.1095 -    dest->dwSize = sizeof(DIEFFECT);    /* Set the structure size. */
 21.1096 -    dest->dwSamplePeriod = 0;   /* Not used by us. */
 21.1097 -    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
 21.1098 -    dest->dwFlags = DIEFF_OBJECTOFFSETS;        /* Seems obligatory. */
 21.1099 -
 21.1100 -    /* Envelope. */
 21.1101 -    envelope = SDL_malloc(sizeof(DIENVELOPE));
 21.1102 -    if (envelope == NULL) {
 21.1103 -        return SDL_OutOfMemory();
 21.1104 -    }
 21.1105 -    SDL_memset(envelope, 0, sizeof(DIENVELOPE));
 21.1106 -    dest->lpEnvelope = envelope;
 21.1107 -    envelope->dwSize = sizeof(DIENVELOPE);      /* Always should be this. */
 21.1108 -
 21.1109 -    /* Axes. */
 21.1110 -    dest->cAxes = haptic->naxes;
 21.1111 -    if (dest->cAxes > 0) {
 21.1112 -        axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
 21.1113 -        if (axes == NULL) {
 21.1114 -            return SDL_OutOfMemory();
 21.1115 -        }
 21.1116 -        axes[0] = haptic->hwdata->axes[0];      /* Always at least one axis. */
 21.1117 -        if (dest->cAxes > 1) {
 21.1118 -            axes[1] = haptic->hwdata->axes[1];
 21.1119 -        }
 21.1120 -        if (dest->cAxes > 2) {
 21.1121 -            axes[2] = haptic->hwdata->axes[2];
 21.1122 -        }
 21.1123 -        dest->rgdwAxes = axes;
 21.1124 -    }
 21.1125 -
 21.1126 -
 21.1127 -    /* The big type handling switch, even bigger then Linux's version. */
 21.1128 -    switch (src->type) {
 21.1129 -    case SDL_HAPTIC_CONSTANT:
 21.1130 -        hap_constant = &src->constant;
 21.1131 -        constant = SDL_malloc(sizeof(DICONSTANTFORCE));
 21.1132 -        if (constant == NULL) {
 21.1133 -            return SDL_OutOfMemory();
 21.1134 -        }
 21.1135 -        SDL_memset(constant, 0, sizeof(DICONSTANTFORCE));
 21.1136 -
 21.1137 -        /* Specifics */
 21.1138 -        constant->lMagnitude = CONVERT(hap_constant->level);
 21.1139 -        dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
 21.1140 -        dest->lpvTypeSpecificParams = constant;
 21.1141 -
 21.1142 -        /* Generics */
 21.1143 -        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
 21.1144 -        dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button);
 21.1145 -        dest->dwTriggerRepeatInterval = hap_constant->interval;
 21.1146 -        dest->dwStartDelay = hap_constant->delay * 1000;        /* In microseconds. */
 21.1147 -
 21.1148 -        /* Direction. */
 21.1149 -        if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes)
 21.1150 -            < 0) {
 21.1151 -            return -1;
 21.1152 -        }
 21.1153 -
 21.1154 -        /* Envelope */
 21.1155 -        if ((hap_constant->attack_length == 0)
 21.1156 -            && (hap_constant->fade_length == 0)) {
 21.1157 -            SDL_free(dest->lpEnvelope);
 21.1158 -            dest->lpEnvelope = NULL;
 21.1159 -        } else {
 21.1160 -            envelope->dwAttackLevel = CONVERT(hap_constant->attack_level);
 21.1161 -            envelope->dwAttackTime = hap_constant->attack_length * 1000;
 21.1162 -            envelope->dwFadeLevel = CONVERT(hap_constant->fade_level);
 21.1163 -            envelope->dwFadeTime = hap_constant->fade_length * 1000;
 21.1164 -        }
 21.1165 -
 21.1166 -        break;
 21.1167 -
 21.1168 -    case SDL_HAPTIC_SINE:
 21.1169 -    /* !!! FIXME: put this back when we have more bits in 2.1 */
 21.1170 -    /* case SDL_HAPTIC_SQUARE: */
 21.1171 -    case SDL_HAPTIC_TRIANGLE:
 21.1172 -    case SDL_HAPTIC_SAWTOOTHUP:
 21.1173 -    case SDL_HAPTIC_SAWTOOTHDOWN:
 21.1174 -        hap_periodic = &src->periodic;
 21.1175 -        periodic = SDL_malloc(sizeof(DIPERIODIC));
 21.1176 -        if (periodic == NULL) {
 21.1177 -            return SDL_OutOfMemory();
 21.1178 -        }
 21.1179 -        SDL_memset(periodic, 0, sizeof(DIPERIODIC));
 21.1180 -
 21.1181 -        /* Specifics */
 21.1182 -        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
 21.1183 -        periodic->lOffset = CONVERT(hap_periodic->offset);
 21.1184 -        periodic->dwPhase = hap_periodic->phase;
 21.1185 -        periodic->dwPeriod = hap_periodic->period * 1000;
 21.1186 -        dest->cbTypeSpecificParams = sizeof(DIPERIODIC);
 21.1187 -        dest->lpvTypeSpecificParams = periodic;
 21.1188 -
 21.1189 -        /* Generics */
 21.1190 -        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
 21.1191 -        dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button);
 21.1192 -        dest->dwTriggerRepeatInterval = hap_periodic->interval;
 21.1193 -        dest->dwStartDelay = hap_periodic->delay * 1000;        /* In microseconds. */
 21.1194 -
 21.1195 -        /* Direction. */
 21.1196 -        if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
 21.1197 -            < 0) {
 21.1198 -            return -1;
 21.1199 -        }
 21.1200 -
 21.1201 -        /* Envelope */
 21.1202 -        if ((hap_periodic->attack_length == 0)
 21.1203 -            && (hap_periodic->fade_length == 0)) {
 21.1204 -            SDL_free(dest->lpEnvelope);
 21.1205 -            dest->lpEnvelope = NULL;
 21.1206 -        } else {
 21.1207 -            envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level);
 21.1208 -            envelope->dwAttackTime = hap_periodic->attack_length * 1000;
 21.1209 -            envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level);
 21.1210 -            envelope->dwFadeTime = hap_periodic->fade_length * 1000;
 21.1211 -        }
 21.1212 -
 21.1213 -        break;
 21.1214 -
 21.1215 -    case SDL_HAPTIC_SPRING:
 21.1216 -    case SDL_HAPTIC_DAMPER:
 21.1217 -    case SDL_HAPTIC_INERTIA:
 21.1218 -    case SDL_HAPTIC_FRICTION:
 21.1219 -        hap_condition = &src->condition;
 21.1220 -        condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes);
 21.1221 -        if (condition == NULL) {
 21.1222 -            return SDL_OutOfMemory();
 21.1223 -        }
 21.1224 -        SDL_memset(condition, 0, sizeof(DICONDITION));
 21.1225 -
 21.1226 -        /* Specifics */
 21.1227 -        for (i = 0; i < (int) dest->cAxes; i++) {
 21.1228 -            condition[i].lOffset = CONVERT(hap_condition->center[i]);
 21.1229 -            condition[i].lPositiveCoefficient =
 21.1230 -                CONVERT(hap_condition->right_coeff[i]);
 21.1231 -            condition[i].lNegativeCoefficient =
 21.1232 -                CONVERT(hap_condition->left_coeff[i]);
 21.1233 -            condition[i].dwPositiveSaturation =
 21.1234 -                CONVERT(hap_condition->right_sat[i]);
 21.1235 -            condition[i].dwNegativeSaturation =
 21.1236 -                CONVERT(hap_condition->left_sat[i]);
 21.1237 -            condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]);
 21.1238 -        }
 21.1239 -        dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes;
 21.1240 -        dest->lpvTypeSpecificParams = condition;
 21.1241 -
 21.1242 -        /* Generics */
 21.1243 -        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
 21.1244 -        dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button);
 21.1245 -        dest->dwTriggerRepeatInterval = hap_condition->interval;
 21.1246 -        dest->dwStartDelay = hap_condition->delay * 1000;       /* In microseconds. */
 21.1247 -
 21.1248 -        /* Direction. */
 21.1249 -        if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
 21.1250 -            < 0) {
 21.1251 -            return -1;
 21.1252 -        }
 21.1253 -
 21.1254 -        /* Envelope - Not actually supported by most CONDITION implementations. */
 21.1255 -        SDL_free(dest->lpEnvelope);
 21.1256 -        dest->lpEnvelope = NULL;
 21.1257 -
 21.1258 -        break;
 21.1259 -
 21.1260 -    case SDL_HAPTIC_RAMP:
 21.1261 -        hap_ramp = &src->ramp;
 21.1262 -        ramp = SDL_malloc(sizeof(DIRAMPFORCE));
 21.1263 -        if (ramp == NULL) {
 21.1264 -            return SDL_OutOfMemory();
 21.1265 -        }
 21.1266 -        SDL_memset(ramp, 0, sizeof(DIRAMPFORCE));
 21.1267 -
 21.1268 -        /* Specifics */
 21.1269 -        ramp->lStart = CONVERT(hap_ramp->start);
 21.1270 -        ramp->lEnd = CONVERT(hap_ramp->end);
 21.1271 -        dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE);
 21.1272 -        dest->lpvTypeSpecificParams = ramp;
 21.1273 -
 21.1274 -        /* Generics */
 21.1275 -        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
 21.1276 -        dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button);
 21.1277 -        dest->dwTriggerRepeatInterval = hap_ramp->interval;
 21.1278 -        dest->dwStartDelay = hap_ramp->delay * 1000;    /* In microseconds. */
 21.1279 -
 21.1280 -        /* Direction. */
 21.1281 -        if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
 21.1282 -            return -1;
 21.1283 -        }
 21.1284 -
 21.1285 -        /* Envelope */
 21.1286 -        if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
 21.1287 -            SDL_free(dest->lpEnvelope);
 21.1288 -            dest->lpEnvelope = NULL;
 21.1289 -        } else {
 21.1290 -            envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level);
 21.1291 -            envelope->dwAttackTime = hap_ramp->attack_length * 1000;
 21.1292 -            envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level);
 21.1293 -            envelope->dwFadeTime = hap_ramp->fade_length * 1000;
 21.1294 -        }
 21.1295 -
 21.1296 -        break;
 21.1297 -
 21.1298 -    case SDL_HAPTIC_CUSTOM:
 21.1299 -        hap_custom = &src->custom;
 21.1300 -        custom = SDL_malloc(sizeof(DICUSTOMFORCE));
 21.1301 -        if (custom == NULL) {
 21.1302 -            return SDL_OutOfMemory();
 21.1303 -        }
 21.1304 -        SDL_memset(custom, 0, sizeof(DICUSTOMFORCE));
 21.1305 -
 21.1306 -        /* Specifics */
 21.1307 -        custom->cChannels = hap_custom->channels;
 21.1308 -        custom->dwSamplePeriod = hap_custom->period * 1000;
 21.1309 -        custom->cSamples = hap_custom->samples;
 21.1310 -        custom->rglForceData =
 21.1311 -            SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
 21.1312 -        for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) {      /* Copy data. */
 21.1313 -            custom->rglForceData[i] = CONVERT(hap_custom->data[i]);
 21.1314 -        }
 21.1315 -        dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE);
 21.1316 -        dest->lpvTypeSpecificParams = custom;
 21.1317 -
 21.1318 -        /* Generics */
 21.1319 -        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
 21.1320 -        dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button);
 21.1321 -        dest->dwTriggerRepeatInterval = hap_custom->interval;
 21.1322 -        dest->dwStartDelay = hap_custom->delay * 1000;  /* In microseconds. */
 21.1323 -
 21.1324 -        /* Direction. */
 21.1325 -        if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) <
 21.1326 -            0) {
 21.1327 -            return -1;
 21.1328 -        }
 21.1329 -
 21.1330 -        /* Envelope */
 21.1331 -        if ((hap_custom->attack_length == 0)
 21.1332 -            && (hap_custom->fade_length == 0)) {
 21.1333 -            SDL_free(dest->lpEnvelope);
 21.1334 -            dest->lpEnvelope = NULL;
 21.1335 -        } else {
 21.1336 -            envelope->dwAttackLevel = CONVERT(hap_custom->attack_level);
 21.1337 -            envelope->dwAttackTime = hap_custom->attack_length * 1000;
 21.1338 -            envelope->dwFadeLevel = CONVERT(hap_custom->fade_level);
 21.1339 -            envelope->dwFadeTime = hap_custom->fade_length * 1000;
 21.1340 -        }
 21.1341 -
 21.1342 -        break;
 21.1343 -
 21.1344 -
 21.1345 -    default:
 21.1346 -        return SDL_SetError("Haptic: Unknown effect type.");
 21.1347 -    }
 21.1348 -
 21.1349 -    return 0;
 21.1350 -}
 21.1351 -
 21.1352 -
 21.1353 -/*
 21.1354 - * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT.
 21.1355 - */
 21.1356 -static void
 21.1357 -SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type)
 21.1358 -{
 21.1359 -    DICUSTOMFORCE *custom;
 21.1360 -
 21.1361 -    SDL_free(effect->lpEnvelope);
 21.1362 -    effect->lpEnvelope = NULL;
 21.1363 -    SDL_free(effect->rgdwAxes);
 21.1364 -    effect->rgdwAxes = NULL;
 21.1365 -    if (effect->lpvTypeSpecificParams != NULL) {
 21.1366 -        if (type == SDL_HAPTIC_CUSTOM) {        /* Must free the custom data. */
 21.1367 -            custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams;
 21.1368 -            SDL_free(custom->rglForceData);
 21.1369 -            custom->rglForceData = NULL;
 21.1370 -        }
 21.1371 -        SDL_free(effect->lpvTypeSpecificParams);
 21.1372 -        effect->lpvTypeSpecificParams = NULL;
 21.1373 -    }
 21.1374 -    SDL_free(effect->rglDirection);
 21.1375 -    effect->rglDirection = NULL;
 21.1376 -}
 21.1377 -
 21.1378 -
 21.1379 -/*
 21.1380 - * Gets the effect type from the generic SDL haptic effect wrapper.
 21.1381 - */
 21.1382 -static REFGUID
 21.1383 -SDL_SYS_HapticEffectType(SDL_HapticEffect * effect)
 21.1384 -{
 21.1385 -    switch (effect->type) {
 21.1386 -    case SDL_HAPTIC_CONSTANT:
 21.1387 -        return &GUID_ConstantForce;
 21.1388 -
 21.1389 -    case SDL_HAPTIC_RAMP:
 21.1390 -        return &GUID_RampForce;
 21.1391 -
 21.1392 -    /* !!! FIXME: put this back when we have more bits in 2.1 */
 21.1393 -    /* case SDL_HAPTIC_SQUARE:
 21.1394 -        return &GUID_Square; */
 21.1395 -
 21.1396 -    case SDL_HAPTIC_SINE:
 21.1397 -        return &GUID_Sine;
 21.1398 -
 21.1399 -    case SDL_HAPTIC_TRIANGLE:
 21.1400 -        return &GUID_Triangle;
 21.1401 -
 21.1402 -    case SDL_HAPTIC_SAWTOOTHUP:
 21.1403 -        return &GUID_SawtoothUp;
 21.1404 -
 21.1405 -    case SDL_HAPTIC_SAWTOOTHDOWN:
 21.1406 -        return &GUID_SawtoothDown;
 21.1407 -
 21.1408 -    case SDL_HAPTIC_SPRING:
 21.1409 -        return &GUID_Spring;
 21.1410 -
 21.1411 -    case SDL_HAPTIC_DAMPER:
 21.1412 -        return &GUID_Damper;
 21.1413 -
 21.1414 -    case SDL_HAPTIC_INERTIA:
 21.1415 -        return &GUID_Inertia;
 21.1416 -
 21.1417 -    case SDL_HAPTIC_FRICTION:
 21.1418 -        return &GUID_Friction;
 21.1419 -
 21.1420 -    case SDL_HAPTIC_CUSTOM:
 21.1421 -        return &GUID_CustomForce;
 21.1422 -
 21.1423 -    default:
 21.1424 -        return NULL;
 21.1425 -    }
 21.1426 -}
 21.1427 -
 21.1428 -
 21.1429 -/*
 21.1430 - * Creates a new haptic effect.
 21.1431 - */
 21.1432 -int
 21.1433 -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
 21.1434 -                        SDL_HapticEffect * base)
 21.1435 -{
 21.1436 -    HRESULT ret;
 21.1437 -    REFGUID type = SDL_SYS_HapticEffectType(base);
 21.1438 -
 21.1439 -    if ((type == NULL) && (!haptic->hwdata->bXInputHaptic)) {
 21.1440 -        SDL_SetError("Haptic: Unknown effect type.");
 21.1441 -        goto err_hweffect;
 21.1442 -    }
 21.1443 -
 21.1444 -    /* Alloc the effect. */
 21.1445 -    effect->hweffect = (struct haptic_hweffect *)
 21.1446 -        SDL_malloc(sizeof(struct haptic_hweffect));
 21.1447 -    if (effect->hweffect == NULL) {
 21.1448 -        SDL_OutOfMemory();
 21.1449 -        goto err_hweffect;
 21.1450 -    }
 21.1451 -
 21.1452 -    SDL_zerop(effect->hweffect);
 21.1453 -
 21.1454 -    if (haptic->hwdata->bXInputHaptic) {
 21.1455 -        SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
 21.1456 -        return SDL_SYS_HapticUpdateEffect(haptic, effect, base);
 21.1457 -    }
 21.1458 -
 21.1459 -    /* Get the effect. */
 21.1460 -    if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) {
 21.1461 -        goto err_effectdone;
 21.1462 -    }
 21.1463 -
 21.1464 -    /* Create the actual effect. */
 21.1465 -    ret = IDirectInputDevice8_CreateEffect(haptic->hwdata->device, type,
 21.1466 -                                           &effect->hweffect->effect,
 21.1467 -                                           &effect->hweffect->ref, NULL);
 21.1468 -    if (FAILED(ret)) {
 21.1469 -        DI_SetError("Unable to create effect", ret);
 21.1470 -        goto err_effectdone;
 21.1471 -    }
 21.1472 -
 21.1473 -    return 0;
 21.1474 -
 21.1475 -  err_effectdone:
 21.1476 -    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type);
 21.1477 -  err_hweffect:
 21.1478 -    SDL_free(effect->hweffect);
 21.1479 -    effect->hweffect = NULL;
 21.1480 -    return -1;
 21.1481 -}
 21.1482 -
 21.1483 -
 21.1484 -/*
 21.1485 - * Updates an effect.
 21.1486 - */
 21.1487 -int
 21.1488 -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
 21.1489 -                           struct haptic_effect *effect,
 21.1490 -                           SDL_HapticEffect * data)
 21.1491 -{
 21.1492 -    HRESULT ret;
 21.1493 -    DWORD flags;
 21.1494 -    DIEFFECT temp;
 21.1495 -
 21.1496 -    if (haptic->hwdata->bXInputHaptic) {
 21.1497 -        XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
 21.1498 -        SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
 21.1499 -        vib->wLeftMotorSpeed = data->leftright.large_magnitude;
 21.1500 -        vib->wRightMotorSpeed = data->leftright.small_magnitude;
 21.1501 -        SDL_LockMutex(haptic->hwdata->mutex);
 21.1502 -        if (haptic->hwdata->stopTicks) {  /* running right now? Update it. */
 21.1503 -            XINPUTSETSTATE(haptic->hwdata->userid, vib);
 21.1504 -        }
 21.1505 -        SDL_UnlockMutex(haptic->hwdata->mutex);
 21.1506 -        return 0;
 21.1507 -    }
 21.1508 -
 21.1509 -    /* Get the effect. */
 21.1510 -    SDL_memset(&temp, 0, sizeof(DIEFFECT));
 21.1511 -    if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) {
 21.1512 -        goto err_update;
 21.1513 -    }
 21.1514 -
 21.1515 -    /* Set the flags.  Might be worthwhile to diff temp with loaded effect and
 21.1516 -     *  only change those parameters. */
 21.1517 -    flags = DIEP_DIRECTION |
 21.1518 -        DIEP_DURATION |
 21.1519 -        DIEP_ENVELOPE |
 21.1520 -        DIEP_STARTDELAY |
 21.1521 -        DIEP_TRIGGERBUTTON |
 21.1522 -        DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS;
 21.1523 -
 21.1524 -    /* Create the actual effect. */
 21.1525 -    ret =
 21.1526 -        IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags);
 21.1527 -    if (FAILED(ret)) {
 21.1528 -        DI_SetError("Unable to update effect", ret);
 21.1529 -        goto err_update;
 21.1530 -    }
 21.1531 -
 21.1532 -    /* Copy it over. */
 21.1533 -    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type);
 21.1534 -    SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT));
 21.1535 -
 21.1536 -    return 0;
 21.1537 -
 21.1538 -  err_update:
 21.1539 -    SDL_SYS_HapticFreeDIEFFECT(&temp, data->type);
 21.1540 -    return -1;
 21.1541 -}
 21.1542 -
 21.1543 -
 21.1544 -/*
 21.1545 - * Runs an effect.
 21.1546 - */
 21.1547 -int
 21.1548 -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
 21.1549 -                        Uint32 iterations)
 21.1550 -{
 21.1551 -    HRESULT ret;
 21.1552 -    DWORD iter;
 21.1553 -
 21.1554 -    if (haptic->hwdata->bXInputHaptic) {
 21.1555 -        XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
 21.1556 -        SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
 21.1557 -        SDL_LockMutex(haptic->hwdata->mutex);
 21.1558 -        if(effect->effect.leftright.length == SDL_HAPTIC_INFINITY || iterations == SDL_HAPTIC_INFINITY) {
 21.1559 -            haptic->hwdata->stopTicks = SDL_HAPTIC_INFINITY;
 21.1560 -        } else if ((!effect->effect.leftright.length) || (!iterations)) {
 21.1561 -            /* do nothing. Effect runs for zero milliseconds. */
 21.1562 -        } else {
 21.1563 -            haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
 21.1564 -            if ((haptic->hwdata->stopTicks == SDL_HAPTIC_INFINITY) || (haptic->hwdata->stopTicks == 0)) {
 21.1565 -                haptic->hwdata->stopTicks = 1;  /* fix edge cases. */
 21.1566 -            }
 21.1567 -        }
 21.1568 -        SDL_UnlockMutex(haptic->hwdata->mutex);
 21.1569 -        return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
 21.1570 -    }
 21.1571 -
 21.1572 -    /* Check if it's infinite. */
 21.1573 -    if (iterations == SDL_HAPTIC_INFINITY) {
 21.1574 -        iter = INFINITE;
 21.1575 -    } else
 21.1576 -        iter = iterations;
 21.1577 -
 21.1578 -    /* Run the effect. */
 21.1579 -    ret = IDirectInputEffect_Start(effect->hweffect->ref, iter, 0);
 21.1580 -    if (FAILED(ret)) {
 21.1581 -        return DI_SetError("Running the effect", ret);
 21.1582 -    }
 21.1583 -
 21.1584 -    return 0;
 21.1585 -}
 21.1586 -
 21.1587 -
 21.1588 -/*
 21.1589 - * Stops an effect.
 21.1590 - */
 21.1591 -int
 21.1592 -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 21.1593 -{
 21.1594 -    HRESULT ret;
 21.1595 -
 21.1596 -    if (haptic->hwdata->bXInputHaptic) {
 21.1597 -        XINPUT_VIBRATION vibration = { 0, 0 };
 21.1598 -        SDL_LockMutex(haptic->hwdata->mutex);
 21.1599 -        haptic->hwdata->stopTicks = 0;
 21.1600 -        SDL_UnlockMutex(haptic->hwdata->mutex);
 21.1601 -        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
 21.1602 -    }
 21.1603 -
 21.1604 -    ret = IDirectInputEffect_Stop(effect->hweffect->ref);
 21.1605 -    if (FAILED(ret)) {
 21.1606 -        return DI_SetError("Unable to stop effect", ret);
 21.1607 -    }
 21.1608 -
 21.1609 -    return 0;
 21.1610 -}
 21.1611 -
 21.1612 -
 21.1613 -/*
 21.1614 - * Frees the effect.
 21.1615 - */
 21.1616 -void
 21.1617 -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 21.1618 -{
 21.1619 -    HRESULT ret;
 21.1620 -
 21.1621 -    if (haptic->hwdata->bXInputHaptic) {
 21.1622 -        SDL_SYS_HapticStopEffect(haptic, effect);
 21.1623 -    } else {
 21.1624 -        ret = IDirectInputEffect_Unload(effect->hweffect->ref);
 21.1625 -        if (FAILED(ret)) {
 21.1626 -            DI_SetError("Removing effect from the device", ret);
 21.1627 -        }
 21.1628 -        SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect,
 21.1629 -                                   effect->effect.type);
 21.1630 -    }
 21.1631 -    SDL_free(effect->hweffect);
 21.1632 -    effect->hweffect = NULL;
 21.1633 -}
 21.1634 -
 21.1635 -
 21.1636 -/*
 21.1637 - * Gets the status of a haptic effect.
 21.1638 - */
 21.1639 -int
 21.1640 -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
 21.1641 -                              struct haptic_effect *effect)
 21.1642 -{
 21.1643 -    HRESULT ret;
 21.1644 -    DWORD status;
 21.1645 -
 21.1646 -    ret = IDirectInputEffect_GetEffectStatus(effect->hweffect->ref, &status);
 21.1647 -    if (FAILED(ret)) {
 21.1648 -        return DI_SetError("Getting effect status", ret);
 21.1649 -    }
 21.1650 -
 21.1651 -    if (status == 0)
 21.1652 -        return SDL_FALSE;
 21.1653 -    return SDL_TRUE;
 21.1654 -}
 21.1655 -
 21.1656 -
 21.1657 -/*
 21.1658 - * Sets the gain.
 21.1659 - */
 21.1660 -int
 21.1661 -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
 21.1662 -{
 21.1663 -    HRESULT ret;
 21.1664 -    DIPROPDWORD dipdw;
 21.1665 -
 21.1666 -    /* Create the weird structure thingy. */
 21.1667 -    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
 21.1668 -    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
 21.1669 -    dipdw.diph.dwObj = 0;
 21.1670 -    dipdw.diph.dwHow = DIPH_DEVICE;
 21.1671 -    dipdw.dwData = gain * 100;  /* 0 to 10,000 */
 21.1672 -
 21.1673 -    /* Try to set the autocenter. */
 21.1674 -    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
 21.1675 -                                          DIPROP_FFGAIN, &dipdw.diph);
 21.1676 -    if (FAILED(ret)) {
 21.1677 -        return DI_SetError("Setting gain", ret);
 21.1678 -    }
 21.1679 -
 21.1680 -    return 0;
 21.1681 -}
 21.1682 -
 21.1683 -
 21.1684 -/*
 21.1685 - * Sets the autocentering.
 21.1686 - */
 21.1687 -int
 21.1688 -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
 21.1689 -{
 21.1690 -    HRESULT ret;
 21.1691 -    DIPROPDWORD dipdw;
 21.1692 -
 21.1693 -    /* Create the weird structure thingy. */
 21.1694 -    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
 21.1695 -    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
 21.1696 -    dipdw.diph.dwObj = 0;
 21.1697 -    dipdw.diph.dwHow = DIPH_DEVICE;
 21.1698 -    dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF :
 21.1699 -        DIPROPAUTOCENTER_ON;
 21.1700 -
 21.1701 -    /* Try to set the autocenter. */
 21.1702 -    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
 21.1703 -                                          DIPROP_AUTOCENTER, &dipdw.diph);
 21.1704 -    if (FAILED(ret)) {
 21.1705 -        return DI_SetError("Setting autocenter", ret);
 21.1706 -    }
 21.1707 -
 21.1708 -    return 0;
 21.1709 -}
 21.1710 -
 21.1711 -
 21.1712 -/*
 21.1713 - * Pauses the device.
 21.1714 - */
 21.1715 -int
 21.1716 -SDL_SYS_HapticPause(SDL_Haptic * haptic)
 21.1717 -{
 21.1718 -    HRESULT ret;
 21.1719 -
 21.1720 -    /* Pause the device. */
 21.1721 -    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 21.1722 -                                                       DISFFC_PAUSE);
 21.1723 -    if (FAILED(ret)) {
 21.1724 -        return DI_SetError("Pausing the device", ret);
 21.1725 -    }
 21.1726 -
 21.1727 -    return 0;
 21.1728 -}
 21.1729 -
 21.1730 -
 21.1731 -/*
 21.1732 - * Pauses the device.
 21.1733 - */
 21.1734 -int
 21.1735 -SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
 21.1736 -{
 21.1737 -    HRESULT ret;
 21.1738 -
 21.1739 -    /* Unpause the device. */
 21.1740 -    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 21.1741 -                                                       DISFFC_CONTINUE);
 21.1742 -    if (FAILED(ret)) {
 21.1743 -        return DI_SetError("Pausing the device", ret);
 21.1744 -    }
 21.1745 -
 21.1746 -    return 0;
 21.1747 -}
 21.1748 -
 21.1749 -
 21.1750 -/*
 21.1751 - * Stops all the playing effects on the device.
 21.1752 - */
 21.1753 -int
 21.1754 -SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
 21.1755 -{
 21.1756 -    HRESULT ret;
 21.1757 -
 21.1758 -    if (haptic->hwdata->bXInputHaptic) {
 21.1759 -        XINPUT_VIBRATION vibration = { 0, 0 };
 21.1760 -        SDL_LockMutex(haptic->hwdata->mutex);
 21.1761 -        haptic->hwdata->stopTicks = 0;
 21.1762 -        SDL_UnlockMutex(haptic->hwdata->mutex);
 21.1763 -        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
 21.1764 -    }
 21.1765 -
 21.1766 -    /* Try to stop the effects. */
 21.1767 -    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
 21.1768 -                                                       DISFFC_STOPALL);
 21.1769 -    if (FAILED(ret)) {
 21.1770 -        return DI_SetError("Stopping the device", ret);
 21.1771 -    }
 21.1772 -
 21.1773 -    return 0;
 21.1774 -}
 21.1775 -
 21.1776 -
 21.1777 -/* !!! FIXME: this is a hack, remove this later. */
 21.1778 -/* Since XInput doesn't offer a way to vibrate for X time, we hook into
 21.1779 - *  SDL_PumpEvents() to check if it's time to stop vibrating with some
 21.1780 - *  frequency.
 21.1781 - * In practice, this works for 99% of use cases. But in an ideal world,
 21.1782 - *  we do this in a separate thread so that:
 21.1783 - *    - we aren't bound to when the app chooses to pump the event queue.
 21.1784 - *    - we aren't adding more polling to the event queue
 21.1785 - *    - we can emulate all the haptic effects correctly (start on a delay,
 21.1786 - *      mix multiple effects, etc).
 21.1787 - *
 21.1788 - * Mostly, this is here to get rumbling to work, and all the other features
 21.1789 - *  are absent in the XInput path for now.  :(
 21.1790 - */
 21.1791 -static int SDLCALL
 21.1792 -SDL_RunXInputHaptic(void *arg)
 21.1793 -{
 21.1794 -    struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
 21.1795 -
 21.1796 -    while (!hwdata->stopThread) {
 21.1797 -        SDL_Delay(50);
 21.1798 -        SDL_LockMutex(hwdata->mutex);
 21.1799 -        /* If we're currently running and need to stop... */
 21.1800 -        if (hwdata->stopTicks) {
 21.1801 -            if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_TICKS_PASSED(SDL_GetTicks(), hwdata->stopTicks)) {
 21.1802 -                XINPUT_VIBRATION vibration = { 0, 0 };
 21.1803 -                hwdata->stopTicks = 0;
 21.1804 -                XINPUTSETSTATE(hwdata->userid, &vibration);
 21.1805 -            }
 21.1806 -        }
 21.1807 -        SDL_UnlockMutex(hwdata->mutex);
 21.1808 -    }
 21.1809 -
 21.1810 -    return 0;
 21.1811 -}
 21.1812 -
 21.1813 -#endif /* SDL_HAPTIC_DINPUT */
 21.1814 -
 21.1815 -/* vi: set ts=4 sw=4 expandtab: */
    22.1 --- a/src/haptic/windows/SDL_syshaptic_c.h	Thu Jul 03 17:36:08 2014 -0300
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,28 +0,0 @@
    22.4 -/*
    22.5 -  Simple DirectMedia Layer
    22.6 -  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    22.7 -
    22.8 -  This software is provided 'as-is', without any express or implied
    22.9 -  warranty.  In no event will the authors be held liable for any damages
   22.10 -  arising from the use of this software.
   22.11 -
   22.12 -  Permission is granted to anyone to use this software for any purpose,
   22.13 -  including commercial applications, and to alter it and redistribute it
   22.14 -  freely, subject to the following restrictions:
   22.15 -
   22.16 -  1. The origin of this software must not be misrepresented; you must not
   22.17 -     claim that you wrote the original software. If you use this software
   22.18 -     in a product, an acknowledgment in the product documentation would be
   22.19 -     appreciated but is not required.
   22.20 -  2. Altered source versions must be plainly marked as such, and must not be
   22.21 -     misrepresented as being the original software.
   22.22 -  3. This notice may not be removed or altered from any source distribution.
   22.23 -*/
   22.24 -
   22.25 -extern int DirectInputHaptic_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
   22.26 -extern int DirectInputHaptic_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
   22.27 -extern int XInputHaptic_MaybeAddDevice(const DWORD dwUserid);
   22.28 -extern int XInputHaptic_MaybeRemoveDevice(const DWORD dwUserid);
   22.29 -
   22.30 -/* vi: set ts=4 sw=4 expandtab: */
   22.31 -
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/haptic/windows/SDL_windowshaptic.c	Thu Jul 03 15:39:55 2014 -0700
    23.3 @@ -0,0 +1,445 @@
    23.4 +/*
    23.5 +  Simple DirectMedia Layer
    23.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    23.7 +
    23.8 +  This software is provided 'as-is', without any express or implied
    23.9 +  warranty.  In no event will the authors be held liable for any damages
   23.10 +  arising from the use of this software.
   23.11 +
   23.12 +  Permission is granted to anyone to use this software for any purpose,
   23.13 +  including commercial applications, and to alter it and redistribute it
   23.14 +  freely, subject to the following restrictions:
   23.15 +
   23.16 +  1. The origin of this software must not be misrepresented; you must not
   23.17 +     claim that you wrote the original software. If you use this software
   23.18 +     in a product, an acknowledgment in the product documentation would be
   23.19 +     appreciated but is not required.
   23.20 +  2. Altered source versions must be plainly marked as such, and must not be
   23.21 +     misrepresented as being the original software.
   23.22 +  3. This notice may not be removed or altered from any source distribution.
   23.23 +*/
   23.24 +#include "../../SDL_internal.h"
   23.25 +
   23.26 +#if SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT
   23.27 +
   23.28 +#include "SDL_assert.h"
   23.29 +#include "SDL_thread.h"
   23.30 +#include "SDL_mutex.h"
   23.31 +#include "SDL_timer.h"
   23.32 +#include "SDL_hints.h"
   23.33 +#include "SDL_haptic.h"
   23.34 +#include "../SDL_syshaptic.h"
   23.35 +#include "SDL_joystick.h"
   23.36 +#include "../../joystick/SDL_sysjoystick.h"     /* For the real SDL_Joystick */
   23.37 +#include "../../joystick/windows/SDL_windowsjoystick_c.h"      /* For joystick hwdata */
   23.38 +#include "../../joystick/windows/SDL_xinputjoystick_c.h"      /* For xinput rumble */
   23.39 +
   23.40 +#include "SDL_windowshaptic_c.h"
   23.41 +#include "SDL_dinputhaptic_c.h"
   23.42 +#include "SDL_xinputhaptic_c.h"
   23.43 +
   23.44 +
   23.45 +/*
   23.46 + * Internal stuff.
   23.47 + */
   23.48 +SDL_hapticlist_item *SDL_hapticlist = NULL;
   23.49 +static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
   23.50 +static int numhaptics = 0;
   23.51 +
   23.52 +
   23.53 +/*
   23.54 + * Initializes the haptic subsystem.
   23.55 + */
   23.56 +int
   23.57 +SDL_SYS_HapticInit(void)
   23.58 +{
   23.59 +    if (SDL_DINPUT_HapticInit() < 0) {
   23.60 +        return -1;
   23.61 +    }
   23.62 +    if (SDL_XINPUT_HapticInit() < 0) {
   23.63 +        return -1;
   23.64 +    }
   23.65 +    return numhaptics;
   23.66 +}
   23.67 +
   23.68 +int
   23.69 +SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item)
   23.70 +{
   23.71 +    if (SDL_hapticlist_tail == NULL) {
   23.72 +        SDL_hapticlist = SDL_hapticlist_tail = item;
   23.73 +    } else {
   23.74 +        SDL_hapticlist_tail->next = item;
   23.75 +        SDL_hapticlist_tail = item;
   23.76 +    }
   23.77 +
   23.78 +    /* Device has been added. */
   23.79 +    ++numhaptics;
   23.80 +
   23.81 +    return numhaptics;
   23.82 +}
   23.83 +
   23.84 +int
   23.85 +SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item)
   23.86 +{
   23.87 +    const int retval = item->haptic ? item->haptic->index : -1;
   23.88 +    if (prev != NULL) {
   23.89 +        prev->next = item->next;
   23.90 +    } else {
   23.91 +        SDL_assert(SDL_hapticlist == item);
   23.92 +        SDL_hapticlist = item->next;
   23.93 +    }
   23.94 +    if (item == SDL_hapticlist_tail) {
   23.95 +        SDL_hapticlist_tail = prev;
   23.96 +    }
   23.97 +    --numhaptics;
   23.98 +    /* !!! TODO: Send a haptic remove event? */
   23.99 +    SDL_free(item);
  23.100 +    return retval;
  23.101 +}
  23.102 +
  23.103 +int
  23.104 +SDL_SYS_NumHaptics()
  23.105 +{
  23.106 +    return numhaptics;
  23.107 +}
  23.108 +
  23.109 +static SDL_hapticlist_item *
  23.110 +HapticByDevIndex(int device_index)
  23.111 +{
  23.112 +    SDL_hapticlist_item *item = SDL_hapticlist;
  23.113 +
  23.114 +    if ((device_index < 0) || (device_index >= numhaptics)) {
  23.115 +        return NULL;
  23.116 +    }
  23.117 +
  23.118 +    while (device_index > 0) {
  23.119 +        SDL_assert(item != NULL);
  23.120 +        --device_index;
  23.121 +        item = item->next;
  23.122 +    }
  23.123 +    return item;
  23.124 +}
  23.125 +
  23.126 +/*
  23.127 + * Return the name of a haptic device, does not need to be opened.
  23.128 + */
  23.129 +const char *
  23.130 +SDL_SYS_HapticName(int index)
  23.131 +{
  23.132 +    SDL_hapticlist_item *item = HapticByDevIndex(index);
  23.133 +    return item->name;
  23.134 +}
  23.135 +
  23.136 +/*
  23.137 + * Opens a haptic device for usage.
  23.138 + */
  23.139 +int
  23.140 +SDL_SYS_HapticOpen(SDL_Haptic * haptic)
  23.141 +{
  23.142 +    SDL_hapticlist_item *item = HapticByDevIndex(haptic->index);
  23.143 +    if (item->bXInputHaptic) {
  23.144 +        return SDL_XINPUT_HapticOpen(haptic, item);
  23.145 +    } else {
  23.146 +        return SDL_DINPUT_HapticOpen(haptic, item);
  23.147 +    }
  23.148 +}
  23.149 +
  23.150 +
  23.151 +/*
  23.152 + * Opens a haptic device from first mouse it finds for usage.
  23.153 + */
  23.154 +int
  23.155 +SDL_SYS_HapticMouse(void)
  23.156 +{
  23.157 +#if SDL_HAPTIC_DINPUT
  23.158 +    SDL_hapticlist_item *item;
  23.159 +    int index = 0;
  23.160 +
  23.161 +    /* Grab the first mouse haptic device we find. */
  23.162 +    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  23.163 +        if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
  23.164 +            return index;
  23.165 +        }
  23.166 +        ++index;
  23.167 +    }
  23.168 +#endif /* SDL_HAPTIC_DINPUT */
  23.169 +    return -1;
  23.170 +}
  23.171 +
  23.172 +
  23.173 +/*
  23.174 + * Checks to see if a joystick has haptic features.
  23.175 + */
  23.176 +int
  23.177 +SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
  23.178 +{
  23.179 +    const struct joystick_hwdata *hwdata = joystick->hwdata;
  23.180 +#if SDL_HAPTIC_XINPUT
  23.181 +    if (hwdata->bXInputHaptic) {
  23.182 +        return 1;
  23.183 +    }
  23.184 +#endif
  23.185 +#if SDL_HAPTIC_DINPUT
  23.186 +    if (hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
  23.187 +        return 1;
  23.188 +    }
  23.189 +#endif
  23.190 +    return 0;
  23.191 +}
  23.192 +
  23.193 +/*
  23.194 + * Checks to see if the haptic device and joystick are in reality the same.
  23.195 + */
  23.196 +int
  23.197 +SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
  23.198 +{
  23.199 +    if (joystick->hwdata->bXInputHaptic != haptic->hwdata->bXInputHaptic) {
  23.200 +        return 0;  /* one is XInput, one is not; not the same device. */
  23.201 +    } else if (joystick->hwdata->bXInputHaptic) {
  23.202 +        return SDL_XINPUT_JoystickSameHaptic(haptic, joystick);
  23.203 +    } else {
  23.204 +        return SDL_DINPUT_JoystickSameHaptic(haptic, joystick);
  23.205 +    }
  23.206 +}
  23.207 +
  23.208 +/*
  23.209 + * Opens a SDL_Haptic from a SDL_Joystick.
  23.210 + */
  23.211 +int
  23.212 +SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
  23.213 +{
  23.214 +    if (joystick->hwdata->bXInputDevice) {
  23.215 +        return SDL_XINPUT_HapticOpenFromJoystick(haptic, joystick);
  23.216 +    } else {
  23.217 +        return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick);
  23.218 +    }
  23.219 +}
  23.220 +
  23.221 +/*
  23.222 + * Closes the haptic device.
  23.223 + */
  23.224 +void
  23.225 +SDL_SYS_HapticClose(SDL_Haptic * haptic)
  23.226 +{
  23.227 +    if (haptic->hwdata) {
  23.228 +
  23.229 +        /* Free effects. */
  23.230 +        SDL_free(haptic->effects);
  23.231 +        haptic->effects = NULL;
  23.232 +        haptic->neffects = 0;
  23.233 +
  23.234 +        /* Clean up */
  23.235 +        if (haptic->hwdata->bXInputHaptic) {
  23.236 +            SDL_XINPUT_HapticClose(haptic);
  23.237 +        } else {
  23.238 +            SDL_DINPUT_HapticClose(haptic);
  23.239 +        }
  23.240 +
  23.241 +        /* Free */
  23.242 +        SDL_free(haptic->hwdata);
  23.243 +        haptic->hwdata = NULL;
  23.244 +    }
  23.245 +}
  23.246 +
  23.247 +/*
  23.248 + * Clean up after system specific haptic stuff
  23.249 + */
  23.250 +void
  23.251 +SDL_SYS_HapticQuit(void)
  23.252 +{
  23.253 +    SDL_hapticlist_item *item;
  23.254 +    SDL_hapticlist_item *next = NULL;
  23.255 +    SDL_Haptic *hapticitem = NULL;
  23.256 +
  23.257 +    extern SDL_Haptic *SDL_haptics;
  23.258 +    for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
  23.259 +        if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
  23.260 +            /* we _have_ to stop the thread before we free the XInput DLL! */
  23.261 +            hapticitem->hwdata->stopThread = 1;
  23.262 +            SDL_WaitThread(hapticitem->hwdata->thread, NULL);
  23.263 +            hapticitem->hwdata->thread = NULL;
  23.264 +        }
  23.265 +    }
  23.266 +
  23.267 +    for (item = SDL_hapticlist; item; item = next) {
  23.268 +        /* Opened and not closed haptics are leaked, this is on purpose.
  23.269 +         * Close your haptic devices after usage. */
  23.270 +        /* !!! FIXME: (...is leaking on purpose a good idea?) - No, of course not. */
  23.271 +        next = item->next;
  23.272 +        SDL_free(item->name);
  23.273 +        SDL_free(item);
  23.274 +    }
  23.275 +
  23.276 +    SDL_XINPUT_HapticQuit();
  23.277 +    SDL_DINPUT_HapticQuit();
  23.278 +}
  23.279 +
  23.280 +/*
  23.281 + * Creates a new haptic effect.
  23.282 + */
  23.283 +int
  23.284 +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
  23.285 +                        SDL_HapticEffect * base)
  23.286 +{
  23.287 +    int result;
  23.288 +
  23.289 +    /* Alloc the effect. */
  23.290 +    effect->hweffect = (struct haptic_hweffect *)
  23.291 +        SDL_malloc(sizeof(struct haptic_hweffect));
  23.292 +    if (effect->hweffect == NULL) {
  23.293 +        SDL_OutOfMemory();
  23.294 +        return -1;
  23.295 +    }
  23.296 +    SDL_zerop(effect->hweffect);
  23.297 +
  23.298 +    if (haptic->hwdata->bXInputHaptic) {
  23.299 +        result = SDL_XINPUT_HapticNewEffect(haptic, effect, base);
  23.300 +    } else {
  23.301 +        result = SDL_DINPUT_HapticNewEffect(haptic, effect, base);
  23.302 +    }
  23.303 +    if (result < 0) {
  23.304 +        SDL_free(effect->hweffect);
  23.305 +        effect->hweffect = NULL;
  23.306 +    }
  23.307 +    return result;
  23.308 +}
  23.309 +
  23.310 +/*
  23.311 + * Updates an effect.
  23.312 + */
  23.313 +int
  23.314 +SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
  23.315 +                           struct haptic_effect *effect,
  23.316 +                           SDL_HapticEffect * data)
  23.317 +{
  23.318 +    if (haptic->hwdata->bXInputHaptic) {
  23.319 +        return SDL_XINPUT_HapticUpdateEffect(haptic, effect, data);
  23.320 +    } else {
  23.321 +        return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data);
  23.322 +    }
  23.323 +}
  23.324 +
  23.325 +/*
  23.326 + * Runs an effect.
  23.327 + */
  23.328 +int
  23.329 +SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
  23.330 +                        Uint32 iterations)
  23.331 +{
  23.332 +    if (haptic->hwdata->bXInputHaptic) {
  23.333 +        return SDL_XINPUT_HapticRunEffect(haptic, effect, iterations);
  23.334 +    } else {
  23.335 +        return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations);
  23.336 +    }
  23.337 +}
  23.338 +
  23.339 +/*
  23.340 + * Stops an effect.
  23.341 + */
  23.342 +int
  23.343 +SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  23.344 +{
  23.345 +    if (haptic->hwdata->bXInputHaptic) {
  23.346 +        return SDL_XINPUT_HapticStopEffect(haptic, effect);
  23.347 +    } else {
  23.348 +        return SDL_DINPUT_HapticStopEffect(haptic, effect);
  23.349 +    }
  23.350 +}
  23.351 +
  23.352 +/*
  23.353 + * Frees the effect.
  23.354 + */
  23.355 +void
  23.356 +SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  23.357 +{
  23.358 +    if (haptic->hwdata->bXInputHaptic) {
  23.359 +        SDL_XINPUT_HapticDestroyEffect(haptic, effect);
  23.360 +    } else {
  23.361 +        SDL_DINPUT_HapticDestroyEffect(haptic, effect);
  23.362 +    }
  23.363 +    SDL_free(effect->hweffect);
  23.364 +    effect->hweffect = NULL;
  23.365 +}
  23.366 +
  23.367 +/*
  23.368 + * Gets the status of a haptic effect.
  23.369 + */
  23.370 +int
  23.371 +SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
  23.372 +                              struct haptic_effect *effect)
  23.373 +{
  23.374 +    if (haptic->hwdata->bXInputHaptic) {
  23.375 +        return SDL_XINPUT_HapticGetEffectStatus(haptic, effect);
  23.376 +    } else {
  23.377 +        return SDL_DINPUT_HapticGetEffectStatus(haptic, effect);
  23.378 +    }
  23.379 +}
  23.380 +
  23.381 +/*
  23.382 + * Sets the gain.
  23.383 + */
  23.384 +int
  23.385 +SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
  23.386 +{
  23.387 +    if (haptic->hwdata->bXInputHaptic) {
  23.388 +        return SDL_XINPUT_HapticSetGain(haptic, gain);
  23.389 +    } else {
  23.390 +        return SDL_DINPUT_HapticSetGain(haptic, gain);
  23.391 +    }
  23.392 +}
  23.393 +
  23.394 +/*
  23.395 + * Sets the autocentering.
  23.396 + */
  23.397 +int
  23.398 +SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
  23.399 +{
  23.400 +    if (haptic->hwdata->bXInputHaptic) {
  23.401 +        return SDL_XINPUT_HapticSetAutocenter(haptic, autocenter);
  23.402 +    } else {
  23.403 +        return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter);
  23.404 +    }
  23.405 +}
  23.406 +
  23.407 +/*
  23.408 + * Pauses the device.
  23.409 + */
  23.410 +int
  23.411 +SDL_SYS_HapticPause(SDL_Haptic * haptic)
  23.412 +{
  23.413 +    if (haptic->hwdata->bXInputHaptic) {
  23.414 +        return SDL_XINPUT_HapticPause(haptic);
  23.415 +    } else {
  23.416 +        return SDL_DINPUT_HapticPause(haptic);
  23.417 +    }
  23.418 +}
  23.419 +
  23.420 +/*
  23.421 + * Pauses the device.
  23.422 + */
  23.423 +int
  23.424 +SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
  23.425 +{
  23.426 +    if (haptic->hwdata->bXInputHaptic) {
  23.427 +        return SDL_XINPUT_HapticUnpause(haptic);
  23.428 +    } else {
  23.429 +        return SDL_DINPUT_HapticUnpause(haptic);
  23.430 +    }
  23.431 +}
  23.432 +
  23.433 +/*
  23.434 + * Stops all the playing effects on the device.
  23.435 + */
  23.436 +int
  23.437 +SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
  23.438 +{
  23.439 +    if (haptic->hwdata->bXInputHaptic) {
  23.440 +        return SDL_XINPUT_HapticStopAll(haptic);
  23.441 +    } else {
  23.442 +        return SDL_DINPUT_HapticStopAll(haptic);
  23.443 +    }
  23.444 +}
  23.445 +
  23.446 +#endif /* SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT */
  23.447 +
  23.448 +/* vi: set ts=4 sw=4 expandtab: */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/haptic/windows/SDL_windowshaptic_c.h	Thu Jul 03 15:39:55 2014 -0700
    24.3 @@ -0,0 +1,88 @@
    24.4 +/*
    24.5 +  Simple DirectMedia Layer
    24.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    24.7 +
    24.8 +  This software is provided 'as-is', without any express or implied
    24.9 +  warranty.  In no event will the authors be held liable for any damages
   24.10 +  arising from the use of this software.
   24.11 +
   24.12 +  Permission is granted to anyone to use this software for any purpose,
   24.13 +  including commercial applications, and to alter it and redistribute it
   24.14 +  freely, subject to the following restrictions:
   24.15 +
   24.16 +  1. The origin of this software must not be misrepresented; you must not
   24.17 +     claim that you wrote the original software. If you use this software
   24.18 +     in a product, an acknowledgment in the product documentation would be
   24.19 +     appreciated but is not required.
   24.20 +  2. Altered source versions must be plainly marked as such, and must not be
   24.21 +     misrepresented as being the original software.
   24.22 +  3. This notice may not be removed or altered from any source distribution.
   24.23 +*/
   24.24 +#include "../../SDL_internal.h"
   24.25 +
   24.26 +#ifndef _SDL_windowshaptic_c_h
   24.27 +#define _SDL_windowshaptic_c_h
   24.28 +
   24.29 +#include "SDL_thread.h"
   24.30 +
   24.31 +#include "../../core/windows/SDL_directx.h"
   24.32 +#include "../../core/windows/SDL_xinput.h"
   24.33 +
   24.34 +/*
   24.35 + * Haptic system hardware data.
   24.36 + */
   24.37 +struct haptic_hwdata
   24.38 +{
   24.39 +#if SDL_HAPTIC_DINPUT
   24.40 +    LPDIRECTINPUTDEVICE8 device;
   24.41 +#endif
   24.42 +    DWORD axes[3];              /* Axes to use. */
   24.43 +    SDL_bool is_joystick;       /* Device is loaded as joystick. */
   24.44 +    Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
   24.45 +    Uint8 userid; /* XInput userid index for this joystick */
   24.46 +    SDL_Thread *thread;
   24.47 +    SDL_mutex *mutex;
   24.48 +    volatile Uint32 stopTicks;
   24.49 +    volatile int stopThread;
   24.50 +};
   24.51 +
   24.52 +
   24.53 +/*
   24.54 + * Haptic system effect data.
   24.55 + */
   24.56 +struct haptic_hweffect
   24.57 +{
   24.58 +#if SDL_HAPTIC_DINPUT
   24.59 +    DIEFFECT effect;
   24.60 +    LPDIRECTINPUTEFFECT ref;
   24.61 +#endif
   24.62 +#if SDL_HAPTIC_XINPUT
   24.63 +    XINPUT_VIBRATION vibration;
   24.64 +#endif
   24.65 +};
   24.66 +
   24.67 +/*
   24.68 +* List of available haptic devices.
   24.69 +*/
   24.70 +typedef struct SDL_hapticlist_item
   24.71 +{
   24.72 +    char *name;
   24.73 +    SDL_Haptic *haptic;
   24.74 +#if SDL_HAPTIC_DINPUT
   24.75 +    DIDEVICEINSTANCE instance;
   24.76 +    DIDEVCAPS capabilities;
   24.77 +#endif
   24.78 +    SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */
   24.79 +    Uint8 userid; /* XInput userid index for this joystick */
   24.80 +    struct SDL_hapticlist_item *next;
   24.81 +} SDL_hapticlist_item;
   24.82 +
   24.83 +extern SDL_hapticlist_item *SDL_hapticlist;
   24.84 +
   24.85 +extern int SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item);
   24.86 +extern int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item);
   24.87 +
   24.88 +#endif /* _SDL_windowshaptic_c_h */
   24.89 +
   24.90 +/* vi: set ts=4 sw=4 expandtab: */
   24.91 +
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/haptic/windows/SDL_xinputhaptic.c	Thu Jul 03 15:39:55 2014 -0700
    25.3 @@ -0,0 +1,491 @@
    25.4 +/*
    25.5 +  Simple DirectMedia Layer
    25.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    25.7 +
    25.8 +  This software is provided 'as-is', without any express or implied
    25.9 +  warranty.  In no event will the authors be held liable for any damages
   25.10 +  arising from the use of this software.
   25.11 +
   25.12 +  Permission is granted to anyone to use this software for any purpose,
   25.13 +  including commercial applications, and to alter it and redistribute it
   25.14 +  freely, subject to the following restrictions:
   25.15 +
   25.16 +  1. The origin of this software must not be misrepresented; you must not
   25.17 +     claim that you wrote the original software. If you use this software
   25.18 +     in a product, an acknowledgment in the product documentation would be
   25.19 +     appreciated but is not required.
   25.20 +  2. Altered source versions must be plainly marked as such, and must not be
   25.21 +     misrepresented as being the original software.
   25.22 +  3. This notice may not be removed or altered from any source distribution.
   25.23 +*/
   25.24 +#include "../../SDL_internal.h"
   25.25 +
   25.26 +#include "SDL_assert.h"
   25.27 +#include "SDL_error.h"
   25.28 +#include "SDL_haptic.h"
   25.29 +#include "SDL_hints.h"
   25.30 +#include "SDL_timer.h"
   25.31 +#include "SDL_windowshaptic_c.h"
   25.32 +#include "SDL_xinputhaptic_c.h"
   25.33 +#include "../SDL_syshaptic.h"
   25.34 +#include "../../core/windows/SDL_xinput.h"
   25.35 +#include "../../joystick/windows/SDL_windowsjoystick_c.h"
   25.36 +
   25.37 +
   25.38 +#if SDL_HAPTIC_XINPUT
   25.39 +
   25.40 +/*
   25.41 + * Internal stuff.
   25.42 + */
   25.43 +static SDL_bool loaded_xinput = SDL_FALSE;
   25.44 +
   25.45 +
   25.46 +int
   25.47 +SDL_XINPUT_HapticInit(void)
   25.48 +{
   25.49 +    const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
   25.50 +    if (!env || SDL_atoi(env)) {
   25.51 +        loaded_xinput = (WIN_LoadXInputDLL() == 0);
   25.52 +    }
   25.53 +
   25.54 +    if (loaded_xinput) {
   25.55 +        DWORD i;
   25.56 +        for (i = 0; i < XUSER_MAX_COUNT; i++) {
   25.57 +            SDL_XINPUT_MaybeAddDevice(i);
   25.58 +        }
   25.59 +    }
   25.60 +    return 0;
   25.61 +}
   25.62 +
   25.63 +int
   25.64 +SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
   25.65 +{
   25.66 +    const Uint8 userid = (Uint8)dwUserid;
   25.67 +    SDL_hapticlist_item *item;
   25.68 +    XINPUT_VIBRATION state;
   25.69 +
   25.70 +    if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
   25.71 +        return -1;
   25.72 +    }
   25.73 +
   25.74 +    /* Make sure we don't already have it */
   25.75 +    for (item = SDL_hapticlist; item; item = item->next) {
   25.76 +        if (item->bXInputHaptic && item->userid == userid) {
   25.77 +            return -1;  /* Already added */
   25.78 +        }
   25.79 +    }
   25.80 +
   25.81 +    SDL_zero(state);
   25.82 +    if (XINPUTSETSTATE(dwUserid, &state) != ERROR_SUCCESS) {
   25.83 +        return -1;  /* no force feedback on this device. */
   25.84 +    }
   25.85 +
   25.86 +    item = (SDL_hapticlist_item *)SDL_malloc(sizeof(SDL_hapticlist_item));
   25.87 +    if (item == NULL) {
   25.88 +        return SDL_OutOfMemory();
   25.89 +    }
   25.90 +
   25.91 +    SDL_zerop(item);
   25.92 +
   25.93 +    /* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */
   25.94 +    {
   25.95 +        char buf[64];
   25.96 +        SDL_snprintf(buf, sizeof(buf), "XInput Controller #%u", (unsigned int)(userid + 1));
   25.97 +        item->name = SDL_strdup(buf);
   25.98 +    }
   25.99 +
  25.100 +    if (!item->name) {
  25.101 +        SDL_free(item);
  25.102 +        return -1;
  25.103 +    }
  25.104 +
  25.105 +    /* Copy the instance over, useful for creating devices. */
  25.106 +    item->bXInputHaptic = SDL_TRUE;
  25.107 +    item->userid = userid;
  25.108 +
  25.109 +    return SDL_SYS_AddHapticDevice(item);
  25.110 +}
  25.111 +
  25.112 +int
  25.113 +SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
  25.114 +{
  25.115 +    const Uint8 userid = (Uint8)dwUserid;
  25.116 +    SDL_hapticlist_item *item;
  25.117 +    SDL_hapticlist_item *prev = NULL;
  25.118 +
  25.119 +    if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
  25.120 +        return -1;
  25.121 +    }
  25.122 +
  25.123 +    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  25.124 +        if (item->bXInputHaptic && item->userid == userid) {
  25.125 +            /* found it, remove it. */
  25.126 +            return SDL_SYS_RemoveHapticDevice(prev, item);
  25.127 +        }
  25.128 +        prev = item;
  25.129 +    }
  25.130 +    return -1;
  25.131 +}
  25.132 +
  25.133 +/* !!! FIXME: this is a hack, remove this later. */
  25.134 +/* Since XInput doesn't offer a way to vibrate for X time, we hook into
  25.135 + *  SDL_PumpEvents() to check if it's time to stop vibrating with some
  25.136 + *  frequency.
  25.137 + * In practice, this works for 99% of use cases. But in an ideal world,
  25.138 + *  we do this in a separate thread so that:
  25.139 + *    - we aren't bound to when the app chooses to pump the event queue.
  25.140 + *    - we aren't adding more polling to the event queue
  25.141 + *    - we can emulate all the haptic effects correctly (start on a delay,
  25.142 + *      mix multiple effects, etc).
  25.143 + *
  25.144 + * Mostly, this is here to get rumbling to work, and all the other features
  25.145 + *  are absent in the XInput path for now.  :(
  25.146 + */
  25.147 +static int SDLCALL
  25.148 +SDL_RunXInputHaptic(void *arg)
  25.149 +{
  25.150 +    struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
  25.151 +
  25.152 +    while (!hwdata->stopThread) {
  25.153 +        SDL_Delay(50);
  25.154 +        SDL_LockMutex(hwdata->mutex);
  25.155 +        /* If we're currently running and need to stop... */
  25.156 +        if (hwdata->stopTicks) {
  25.157 +            if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_TICKS_PASSED(SDL_GetTicks(), hwdata->stopTicks)) {
  25.158 +                XINPUT_VIBRATION vibration = { 0, 0 };
  25.159 +                hwdata->stopTicks = 0;
  25.160 +                XINPUTSETSTATE(hwdata->userid, &vibration);
  25.161 +            }
  25.162 +        }
  25.163 +        SDL_UnlockMutex(hwdata->mutex);
  25.164 +    }
  25.165 +
  25.166 +    return 0;
  25.167 +}
  25.168 +
  25.169 +static int
  25.170 +SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid)
  25.171 +{
  25.172 +    char threadName[32];
  25.173 +    XINPUT_VIBRATION vibration = { 0, 0 };  /* stop any current vibration */
  25.174 +    XINPUTSETSTATE(userid, &vibration);
  25.175 +
  25.176 +    haptic->supported = SDL_HAPTIC_LEFTRIGHT;
  25.177 +
  25.178 +    haptic->neffects = 1;
  25.179 +    haptic->nplaying = 1;
  25.180 +
  25.181 +    /* Prepare effects memory. */
  25.182 +    haptic->effects = (struct haptic_effect *)
  25.183 +        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
  25.184 +    if (haptic->effects == NULL) {
  25.185 +        return SDL_OutOfMemory();
  25.186 +    }
  25.187 +    /* Clear the memory */
  25.188 +    SDL_memset(haptic->effects, 0,
  25.189 +        sizeof(struct haptic_effect) * haptic->neffects);
  25.190 +
  25.191 +    haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata));
  25.192 +    if (haptic->hwdata == NULL) {
  25.193 +        SDL_free(haptic->effects);
  25.194 +        haptic->effects = NULL;
  25.195 +        return SDL_OutOfMemory();
  25.196 +    }
  25.197 +    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
  25.198 +
  25.199 +    haptic->hwdata->bXInputHaptic = 1;
  25.200 +    haptic->hwdata->userid = userid;
  25.201 +
  25.202 +    haptic->hwdata->mutex = SDL_CreateMutex();
  25.203 +    if (haptic->hwdata->mutex == NULL) {
  25.204 +        SDL_free(haptic->effects);
  25.205 +        SDL_free(haptic->hwdata);
  25.206 +        haptic->effects = NULL;
  25.207 +        return SDL_SetError("Couldn't create XInput haptic mutex");
  25.208 +    }
  25.209 +
  25.210 +    SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid);
  25.211 +
  25.212 +#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
  25.213 +#undef SDL_CreateThread
  25.214 +#if SDL_DYNAMIC_API
  25.215 +    haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
  25.216 +#else
  25.217 +    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
  25.218 +#endif
  25.219 +#else
  25.220 +    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
  25.221 +#endif
  25.222 +    if (haptic->hwdata->thread == NULL) {
  25.223 +        SDL_DestroyMutex(haptic->hwdata->mutex);
  25.224 +        SDL_free(haptic->effects);
  25.225 +        SDL_free(haptic->hwdata);
  25.226 +        haptic->effects = NULL;
  25.227 +        return SDL_SetError("Couldn't create XInput haptic thread");
  25.228 +    }
  25.229 +
  25.230 +    return 0;
  25.231 +}
  25.232 +
  25.233 +int
  25.234 +SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
  25.235 +{
  25.236 +    return SDL_XINPUT_HapticOpenFromUserIndex(haptic, item->userid);
  25.237 +}
  25.238 +
  25.239 +int
  25.240 +SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
  25.241 +{
  25.242 +    return (haptic->hwdata->userid == joystick->hwdata->userid);
  25.243 +}
  25.244 +
  25.245 +int
  25.246 +SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
  25.247 +{
  25.248 +    SDL_hapticlist_item *item;
  25.249 +    int index = 0;
  25.250 +
  25.251 +    /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
  25.252 +    for (item = SDL_hapticlist; item != NULL; item = item->next) {
  25.253 +        if (item->bXInputHaptic && item->userid == joystick->hwdata->userid) {
  25.254 +            haptic->index = index;
  25.255 +            return SDL_XINPUT_HapticOpenFromUserIndex(haptic, joystick->hwdata->userid);
  25.256 +        }
  25.257 +        ++index;
  25.258 +    }
  25.259 +
  25.260 +    SDL_SetError("Couldn't find joystick in haptic device list");
  25.261 +    return -1;
  25.262 +}
  25.263 +
  25.264 +void
  25.265 +SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
  25.266 +{
  25.267 +    haptic->hwdata->stopThread = 1;
  25.268 +    SDL_WaitThread(haptic->hwdata->thread, NULL);
  25.269 +    SDL_DestroyMutex(haptic->hwdata->mutex);
  25.270 +}
  25.271 +
  25.272 +void
  25.273 +SDL_XINPUT_HapticQuit(void)
  25.274 +{
  25.275 +    if (loaded_xinput) {
  25.276 +        WIN_UnloadXInputDLL();
  25.277 +        loaded_xinput = SDL_FALSE;
  25.278 +    }
  25.279 +}
  25.280 +
  25.281 +int
  25.282 +SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
  25.283 +{
  25.284 +    SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
  25.285 +    return SDL_XINPUT_HapticUpdateEffect(haptic, effect, base);
  25.286 +}
  25.287 +
  25.288 +int
  25.289 +SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
  25.290 +{
  25.291 +    XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
  25.292 +    SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
  25.293 +    vib->wLeftMotorSpeed = data->leftright.large_magnitude;
  25.294 +    vib->wRightMotorSpeed = data->leftright.small_magnitude;
  25.295 +    SDL_LockMutex(haptic->hwdata->mutex);
  25.296 +    if (haptic->hwdata->stopTicks) {  /* running right now? Update it. */
  25.297 +        XINPUTSETSTATE(haptic->hwdata->userid, vib);
  25.298 +    }
  25.299 +    SDL_UnlockMutex(haptic->hwdata->mutex);
  25.300 +    return 0;
  25.301 +}
  25.302 +
  25.303 +int
  25.304 +SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
  25.305 +{
  25.306 +    XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
  25.307 +    SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
  25.308 +    SDL_LockMutex(haptic->hwdata->mutex);
  25.309 +    if (effect->effect.leftright.length == SDL_HAPTIC_INFINITY || iterations == SDL_HAPTIC_INFINITY) {
  25.310 +        haptic->hwdata->stopTicks = SDL_HAPTIC_INFINITY;
  25.311 +    } else if ((!effect->effect.leftright.length) || (!iterations)) {
  25.312 +        /* do nothing. Effect runs for zero milliseconds. */
  25.313 +    } else {
  25.314 +        haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
  25.315 +        if ((haptic->hwdata->stopTicks == SDL_HAPTIC_INFINITY) || (haptic->hwdata->stopTicks == 0)) {
  25.316 +            haptic->hwdata->stopTicks = 1;  /* fix edge cases. */
  25.317 +        }
  25.318 +    }
  25.319 +    SDL_UnlockMutex(haptic->hwdata->mutex);
  25.320 +    return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
  25.321 +}
  25.322 +
  25.323 +int
  25.324 +SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.325 +{
  25.326 +    XINPUT_VIBRATION vibration = { 0, 0 };
  25.327 +    SDL_LockMutex(haptic->hwdata->mutex);
  25.328 +    haptic->hwdata->stopTicks = 0;
  25.329 +    SDL_UnlockMutex(haptic->hwdata->mutex);
  25.330 +    return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
  25.331 +}
  25.332 +
  25.333 +void
  25.334 +SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.335 +{
  25.336 +    SDL_XINPUT_HapticStopEffect(haptic, effect);
  25.337 +}
  25.338 +
  25.339 +int
  25.340 +SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.341 +{
  25.342 +    return SDL_Unsupported();
  25.343 +}
  25.344 +
  25.345 +int
  25.346 +SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
  25.347 +{
  25.348 +    return SDL_Unsupported();
  25.349 +}
  25.350 +
  25.351 +int
  25.352 +SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
  25.353 +{
  25.354 +    return SDL_Unsupported();
  25.355 +}
  25.356 +
  25.357 +int
  25.358 +SDL_XINPUT_HapticPause(SDL_Haptic * haptic)
  25.359 +{
  25.360 +    return SDL_Unsupported();
  25.361 +}
  25.362 +
  25.363 +int
  25.364 +SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic)
  25.365 +{
  25.366 +    return SDL_Unsupported();
  25.367 +}
  25.368 +
  25.369 +int
  25.370 +SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic)
  25.371 +{
  25.372 +    XINPUT_VIBRATION vibration = { 0, 0 };
  25.373 +    SDL_LockMutex(haptic->hwdata->mutex);
  25.374 +    haptic->hwdata->stopTicks = 0;
  25.375 +    SDL_UnlockMutex(haptic->hwdata->mutex);
  25.376 +    return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
  25.377 +}
  25.378 +
  25.379 +#else /* !SDL_HAPTIC_XINPUT */
  25.380 +
  25.381 +
  25.382 +int
  25.383 +SDL_XINPUT_HapticInit(void)
  25.384 +{
  25.385 +    return 0;
  25.386 +}
  25.387 +
  25.388 +int
  25.389 +SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
  25.390 +{
  25.391 +    return SDL_Unsupported();
  25.392 +}
  25.393 +
  25.394 +int
  25.395 +SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
  25.396 +{
  25.397 +    return SDL_Unsupported();
  25.398 +}
  25.399 +
  25.400 +int
  25.401 +SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
  25.402 +{
  25.403 +    return SDL_Unsupported();
  25.404 +}
  25.405 +
  25.406 +int
  25.407 +SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
  25.408 +{
  25.409 +    return SDL_Unsupported();
  25.410 +}
  25.411 +
  25.412 +int
  25.413 +SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
  25.414 +{
  25.415 +    return SDL_Unsupported();
  25.416 +}
  25.417 +
  25.418 +void
  25.419 +SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
  25.420 +{
  25.421 +}
  25.422 +
  25.423 +void
  25.424 +SDL_XINPUT_HapticQuit(void)
  25.425 +{
  25.426 +}
  25.427 +
  25.428 +int
  25.429 +SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
  25.430 +{
  25.431 +    return SDL_Unsupported();
  25.432 +}
  25.433 +
  25.434 +int
  25.435 +SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
  25.436 +{
  25.437 +    return SDL_Unsupported();
  25.438 +}
  25.439 +
  25.440 +int
  25.441 +SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
  25.442 +{
  25.443 +    return SDL_Unsupported();
  25.444 +}
  25.445 +
  25.446 +int
  25.447 +SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.448 +{
  25.449 +    return SDL_Unsupported();
  25.450 +}
  25.451 +
  25.452 +void
  25.453 +SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.454 +{
  25.455 +}
  25.456 +
  25.457 +int
  25.458 +SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
  25.459 +{
  25.460 +    return SDL_Unsupported();
  25.461 +}
  25.462 +
  25.463 +int
  25.464 +SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
  25.465 +{
  25.466 +    return SDL_Unsupported();
  25.467 +}
  25.468 +
  25.469 +int
  25.470 +SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
  25.471 +{
  25.472 +    return SDL_Unsupported();
  25.473 +}
  25.474 +
  25.475 +int
  25.476 +SDL_XINPUT_HapticPause(SDL_Haptic * haptic)
  25.477 +{
  25.478 +    return SDL_Unsupported();
  25.479 +}
  25.480 +
  25.481 +int
  25.482 +SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic)
  25.483 +{
  25.484 +    return SDL_Unsupported();
  25.485 +}
  25.486 +
  25.487 +int
  25.488 +SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic)
  25.489 +{
  25.490 +    return SDL_Unsupported();
  25.491 +}
  25.492 +
  25.493 +#endif /* SDL_HAPTIC_XINPUT */
  25.494 +/* vi: set ts=4 sw=4 expandtab: */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/haptic/windows/SDL_xinputhaptic_c.h	Thu Jul 03 15:39:55 2014 -0700
    26.3 @@ -0,0 +1,47 @@
    26.4 +/*
    26.5 +  Simple DirectMedia Layer
    26.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    26.7 +
    26.8 +  This software is provided 'as-is', without any express or implied
    26.9 +  warranty.  In no event will the authors be held liable for any damages
   26.10 +  arising from the use of this software.
   26.11 +
   26.12 +  Permission is granted to anyone to use this software for any purpose,
   26.13 +  including commercial applications, and to alter it and redistribute it
   26.14 +  freely, subject to the following restrictions:
   26.15 +
   26.16 +  1. The origin of this software must not be misrepresented; you must not
   26.17 +     claim that you wrote the original software. If you use this software
   26.18 +     in a product, an acknowledgment in the product documentation would be
   26.19 +     appreciated but is not required.
   26.20 +  2. Altered source versions must be plainly marked as such, and must not be
   26.21 +     misrepresented as being the original software.
   26.22 +  3. This notice may not be removed or altered from any source distribution.
   26.23 +*/
   26.24 +#include "../../SDL_internal.h"
   26.25 +
   26.26 +#include "SDL_haptic.h"
   26.27 +#include "SDL_windowshaptic_c.h"
   26.28 +
   26.29 +
   26.30 +extern int SDL_XINPUT_HapticInit(void);
   26.31 +extern int SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid);
   26.32 +extern int SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid);
   26.33 +extern int SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
   26.34 +extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
   26.35 +extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
   26.36 +extern void SDL_XINPUT_HapticClose(SDL_Haptic * haptic);
   26.37 +extern void SDL_XINPUT_HapticQuit(void);
   26.38 +extern int SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base);
   26.39 +extern int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data);
   26.40 +extern int SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations);
   26.41 +extern int SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
   26.42 +extern void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
   26.43 +extern int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect);
   26.44 +extern int SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain);
   26.45 +extern int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
   26.46 +extern int SDL_XINPUT_HapticPause(SDL_Haptic * haptic);
   26.47 +extern int SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic);
   26.48 +extern int SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic);
   26.49 +
   26.50 +/* vi: set ts=4 sw=4 expandtab: */
    27.1 --- a/src/joystick/SDL_gamecontroller.c	Thu Jul 03 17:36:08 2014 -0300
    27.2 +++ b/src/joystick/SDL_gamecontroller.c	Thu Jul 03 15:39:55 2014 -0700
    27.3 @@ -88,9 +88,7 @@
    27.4  } ControllerMapping_t;
    27.5  
    27.6  static ControllerMapping_t *s_pSupportedControllers = NULL;
    27.7 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
    27.8  static ControllerMapping_t *s_pXInputMapping = NULL;
    27.9 -#endif
   27.10  
   27.11  /* The SDL game controller structure */
   27.12  struct _SDL_GameController
   27.13 @@ -260,12 +258,10 @@
   27.14   */
   27.15  ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
   27.16  {
   27.17 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
   27.18      if (SDL_SYS_IsXInputGamepad_DeviceIndex(device_index) && s_pXInputMapping) {
   27.19          return s_pXInputMapping;
   27.20      }
   27.21      else
   27.22 -#endif
   27.23      {
   27.24          SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
   27.25          return SDL_PrivateGetControllerMappingForGUID(&jGUID);
   27.26 @@ -669,19 +665,15 @@
   27.27      char *pchMapping;
   27.28      SDL_JoystickGUID jGUID;
   27.29      ControllerMapping_t *pControllerMapping;
   27.30 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
   27.31      SDL_bool is_xinput_mapping = SDL_FALSE;
   27.32 -#endif
   27.33  
   27.34      pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
   27.35      if (!pchGUID) {
   27.36          return SDL_SetError("Couldn't parse GUID from %s", mappingString);
   27.37      }
   27.38 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
   27.39      if (!SDL_strcasecmp(pchGUID, "xinput")) {
   27.40          is_xinput_mapping = SDL_TRUE;
   27.41      }
   27.42 -#endif
   27.43      jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
   27.44      SDL_free(pchGUID);
   27.45  
   27.46 @@ -714,11 +706,9 @@
   27.47              SDL_free(pchMapping);
   27.48              return SDL_OutOfMemory();
   27.49          }
   27.50 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
   27.51          if (is_xinput_mapping) {
   27.52              s_pXInputMapping = pControllerMapping;
   27.53          }
   27.54 -#endif
   27.55          pControllerMapping->guid = jGUID;
   27.56          pControllerMapping->name = pchName;
   27.57          pControllerMapping->mapping = pchMapping;
    28.1 --- a/src/joystick/SDL_gamecontrollerdb.h	Thu Jul 03 17:36:08 2014 -0300
    28.2 +++ b/src/joystick/SDL_gamecontrollerdb.h	Thu Jul 03 15:39:55 2014 -0700
    28.3 @@ -31,7 +31,10 @@
    28.4   */
    28.5  static const char *s_ControllerMappings [] =
    28.6  {
    28.7 -#ifdef SDL_JOYSTICK_DINPUT
    28.8 +#if SDL_JOYSTICK_XINPUT
    28.9 +    "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.10 +#endif
   28.11 +#if SDL_JOYSTICK_DINPUT
   28.12      "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
   28.13      "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
   28.14      "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
   28.15 @@ -41,10 +44,8 @@
   28.16      "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
   28.17      "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,",
   28.18      "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
   28.19 -    "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.20 -#elif defined(SDL_JOYSTICK_XINPUT)
   28.21 -	"xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.22 -#elif defined(__MACOSX__)
   28.23 +#endif
   28.24 +#if defined(__MACOSX__)
   28.25      "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
   28.26      "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
   28.27      "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
   28.28 @@ -53,7 +54,8 @@
   28.29      "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
   28.30      "4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
   28.31      "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
   28.32 -#elif defined(__LINUX__)
   28.33 +#endif
   28.34 +#if defined(__LINUX__)
   28.35      "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
   28.36      "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
   28.37      "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
   28.38 @@ -70,7 +72,8 @@
   28.39      "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.40      "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.41      "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   28.42 -#elif defined(__ANDROID__)
   28.43 +#endif
   28.44 +#if defined(__ANDROID__)
   28.45      "4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
   28.46  #endif
   28.47      NULL
    29.1 --- a/src/joystick/SDL_sysjoystick.h	Thu Jul 03 17:36:08 2014 -0300
    29.2 +++ b/src/joystick/SDL_sysjoystick.h	Thu Jul 03 15:39:55 2014 -0700
    29.3 @@ -20,6 +20,9 @@
    29.4  */
    29.5  #include "../SDL_internal.h"
    29.6  
    29.7 +#ifndef _SDL_sysjoystick_h
    29.8 +#define _SDL_sysjoystick_h
    29.9 +
   29.10  /* This is the system specific header for the SDL joystick API */
   29.11  
   29.12  #include "SDL_joystick.h"
   29.13 @@ -105,9 +108,9 @@
   29.14  /* Function to return the stable GUID for a opened joystick */
   29.15  extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick);
   29.16  
   29.17 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
   29.18  /* Function returns SDL_TRUE if this device is an XInput gamepad */
   29.19 -extern SDL_bool SDL_SYS_IsXInputGamepad_DeviceIndex( int device_index );
   29.20 -#endif
   29.21 +extern SDL_bool SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index);
   29.22 +
   29.23 +#endif /* _SDL_sysjoystick_h */
   29.24  
   29.25  /* vi: set ts=4 sw=4 expandtab: */
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/joystick/windows/SDL_dinputjoystick.c	Thu Jul 03 15:39:55 2014 -0700
    30.3 @@ -0,0 +1,900 @@
    30.4 +/*
    30.5 +  Simple DirectMedia Layer
    30.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    30.7 +
    30.8 +  This software is provided 'as-is', without any express or implied
    30.9 +  warranty.  In no event will the authors be held liable for any damages
   30.10 +  arising from the use of this software.
   30.11 +
   30.12 +  Permission is granted to anyone to use this software for any purpose,
   30.13 +  including commercial applications, and to alter it and redistribute it
   30.14 +  freely, subject to the following restrictions:
   30.15 +
   30.16 +  1. The origin of this software must not be misrepresented; you must not
   30.17 +     claim that you wrote the original software. If you use this software
   30.18 +     in a product, an acknowledgment in the product documentation would be
   30.19 +     appreciated but is not required.
   30.20 +  2. Altered source versions must be plainly marked as such, and must not be
   30.21 +     misrepresented as being the original software.
   30.22 +  3. This notice may not be removed or altered from any source distribution.
   30.23 +*/
   30.24 +#include "../../SDL_internal.h"
   30.25 +
   30.26 +#include "../SDL_sysjoystick.h"
   30.27 +#include "SDL_windowsjoystick_c.h"
   30.28 +#include "SDL_dinputjoystick_c.h"
   30.29 +#include "SDL_xinputjoystick_c.h"
   30.30 +
   30.31 +
   30.32 +#if SDL_JOYSTICK_DINPUT
   30.33 +
   30.34 +#ifndef DIDFT_OPTIONAL
   30.35 +#define DIDFT_OPTIONAL      0x80000000
   30.36 +#endif
   30.37 +
   30.38 +#define INPUT_QSIZE 32      /* Buffer up to 32 input messages */
   30.39 +#define AXIS_MIN    -32768  /* minimum value for axis coordinate */
   30.40 +#define AXIS_MAX    32767   /* maximum value for axis coordinate */
   30.41 +#define JOY_AXIS_THRESHOLD  (((AXIS_MAX)-(AXIS_MIN))/100)   /* 1% motion */
   30.42 +
   30.43 +/* external variables referenced. */
   30.44 +extern HWND SDL_HelperWindow;
   30.45 +
   30.46 +/* local variables */
   30.47 +static SDL_bool coinitialized = SDL_FALSE;
   30.48 +static LPDIRECTINPUT8 dinput = NULL;
   30.49 +static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
   30.50 +static UINT SDL_RawDevListCount = 0;
   30.51 +
   30.52 +/* Taken from Wine - Thanks! */
   30.53 +static DIOBJECTDATAFORMAT dfDIJoystick2[] = {
   30.54 +        { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.55 +        { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.56 +        { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.57 +        { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.58 +        { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.59 +        { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.60 +        { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.61 +        { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
   30.62 +        { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
   30.63 +        { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
   30.64 +        { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
   30.65 +        { &GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
   30.66 +        { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.67 +        { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.68 +        { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.69 +        { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.70 +        { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.71 +        { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.72 +        { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.73 +        { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.74 +        { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.75 +        { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.76 +        { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.77 +        { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.78 +        { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.79 +        { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.80 +        { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.81 +        { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.82 +        { NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.83 +        { NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.84 +        { NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.85 +        { NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.86 +        { NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.87 +        { NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.88 +        { NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.89 +        { NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.90 +        { NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.91 +        { NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.92 +        { NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.93 +        { NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.94 +        { NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.95 +        { NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.96 +        { NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.97 +        { NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.98 +        { NULL, DIJOFS_BUTTON(32), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
   30.99 +        { NULL, DIJOFS_BUTTON(33), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.100 +        { NULL, DIJOFS_BUTTON(34), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.101 +        { NULL, DIJOFS_BUTTON(35), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.102 +        { NULL, DIJOFS_BUTTON(36), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.103 +        { NULL, DIJOFS_BUTTON(37), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.104 +        { NULL, DIJOFS_BUTTON(38), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.105 +        { NULL, DIJOFS_BUTTON(39), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.106 +        { NULL, DIJOFS_BUTTON(40), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.107 +        { NULL, DIJOFS_BUTTON(41), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.108 +        { NULL, DIJOFS_BUTTON(42), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.109 +        { NULL, DIJOFS_BUTTON(43), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.110 +        { NULL, DIJOFS_BUTTON(44), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.111 +        { NULL, DIJOFS_BUTTON(45), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.112 +        { NULL, DIJOFS_BUTTON(46), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.113 +        { NULL, DIJOFS_BUTTON(47), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.114 +        { NULL, DIJOFS_BUTTON(48), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.115 +        { NULL, DIJOFS_BUTTON(49), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.116 +        { NULL, DIJOFS_BUTTON(50), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.117 +        { NULL, DIJOFS_BUTTON(51), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.118 +        { NULL, DIJOFS_BUTTON(52), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.119 +        { NULL, DIJOFS_BUTTON(53), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.120 +        { NULL, DIJOFS_BUTTON(54), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.121 +        { NULL, DIJOFS_BUTTON(55), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.122 +        { NULL, DIJOFS_BUTTON(56), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.123 +        { NULL, DIJOFS_BUTTON(57), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.124 +        { NULL, DIJOFS_BUTTON(58), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.125 +        { NULL, DIJOFS_BUTTON(59), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.126 +        { NULL, DIJOFS_BUTTON(60), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.127 +        { NULL, DIJOFS_BUTTON(61), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.128 +        { NULL, DIJOFS_BUTTON(62), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.129 +        { NULL, DIJOFS_BUTTON(63), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.130 +        { NULL, DIJOFS_BUTTON(64), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.131 +        { NULL, DIJOFS_BUTTON(65), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.132 +        { NULL, DIJOFS_BUTTON(66), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.133 +        { NULL, DIJOFS_BUTTON(67), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.134 +        { NULL, DIJOFS_BUTTON(68), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.135 +        { NULL, DIJOFS_BUTTON(69), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.136 +        { NULL, DIJOFS_BUTTON(70), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.137 +        { NULL, DIJOFS_BUTTON(71), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.138 +        { NULL, DIJOFS_BUTTON(72), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.139 +        { NULL, DIJOFS_BUTTON(73), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.140 +        { NULL, DIJOFS_BUTTON(74), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.141 +        { NULL, DIJOFS_BUTTON(75), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.142 +        { NULL, DIJOFS_BUTTON(76), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.143 +        { NULL, DIJOFS_BUTTON(77), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.144 +        { NULL, DIJOFS_BUTTON(78), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.145 +        { NULL, DIJOFS_BUTTON(79), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.146 +        { NULL, DIJOFS_BUTTON(80), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.147 +        { NULL, DIJOFS_BUTTON(81), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.148 +        { NULL, DIJOFS_BUTTON(82), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.149 +        { NULL, DIJOFS_BUTTON(83), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.150 +        { NULL, DIJOFS_BUTTON(84), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.151 +        { NULL, DIJOFS_BUTTON(85), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.152 +        { NULL, DIJOFS_BUTTON(86), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.153 +        { NULL, DIJOFS_BUTTON(87), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.154 +        { NULL, DIJOFS_BUTTON(88), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.155 +        { NULL, DIJOFS_BUTTON(89), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.156 +        { NULL, DIJOFS_BUTTON(90), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.157 +        { NULL, DIJOFS_BUTTON(91), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.158 +        { NULL, DIJOFS_BUTTON(92), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.159 +        { NULL, DIJOFS_BUTTON(93), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.160 +        { NULL, DIJOFS_BUTTON(94), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.161 +        { NULL, DIJOFS_BUTTON(95), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.162 +        { NULL, DIJOFS_BUTTON(96), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.163 +        { NULL, DIJOFS_BUTTON(97), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.164 +        { NULL, DIJOFS_BUTTON(98), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.165 +        { NULL, DIJOFS_BUTTON(99), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.166 +        { NULL, DIJOFS_BUTTON(100), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.167 +        { NULL, DIJOFS_BUTTON(101), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.168 +        { NULL, DIJOFS_BUTTON(102), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.169 +        { NULL, DIJOFS_BUTTON(103), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.170 +        { NULL, DIJOFS_BUTTON(104), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.171 +        { NULL, DIJOFS_BUTTON(105), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.172 +        { NULL, DIJOFS_BUTTON(106), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.173 +        { NULL, DIJOFS_BUTTON(107), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.174 +        { NULL, DIJOFS_BUTTON(108), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.175 +        { NULL, DIJOFS_BUTTON(109), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.176 +        { NULL, DIJOFS_BUTTON(110), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.177 +        { NULL, DIJOFS_BUTTON(111), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.178 +        { NULL, DIJOFS_BUTTON(112), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.179 +        { NULL, DIJOFS_BUTTON(113), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.180 +        { NULL, DIJOFS_BUTTON(114), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.181 +        { NULL, DIJOFS_BUTTON(115), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.182 +        { NULL, DIJOFS_BUTTON(116), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.183 +        { NULL, DIJOFS_BUTTON(117), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.184 +        { NULL, DIJOFS_BUTTON(118), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.185 +        { NULL, DIJOFS_BUTTON(119), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.186 +        { NULL, DIJOFS_BUTTON(120), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.187 +        { NULL, DIJOFS_BUTTON(121), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.188 +        { NULL, DIJOFS_BUTTON(122), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.189 +        { NULL, DIJOFS_BUTTON(123), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.190 +        { NULL, DIJOFS_BUTTON(124), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.191 +        { NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.192 +        { NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.193 +        { NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
  30.194 +        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.195 +        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.196 +        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.197 +        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.198 +        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.199 +        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.200 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.201 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.202 +        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.203 +        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.204 +        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.205 +        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.206 +        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.207 +        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.208 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.209 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.210 +        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.211 +        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.212 +        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.213 +        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.214 +        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.215 +        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.216 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.217 +        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
  30.218 +};
  30.219 +
  30.220 +const DIDATAFORMAT c_dfDIJoystick2 = {
  30.221 +    sizeof(DIDATAFORMAT),
  30.222 +    sizeof(DIOBJECTDATAFORMAT),
  30.223 +    DIDF_ABSAXIS,
  30.224 +    sizeof(DIJOYSTATE2),
  30.225 +    SDL_arraysize(dfDIJoystick2),
  30.226 +    dfDIJoystick2
  30.227 +};
  30.228 +
  30.229 +/* Convert a DirectInput return code to a text message */
  30.230 +static int
  30.231 +SetDIerror(const char *function, HRESULT code)
  30.232 +{
  30.233 +    /*
  30.234 +    return SDL_SetError("%s() [%s]: %s", function,
  30.235 +    DXGetErrorString9A(code), DXGetErrorDescription9A(code));
  30.236 +    */
  30.237 +    return SDL_SetError("%s() DirectX error %d", function, code);
  30.238 +}
  30.239 +
  30.240 +static SDL_bool
  30.241 +SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
  30.242 +{
  30.243 +    static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
  30.244 +    static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
  30.245 +    static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
  30.246 +
  30.247 +    static const GUID *s_XInputProductGUID[] = {
  30.248 +        &IID_ValveStreamingGamepad,
  30.249 +        &IID_X360WiredGamepad,   /* Microsoft's wired X360 controller for Windows. */
  30.250 +        &IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */
  30.251 +    };
  30.252 +
  30.253 +    size_t iDevice;
  30.254 +    UINT i;
  30.255 +
  30.256 +    if (!SDL_XINPUT_Enabled()) {
  30.257 +        return SDL_FALSE;
  30.258 +    }
  30.259 +
  30.260 +    /* Check for well known XInput device GUIDs */
  30.261 +    /* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
  30.262 +    for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
  30.263 +        if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
  30.264 +            return SDL_TRUE;
  30.265 +        }
  30.266 +    }
  30.267 +
  30.268 +    /* Go through RAWINPUT (WinXP and later) to find HID devices. */
  30.269 +    /* Cache this if we end up using it. */
  30.270 +    if (SDL_RawDevList == NULL) {
  30.271 +        if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
  30.272 +            return SDL_FALSE;  /* oh well. */
  30.273 +        }
  30.274 +
  30.275 +        SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
  30.276 +        if (SDL_RawDevList == NULL) {
  30.277 +            SDL_OutOfMemory();
  30.278 +            return SDL_FALSE;
  30.279 +        }
  30.280 +
  30.281 +        if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) {
  30.282 +            SDL_free(SDL_RawDevList);
  30.283 +            SDL_RawDevList = NULL;
  30.284 +            return SDL_FALSE;  /* oh well. */
  30.285 +        }
  30.286 +    }
  30.287 +
  30.288 +    for (i = 0; i < SDL_RawDevListCount; i++) {
  30.289 +        RID_DEVICE_INFO rdi;
  30.290 +        char devName[128];
  30.291 +        UINT rdiSize = sizeof(rdi);
  30.292 +        UINT nameSize = SDL_arraysize(devName);
  30.293 +
  30.294 +        rdi.cbSize = sizeof(rdi);
  30.295 +        if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
  30.296 +            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
  30.297 +            (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
  30.298 +            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
  30.299 +            (SDL_strstr(devName, "IG_") != NULL)) {
  30.300 +            return SDL_TRUE;
  30.301 +        }
  30.302 +    }
  30.303 +
  30.304 +    return SDL_FALSE;
  30.305 +}
  30.306 +
  30.307 +int
  30.308 +SDL_DINPUT_JoystickInit(void)
  30.309 +{
  30.310 +    HRESULT result;
  30.311 +    HINSTANCE instance;
  30.312 +
  30.313 +    result = WIN_CoInitialize();
  30.314 +    if (FAILED(result)) {
  30.315 +        return SetDIerror("CoInitialize", result);
  30.316 +    }
  30.317 +
  30.318 +    coinitialized = SDL_TRUE;
  30.319 +
  30.320 +    result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
  30.321 +        &IID_IDirectInput8, (LPVOID)&dinput);
  30.322 +
  30.323 +    if (FAILED(result)) {
  30.324 +        return SetDIerror("CoCreateInstance", result);
  30.325 +    }
  30.326 +
  30.327 +    /* Because we used CoCreateInstance, we need to Initialize it, first. */
  30.328 +    instance = GetModuleHandle(NULL);
  30.329 +    if (instance == NULL) {
  30.330 +        return SDL_SetError("GetModuleHandle() failed with error code %d.", GetLastError());
  30.331 +    }
  30.332 +    result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
  30.333 +
  30.334 +    if (FAILED(result)) {
  30.335 +        return SetDIerror("IDirectInput::Initialize", result);
  30.336 +    }
  30.337 +    return 0;
  30.338 +}
  30.339 +
  30.340 +/* helper function for direct input, gets called for each connected joystick */
  30.341 +static BOOL CALLBACK
  30.342 +EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
  30.343 +{
  30.344 +    JoyStick_DeviceData *pNewJoystick;
  30.345 +    JoyStick_DeviceData *pPrevJoystick = NULL;
  30.346 +
  30.347 +    if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
  30.348 +        return DIENUM_CONTINUE;  /* ignore XInput devices here, keep going. */
  30.349 +    }
  30.350 +
  30.351 +    pNewJoystick = *(JoyStick_DeviceData **)pContext;
  30.352 +    while (pNewJoystick) {
  30.353 +        if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) {
  30.354 +            /* if we are replacing the front of the list then update it */
  30.355 +            if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
  30.356 +                *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
  30.357 +            } else if (pPrevJoystick) {
  30.358 +                pPrevJoystick->pNext = pNewJoystick->pNext;
  30.359 +            }
  30.360 +
  30.361 +            pNewJoystick->pNext = SYS_Joystick;
  30.362 +            SYS_Joystick = pNewJoystick;
  30.363 +
  30.364 +            return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
  30.365 +        }
  30.366 +
  30.367 +        pPrevJoystick = pNewJoystick;
  30.368 +        pNewJoystick = pNewJoystick->pNext;
  30.369 +    }
  30.370 +
  30.371 +    pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
  30.372 +    if (!pNewJoystick) {
  30.373 +        return DIENUM_CONTINUE; /* better luck next time? */
  30.374 +    }
  30.375 +
  30.376 +    SDL_zerop(pNewJoystick);
  30.377 +    pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
  30.378 +    if (!pNewJoystick->joystickname) {
  30.379 +        SDL_free(pNewJoystick);
  30.380 +        return DIENUM_CONTINUE; /* better luck next time? */
  30.381 +    }
  30.382 +
  30.383 +    SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
  30.384 +        sizeof(DIDEVICEINSTANCE));
  30.385 +
  30.386 +    SDL_memcpy(&pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid));
  30.387 +    SDL_SYS_AddJoystickDevice(pNewJoystick);
  30.388 +
  30.389 +    return DIENUM_CONTINUE; /* get next device, please */
  30.390 +}
  30.391 +
  30.392 +void
  30.393 +SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
  30.394 +{
  30.395 +    IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
  30.396 +
  30.397 +    if (SDL_RawDevList) {
  30.398 +        SDL_free(SDL_RawDevList);  /* in case we used this in DirectInput detection */
  30.399 +        SDL_RawDevList = NULL;
  30.400 +    }
  30.401 +    SDL_RawDevListCount = 0;
  30.402 +}
  30.403 +
  30.404 +static BOOL CALLBACK
  30.405 +EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
  30.406 +{
  30.407 +    SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
  30.408 +    HRESULT result;
  30.409 +    input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
  30.410 +
  30.411 +    if (dev->dwType & DIDFT_BUTTON) {
  30.412 +        in->type = BUTTON;
  30.413 +        in->num = joystick->nbuttons;
  30.414 +        in->ofs = DIJOFS_BUTTON(in->num);
  30.415 +        joystick->nbuttons++;
  30.416 +    } else if (dev->dwType & DIDFT_POV) {
  30.417 +        in->type = HAT;
  30.418 +        in->num = joystick->nhats;
  30.419 +        in->ofs = DIJOFS_POV(in->num);
  30.420 +        joystick->nhats++;
  30.421 +    } else if (dev->dwType & DIDFT_AXIS) {
  30.422 +        DIPROPRANGE diprg;
  30.423 +        DIPROPDWORD dilong;
  30.424 +
  30.425 +        in->type = AXIS;
  30.426 +        in->num = joystick->naxes;
  30.427 +        if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType)))
  30.428 +            in->ofs = DIJOFS_X;
  30.429 +        else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType)))
  30.430 +            in->ofs = DIJOFS_Y;
  30.431 +        else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType)))
  30.432 +            in->ofs = DIJOFS_Z;
  30.433 +        else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType)))
  30.434 +            in->ofs = DIJOFS_RX;
  30.435 +        else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType)))
  30.436 +            in->ofs = DIJOFS_RY;
  30.437 +        else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType)))
  30.438 +            in->ofs = DIJOFS_RZ;
  30.439 +        else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) {
  30.440 +            in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders);
  30.441 +            ++joystick->hwdata->NumSliders;
  30.442 +        } else {
  30.443 +            return DIENUM_CONTINUE; /* not an axis we can grok */
  30.444 +        }
  30.445 +
  30.446 +        diprg.diph.dwSize = sizeof(diprg);
  30.447 +        diprg.diph.dwHeaderSize = sizeof(diprg.diph);
  30.448 +        diprg.diph.dwObj = dev->dwType;
  30.449 +        diprg.diph.dwHow = DIPH_BYID;
  30.450 +        diprg.lMin = AXIS_MIN;
  30.451 +        diprg.lMax = AXIS_MAX;
  30.452 +
  30.453 +        result =
  30.454 +            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
  30.455 +            DIPROP_RANGE, &diprg.diph);
  30.456 +        if (FAILED(result)) {
  30.457 +            return DIENUM_CONTINUE;     /* don't use this axis */
  30.458 +        }
  30.459 +
  30.460 +        /* Set dead zone to 0. */
  30.461 +        dilong.diph.dwSize = sizeof(dilong);
  30.462 +        dilong.diph.dwHeaderSize = sizeof(dilong.diph);
  30.463 +        dilong.diph.dwObj = dev->dwType;
  30.464 +        dilong.diph.dwHow = DIPH_BYID;
  30.465 +        dilong.dwData = 0;
  30.466 +        result =
  30.467 +            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
  30.468 +            DIPROP_DEADZONE, &dilong.diph);
  30.469 +        if (FAILED(result)) {
  30.470 +            return DIENUM_CONTINUE;     /* don't use this axis */
  30.471 +        }
  30.472 +
  30.473 +        joystick->naxes++;
  30.474 +    } else {
  30.475 +        /* not supported at this time */
  30.476 +        return DIENUM_CONTINUE;
  30.477 +    }
  30.478 +
  30.479 +    joystick->hwdata->NumInputs++;
  30.480 +
  30.481 +    if (joystick->hwdata->NumInputs == MAX_INPUTS) {
  30.482 +        return DIENUM_STOP;     /* too many */
  30.483 +    }
  30.484 +
  30.485 +    return DIENUM_CONTINUE;
  30.486 +}
  30.487 +
  30.488 +/* Sort using the data offset into the DInput struct.
  30.489 + * This gives a reasonable ordering for the inputs.
  30.490 + */
  30.491 +static int
  30.492 +SortDevFunc(const void *a, const void *b)
  30.493 +{
  30.494 +    const input_t *inputA = (const input_t*)a;
  30.495 +    const input_t *inputB = (const input_t*)b;
  30.496 +
  30.497 +    if (inputA->ofs < inputB->ofs)
  30.498 +        return -1;
  30.499 +    if (inputA->ofs > inputB->ofs)
  30.500 +        return 1;
  30.501 +    return 0;
  30.502 +}
  30.503 +
  30.504 +/* Sort the input objects and recalculate the indices for each input. */
  30.505 +static void
  30.506 +SortDevObjects(SDL_Joystick *joystick)
  30.507 +{
  30.508 +    input_t *inputs = joystick->hwdata->Inputs;
  30.509 +    int nButtons = 0;
  30.510 +    int nHats = 0;
  30.511 +    int nAxis = 0;
  30.512 +    int n;
  30.513 +
  30.514 +    SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc);
  30.515 +
  30.516 +    for (n = 0; n < joystick->hwdata->NumInputs; n++) {
  30.517 +        switch (inputs[n].type) {
  30.518 +        case BUTTON:
  30.519 +            inputs[n].num = nButtons;
  30.520 +            nButtons++;
  30.521 +            break;
  30.522 +
  30.523 +        case HAT:
  30.524 +            inputs[n].num = nHats;
  30.525 +            nHats++;
  30.526 +            break;
  30.527 +
  30.528 +        case AXIS:
  30.529 +            inputs[n].num = nAxis;
  30.530 +            nAxis++;
  30.531 +            break;
  30.532 +        }
  30.533 +    }
  30.534 +}
  30.535 +
  30.536 +int
  30.537 +SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
  30.538 +{
  30.539 +    HRESULT result;
  30.540 +    LPDIRECTINPUTDEVICE8 device;
  30.541 +    DIPROPDWORD dipdw;
  30.542 +
  30.543 +    joystick->hwdata->buffered = SDL_TRUE;
  30.544 +    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
  30.545 +
  30.546 +    SDL_zero(dipdw);
  30.547 +    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  30.548 +    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  30.549 +
  30.550 +    result =
  30.551 +        IDirectInput8_CreateDevice(dinput,
  30.552 +        &(joystickdevice->dxdevice.guidInstance), &device, NULL);
  30.553 +    if (FAILED(result)) {
  30.554 +        return SetDIerror("IDirectInput::CreateDevice", result);
  30.555 +    }
  30.556 +
  30.557 +    /* Now get the IDirectInputDevice8 interface, instead. */
  30.558 +    result = IDirectInputDevice8_QueryInterface(device,
  30.559 +        &IID_IDirectInputDevice8,
  30.560 +        (LPVOID *)& joystick->
  30.561 +        hwdata->InputDevice);
  30.562 +    /* We are done with this object.  Use the stored one from now on. */
  30.563 +    IDirectInputDevice8_Release(device);
  30.564 +
  30.565 +    if (FAILED(result)) {
  30.566 +        return SetDIerror("IDirectInputDevice8::QueryInterface", result);
  30.567 +    }
  30.568 +
  30.569 +    /* Acquire shared access. Exclusive access is required for forces,
  30.570 +    * though. */
  30.571 +    result =
  30.572 +        IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
  30.573 +        InputDevice, SDL_HelperWindow,
  30.574 +        DISCL_EXCLUSIVE |
  30.575 +        DISCL_BACKGROUND);
  30.576 +    if (FAILED(result)) {
  30.577 +        return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result);
  30.578 +    }
  30.579 +
  30.580 +    /* Use the extended data structure: DIJOYSTATE2. */
  30.581 +    result =
  30.582 +        IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
  30.583 +        &c_dfDIJoystick2);
  30.584 +    if (FAILED(result)) {
  30.585 +        return SetDIerror("IDirectInputDevice8::SetDataFormat", result);
  30.586 +    }
  30.587 +
  30.588 +    /* Get device capabilities */
  30.589 +    result =
  30.590 +        IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
  30.591 +        &joystick->hwdata->Capabilities);
  30.592 +    if (FAILED(result)) {
  30.593 +        return SetDIerror("IDirectInputDevice8::GetCapabilities", result);
  30.594 +    }
  30.595 +
  30.596 +    /* Force capable? */
  30.597 +    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
  30.598 +
  30.599 +        result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
  30.600 +        if (FAILED(result)) {
  30.601 +            return SetDIerror("IDirectInputDevice8::Acquire", result);
  30.602 +        }
  30.603 +
  30.604 +        /* reset all actuators. */
  30.605 +        result =
  30.606 +            IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
  30.607 +            InputDevice,
  30.608 +            DISFFC_RESET);
  30.609 +
  30.610 +        /* Not necessarily supported, ignore if not supported.
  30.611 +        if (FAILED(result)) {
  30.612 +        return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result);
  30.613 +        }
  30.614 +        */
  30.615 +
  30.616 +        result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
  30.617 +
  30.618 +        if (FAILED(result)) {
  30.619 +            return SetDIerror("IDirectInputDevice8::Unacquire", result);
  30.620 +        }
  30.621 +
  30.622 +        /* Turn on auto-centering for a ForceFeedback device (until told
  30.623 +        * otherwise). */
  30.624 +        dipdw.diph.dwObj = 0;
  30.625 +        dipdw.diph.dwHow = DIPH_DEVICE;
  30.626 +        dipdw.dwData = DIPROPAUTOCENTER_ON;
  30.627 +
  30.628 +        result =
  30.629 +            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
  30.630 +            DIPROP_AUTOCENTER, &dipdw.diph);
  30.631 +
  30.632 +        /* Not necessarily supported, ignore if not supported.
  30.633 +        if (FAILED(result)) {
  30.634 +        return SetDIerror("IDirectInputDevice8::SetProperty", result);
  30.635 +        }
  30.636 +        */
  30.637 +    }
  30.638 +
  30.639 +    /* What buttons and axes does it have? */
  30.640 +    IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
  30.641 +        EnumDevObjectsCallback, joystick,
  30.642 +        DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
  30.643 +
  30.644 +    /* Reorder the input objects. Some devices do not report the X axis as
  30.645 +    * the first axis, for example. */
  30.646 +    SortDevObjects(joystick);
  30.647 +
  30.648 +    dipdw.diph.dwObj = 0;
  30.649 +    dipdw.diph.dwHow = DIPH_DEVICE;
  30.650 +    dipdw.dwData = INPUT_QSIZE;
  30.651 +
  30.652 +    /* Set the buffer size */
  30.653 +    result =
  30.654 +        IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
  30.655 +        DIPROP_BUFFERSIZE, &dipdw.diph);
  30.656 +
  30.657 +    if (result == DI_POLLEDDEVICE) {
  30.658 +        /* This device doesn't support buffering, so we're forced
  30.659 +         * to use less reliable polling. */
  30.660 +        joystick->hwdata->buffered = SDL_FALSE;
  30.661 +    } else if (FAILED(result)) {
  30.662 +        return SetDIerror("IDirectInputDevice8::SetProperty", result);
  30.663 +    }
  30.664 +    return 0;
  30.665 +}
  30.666 +
  30.667 +static Uint8
  30.668 +TranslatePOV(DWORD value)
  30.669 +{
  30.670 +    const int HAT_VALS[] = {
  30.671 +        SDL_HAT_UP,
  30.672 +        SDL_HAT_UP | SDL_HAT_RIGHT,
  30.673 +        SDL_HAT_RIGHT,
  30.674 +        SDL_HAT_DOWN | SDL_HAT_RIGHT,
  30.675 +        SDL_HAT_DOWN,
  30.676 +        SDL_HAT_DOWN | SDL_HAT_LEFT,
  30.677 +        SDL_HAT_LEFT,
  30.678 +        SDL_HAT_UP | SDL_HAT_LEFT
  30.679 +    };
  30.680 +
  30.681 +    if (LOWORD(value) == 0xFFFF)
  30.682 +        return SDL_HAT_CENTERED;
  30.683 +
  30.684 +    /* Round the value up: */
  30.685 +    value += 4500 / 2;
  30.686 +    value %= 36000;
  30.687 +    value /= 4500;
  30.688 +
  30.689 +    if (value >= 8)
  30.690 +        return SDL_HAT_CENTERED;        /* shouldn't happen */
  30.691 +
  30.692 +    return HAT_VALS[value];
  30.693 +}
  30.694 +
  30.695 +static void
  30.696 +UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
  30.697 +{
  30.698 +    int i;
  30.699 +    HRESULT result;
  30.700 +    DWORD numevents;
  30.701 +    DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
  30.702 +
  30.703 +    numevents = INPUT_QSIZE;
  30.704 +    result =
  30.705 +        IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
  30.706 +        sizeof(DIDEVICEOBJECTDATA), evtbuf,
  30.707 +        &numevents, 0);
  30.708 +    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
  30.709 +        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
  30.710 +        result =
  30.711 +            IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
  30.712 +            sizeof(DIDEVICEOBJECTDATA),
  30.713 +            evtbuf, &numevents, 0);
  30.714 +    }
  30.715 +
  30.716 +    /* Handle the events or punt */
  30.717 +    if (FAILED(result)) {
  30.718 +        joystick->hwdata->send_remove_event = SDL_TRUE;
  30.719 +        joystick->hwdata->removed = SDL_TRUE;
  30.720 +        return;
  30.721 +    }
  30.722 +
  30.723 +    for (i = 0; i < (int)numevents; ++i) {
  30.724 +        int j;
  30.725 +
  30.726 +        for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
  30.727 +            const input_t *in = &joystick->hwdata->Inputs[j];
  30.728 +
  30.729 +            if (evtbuf[i].dwOfs != in->ofs)
  30.730 +                continue;
  30.731 +
  30.732 +            switch (in->type) {
  30.733 +            case AXIS:
  30.734 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
  30.735 +                break;
  30.736 +            case BUTTON:
  30.737 +                SDL_PrivateJoystickButton(joystick, in->num,
  30.738 +                    (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED));
  30.739 +                break;
  30.740 +            case HAT:
  30.741 +                {
  30.742 +                    Uint8 pos = TranslatePOV(evtbuf[i].dwData);
  30.743 +                    SDL_PrivateJoystickHat(joystick, in->num, pos);
  30.744 +                }
  30.745 +                break;
  30.746 +            }
  30.747 +        }
  30.748 +    }
  30.749 +}
  30.750 +
  30.751 +/* Function to update the state of a joystick - called as a device poll.
  30.752 + * This function shouldn't update the joystick structure directly,
  30.753 + * but instead should call SDL_PrivateJoystick*() to deliver events
  30.754 + * and update joystick device state.
  30.755 + */
  30.756 +static void
  30.757 +UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
  30.758 +{
  30.759 +    DIJOYSTATE2 state;
  30.760 +    HRESULT result;
  30.761 +    int i;
  30.762 +
  30.763 +    result =
  30.764 +        IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
  30.765 +        sizeof(DIJOYSTATE2), &state);
  30.766 +    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
  30.767 +        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
  30.768 +        result =
  30.769 +            IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
  30.770 +            sizeof(DIJOYSTATE2), &state);
  30.771 +    }
  30.772 +
  30.773 +    if (result != DI_OK) {
  30.774 +        joystick->hwdata->send_remove_event = SDL_TRUE;
  30.775 +        joystick->hwdata->removed = SDL_TRUE;
  30.776 +        return;
  30.777 +    }
  30.778 +
  30.779 +    /* Set each known axis, button and POV. */
  30.780 +    for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
  30.781 +        const input_t *in = &joystick->hwdata->Inputs[i];
  30.782 +
  30.783 +        switch (in->type) {
  30.784 +        case AXIS:
  30.785 +            switch (in->ofs) {
  30.786 +            case DIJOFS_X:
  30.787 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lX);
  30.788 +                break;
  30.789 +            case DIJOFS_Y:
  30.790 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lY);
  30.791 +                break;
  30.792 +            case DIJOFS_Z:
  30.793 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lZ);
  30.794 +                break;
  30.795 +            case DIJOFS_RX:
  30.796 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRx);
  30.797 +                break;
  30.798 +            case DIJOFS_RY:
  30.799 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRy);
  30.800 +                break;
  30.801 +            case DIJOFS_RZ:
  30.802 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRz);
  30.803 +                break;
  30.804 +            case DIJOFS_SLIDER(0):
  30.805 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[0]);
  30.806 +                break;
  30.807 +            case DIJOFS_SLIDER(1):
  30.808 +                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[1]);
  30.809 +                break;
  30.810 +            }
  30.811 +            break;
  30.812 +
  30.813 +        case BUTTON:
  30.814 +            SDL_PrivateJoystickButton(joystick, in->num,
  30.815 +                (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED));
  30.816 +            break;
  30.817 +        case HAT:
  30.818 +        {
  30.819 +            Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]);
  30.820 +            SDL_PrivateJoystickHat(joystick, in->num, pos);
  30.821 +            break;
  30.822 +        }
  30.823 +        }
  30.824 +    }
  30.825 +}
  30.826 +
  30.827 +void
  30.828 +SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
  30.829 +{
  30.830 +    HRESULT result;
  30.831 +
  30.832 +    result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
  30.833 +    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
  30.834 +        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
  30.835 +        IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
  30.836 +    }
  30.837 +
  30.838 +    if (joystick->hwdata->buffered) {
  30.839 +        UpdateDINPUTJoystickState_Buffered(joystick);
  30.840 +    } else {
  30.841 +        UpdateDINPUTJoystickState_Polled(joystick);
  30.842 +    }
  30.843 +}
  30.844 +
  30.845 +void
  30.846 +SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
  30.847 +{
  30.848 +    IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
  30.849 +    IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
  30.850 +}
  30.851 +
  30.852 +void
  30.853 +SDL_DINPUT_JoystickQuit(void)
  30.854 +{
  30.855 +    if (dinput != NULL) {
  30.856 +        IDirectInput8_Release(dinput);
  30.857 +        dinput = NULL;
  30.858 +    }
  30.859 +
  30.860 +    if (coinitialized) {
  30.861 +        WIN_CoUninitialize();
  30.862 +        coinitialized = SDL_FALSE;
  30.863 +    }
  30.864 +}
  30.865 +
  30.866 +#else /* !SDL_JOYSTICK_DINPUT */
  30.867 +
  30.868 +
  30.869 +int
  30.870 +SDL_DINPUT_JoystickInit(void)
  30.871 +{
  30.872 +    return 0;
  30.873 +}
  30.874 +
  30.875 +void
  30.876 +SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
  30.877 +{
  30.878 +}
  30.879 +
  30.880 +int
  30.881 +SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
  30.882 +{
  30.883 +    return SDL_Unsupported();
  30.884 +}
  30.885 +
  30.886 +void
  30.887 +SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
  30.888 +{
  30.889 +}
  30.890 +
  30.891 +void
  30.892 +SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
  30.893 +{
  30.894 +}
  30.895 +
  30.896 +void
  30.897 +SDL_DINPUT_JoystickQuit(void)
  30.898 +{
  30.899 +}
  30.900 +
  30.901 +#endif /* SDL_JOYSTICK_DINPUT */
  30.902 +
  30.903 +/* vi: set ts=4 sw=4 expandtab: */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/joystick/windows/SDL_dinputjoystick_c.h	Thu Jul 03 15:39:55 2014 -0700
    31.3 @@ -0,0 +1,30 @@
    31.4 +/*
    31.5 +  Simple DirectMedia Layer
    31.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    31.7 +
    31.8 +  This software is provided 'as-is', without any express or implied
    31.9 +  warranty.  In no event will the authors be held liable for any damages
   31.10 +  arising from the use of this software.
   31.11 +
   31.12 +  Permission is granted to anyone to use this software for any purpose,
   31.13 +  including commercial applications, and to alter it and redistribute it
   31.14 +  freely, subject to the following restrictions:
   31.15 +
   31.16 +  1. The origin of this software must not be misrepresented; you must not
   31.17 +     claim that you wrote the original software. If you use this software
   31.18 +     in a product, an acknowledgment in the product documentation would be
   31.19 +     appreciated but is not required.
   31.20 +  2. Altered source versions must be plainly marked as such, and must not be
   31.21 +     misrepresented as being the original software.
   31.22 +  3. This notice may not be removed or altered from any source distribution.
   31.23 +*/
   31.24 +#include "../../SDL_internal.h"
   31.25 +
   31.26 +extern int SDL_DINPUT_JoystickInit(void);
   31.27 +extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
   31.28 +extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
   31.29 +extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick);
   31.30 +extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick);
   31.31 +extern void SDL_DINPUT_JoystickQuit(void);
   31.32 +
   31.33 +/* vi: set ts=4 sw=4 expandtab: */
    32.1 --- a/src/joystick/windows/SDL_dxjoystick.c	Thu Jul 03 17:36:08 2014 -0300
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,1661 +0,0 @@
    32.4 -/*
    32.5 -  Simple DirectMedia Layer
    32.6 -  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
    32.7 -
    32.8 -  This software is provided 'as-is', without any express or implied
    32.9 -  warranty.  In no event will the authors be held liable for any damages
   32.10 -  arising from the use of this software.
   32.11 -
   32.12 -  Permission is granted to anyone to use this software for any purpose,
   32.13 -  including commercial applications, and to alter it and redistribute it
   32.14 -  freely, subject to the following restrictions:
   32.15 -
   32.16 -  1. The origin of this software must not be misrepresented; you must not
   32.17 -     claim that you wrote the original software. If you use this software
   32.18 -     in a product, an acknowledgment in the product documentation would be
   32.19 -     appreciated but is not required.
   32.20 -  2. Altered source versions must be plainly marked as such, and must not be
   32.21 -     misrepresented as being the original software.
   32.22 -  3. This notice may not be removed or altered from any source distribution.
   32.23 -*/
   32.24 -#include "../../SDL_internal.h"
   32.25 -
   32.26 -#ifdef SDL_JOYSTICK_DINPUT
   32.27 -
   32.28 -/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
   32.29 - * A. Formiga's WINMM driver.
   32.30 - *
   32.31 - * Hats and sliders are completely untested; the app I'm writing this for mostly
   32.32 - * doesn't use them and I don't own any joysticks with them.
   32.33 - *
   32.34 - * We don't bother to use event notification here.  It doesn't seem to work
   32.35 - * with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and
   32.36 - * let it return 0 events. */
   32.37 -
   32.38 -#include "SDL_error.h"
   32.39 -#include "SDL_assert.h"
   32.40 -#include "SDL_events.h"
   32.41 -#include "SDL_thread.h"
   32.42 -#include "SDL_timer.h"
   32.43 -#include "SDL_mutex.h"
   32.44 -#include "SDL_events.h"
   32.45 -#include "SDL_hints.h"
   32.46 -#include "SDL_joystick.h"
   32.47 -#include "../SDL_sysjoystick.h"
   32.48 -#if !SDL_EVENTS_DISABLED
   32.49 -#include "../../events/SDL_events_c.h"
   32.50 -#endif
   32.51 -#include "../../core/windows/SDL_windows.h"
   32.52 -
   32.53 -#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
   32.54 -#include "SDL_dxjoystick_c.h"
   32.55 -
   32.56 -#if SDL_HAPTIC_DINPUT
   32.57 -#include "../../haptic/windows/SDL_syshaptic_c.h"    /* For haptic hot plugging */
   32.58 -#endif
   32.59 -
   32.60 -#ifndef DIDFT_OPTIONAL
   32.61 -#define DIDFT_OPTIONAL      0x80000000
   32.62 -#endif
   32.63 -
   32.64 -DEFINE_GUID(GUID_DEVINTERFACE_HID, 0x4D1E55B2L, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30);
   32.65 -
   32.66 -
   32.67 -#define INPUT_QSIZE 32      /* Buffer up to 32 input messages */
   32.68 -#define AXIS_MIN    -32768  /* minimum value for axis coordinate */
   32.69 -#define AXIS_MAX    32767   /* maximum value for axis coordinate */
   32.70 -#define JOY_AXIS_THRESHOLD  (((AXIS_MAX)-(AXIS_MIN))/100)   /* 1% motion */
   32.71 -
   32.72 -/* external variables referenced. */
   32.73 -extern HWND SDL_HelperWindow;
   32.74 -
   32.75 -
   32.76 -/* local variables */
   32.77 -static SDL_bool coinitialized = SDL_FALSE;
   32.78 -static LPDIRECTINPUT8 dinput = NULL;
   32.79 -static SDL_bool s_bDeviceAdded = SDL_FALSE;
   32.80 -static SDL_bool s_bDeviceRemoved = SDL_FALSE;
   32.81 -static SDL_JoystickID s_nInstanceID = -1;
   32.82 -static SDL_cond *s_condJoystickThread = NULL;
   32.83 -static SDL_mutex *s_mutexJoyStickEnum = NULL;
   32.84 -static SDL_Thread *s_threadJoystick = NULL;
   32.85 -static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
   32.86 -static SDL_bool s_bXInputEnabled = SDL_TRUE;
   32.87 -
   32.88 -XInputGetState_t SDL_XInputGetState = NULL;
   32.89 -XInputSetState_t SDL_XInputSetState = NULL;
   32.90 -XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;
   32.91 -DWORD SDL_XInputVersion = 0;
   32.92 -
   32.93 -static HANDLE s_pXInputDLL = 0;
   32.94 -static int s_XInputDLLRefCount = 0;
   32.95 -
   32.96 -int
   32.97 -WIN_LoadXInputDLL(void)
   32.98 -{
   32.99 -    DWORD version = 0;
  32.100 -
  32.101 -    if (s_pXInputDLL) {
  32.102 -        SDL_assert(s_XInputDLLRefCount > 0);
  32.103 -        s_XInputDLLRefCount++;
  32.104 -        return 0;  /* already loaded */
  32.105 -    }
  32.106 -
  32.107 -    version = (1 << 16) | 4;
  32.108 -    s_pXInputDLL = LoadLibrary(L"XInput1_4.dll");  /* 1.4 Ships with Windows 8. */
  32.109 -    if (!s_pXInputDLL) {
  32.110 -        version = (1 << 16) | 3;
  32.111 -        s_pXInputDLL = LoadLibrary(L"XInput1_3.dll");  /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */
  32.112 -    }
  32.113 -    if (!s_pXInputDLL) {
  32.114 -        s_pXInputDLL = LoadLibrary(L"bin\\XInput1_3.dll");
  32.115 -    }
  32.116 -    if (!s_pXInputDLL) {
  32.117 -        return -1;
  32.118 -    }
  32.119 -
  32.120 -    SDL_assert(s_XInputDLLRefCount == 0);
  32.121 -    SDL_XInputVersion = version;
  32.122 -    s_XInputDLLRefCount = 1;
  32.123 -
  32.124 -    /* 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... */
  32.125 -    SDL_XInputGetState = (XInputGetState_t)GetProcAddress((HMODULE)s_pXInputDLL, (LPCSTR)100);
  32.126 -    SDL_XInputSetState = (XInputSetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputSetState");
  32.127 -    SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetCapabilities");
  32.128 -    if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) {
  32.129 -        WIN_UnloadXInputDLL();
  32.130 -        return -1;
  32.131 -    }
  32.132 -
  32.133 -    return 0;
  32.134 -}
  32.135 -
  32.136 -void
  32.137 -WIN_UnloadXInputDLL(void)
  32.138 -{
  32.139 -    if (s_pXInputDLL) {
  32.140 -        SDL_assert(s_XInputDLLRefCount > 0);
  32.141 -        if (--s_XInputDLLRefCount == 0) {
  32.142 -            FreeLibrary(s_pXInputDLL);
  32.143 -            s_pXInputDLL = NULL;
  32.144 -        }
  32.145 -    } else {
  32.146 -        SDL_assert(s_XInputDLLRefCount == 0);
  32.147 -    }
  32.148 -}
  32.149 -
  32.150 -
  32.151 -extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
  32.152 -                                       LPDIRECTINPUT * ppDI,
  32.153 -                                       LPUNKNOWN punkOuter);
  32.154 -struct JoyStick_DeviceData_
  32.155 -{
  32.156 -    SDL_JoystickGUID guid;
  32.157 -    DIDEVICEINSTANCE dxdevice;
  32.158 -    char *joystickname;
  32.159 -    Uint8 send_add_event;
  32.160 -    SDL_JoystickID nInstanceID;
  32.161 -    SDL_bool bXInputDevice;
  32.162 -    BYTE SubType;
  32.163 -    Uint8 XInputUserId;
  32.164 -    struct JoyStick_DeviceData_ *pNext;
  32.165 -};
  32.166 -
  32.167 -typedef struct JoyStick_DeviceData_ JoyStick_DeviceData;
  32.168 -
  32.169 -static JoyStick_DeviceData *SYS_Joystick;    /* array to hold joystick ID values */
  32.170 -
  32.171 -/* local prototypes */
  32.172 -static int SetDIerror(const char *function, HRESULT code);
  32.173 -static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE *
  32.174 -                                           pdidInstance, VOID * pContext);
  32.175 -static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
  32.176 -                                            LPVOID pvRef);
  32.177 -static void SortDevObjects(SDL_Joystick *joystick);
  32.178 -static Uint8 TranslatePOV(DWORD value);
  32.179 -
  32.180 -/* Taken from Wine - Thanks! */
  32.181 -DIOBJECTDATAFORMAT dfDIJoystick2[] = {
  32.182 -  { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.183 -  { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.184 -  { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.185 -  { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.186 -  { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.187 -  { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.188 -  { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.189 -  { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.190 -  { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  32.191 -  { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  32.192 -  { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  32.193 -  { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  32.194 -  { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.195 -  { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.196 -  { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.197 -  { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.198 -  { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.199 -  { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.200 -  { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.201 -  { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.202 -  { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.203 -  { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.204 -  { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.205 -  { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.206 -  { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.207 -  { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.208 -  { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.209 -  { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.210 -  { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.211 -  { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.212 -  { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.213 -  { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.214 -  { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.215 -  { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.216 -  { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.217 -  { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.218 -  { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.219 -  { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.220 -  { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.221 -  { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.222 -  { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.223 -  { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.224 -  { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.225 -  { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.226 -  { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.227 -  { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.228 -  { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.229 -  { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.230 -  { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.231 -  { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.232 -  { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.233 -  { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.234 -  { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.235 -  { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.236 -  { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.237 -  { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.238 -  { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.239 -  { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.240 -  { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.241 -  { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.242 -  { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.243 -  { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.244 -  { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.245 -  { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.246 -  { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.247 -  { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.248 -  { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.249 -  { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.250 -  { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.251 -  { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.252 -  { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.253 -  { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.254 -  { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.255 -  { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.256 -  { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.257 -  { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.258 -  { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.259 -  { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.260 -  { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.261 -  { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.262 -  { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.263 -  { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.264 -  { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.265 -  { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.266 -  { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.267 -  { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.268 -  { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.269 -  { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.270 -  { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.271 -  { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.272 -  { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.273 -  { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.274 -  { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.275 -  { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.276 -  { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.277 -  { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.278 -  { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.279 -  { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.280 -  { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.281 -  { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.282 -  { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.283 -  { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.284 -  { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.285 -  { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.286 -  { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.287 -  { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.288 -  { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.289 -  { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.290 -  { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.291 -  { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.292 -  { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.293 -  { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.294 -  { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.295 -  { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.296 -  { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.297 -  { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.298 -  { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.299 -  { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.300 -  { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.301 -  { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.302 -  { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.303 -  { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.304 -  { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.305 -  { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.306 -  { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.307 -  { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.308 -  { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.309 -  { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.310 -  { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.311 -  { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.312 -  { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.313 -  { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.314 -  { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.315 -  { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.316 -  { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.317 -  { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.318 -  { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.319 -  { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.320 -  { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.321 -  { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  32.322 -  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.323 -  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.324 -  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.325 -  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.326 -  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.327 -  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.328 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.329 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.330 -  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.331 -  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.332 -  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.333 -  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.334 -  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.335 -  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.336 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.337 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.338 -  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.339 -  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.340 -  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.341 -  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.342 -  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.343 -  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.344 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.345 -  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  32.346 -};
  32.347 -
  32.348 -const DIDATAFORMAT c_dfDIJoystick2 = {
  32.349 -    sizeof(DIDATAFORMAT),
  32.350 -    sizeof(DIOBJECTDATAFORMAT),
  32.351 -    DIDF_ABSAXIS,
  32.352 -    sizeof(DIJOYSTATE2),
  32.353 -    SDL_arraysize(dfDIJoystick2),
  32.354 -    dfDIJoystick2
  32.355 -};
  32.356 -
  32.357 -
  32.358 -/* Convert a DirectInput return code to a text message */
  32.359 -static int
  32.360 -SetDIerror(const char *function, HRESULT code)
  32.361 -{
  32.362 -    /*
  32.363 -    return SDL_SetError("%s() [%s]: %s", function,
  32.364 -                 DXGetErrorString9A(code), DXGetErrorDescription9A(code));
  32.365 -     */
  32.366 -    return SDL_SetError("%s() DirectX error %d", function, code);
  32.367 -}
  32.368 -
  32.369 -
  32.370 -#define SAFE_RELEASE(p)                             \
  32.371 -{                                                   \
  32.372 -    if (p) {                                        \
  32.373 -        (p)->lpVtbl->Release((p));                  \
  32.374 -        (p) = 0;                                    \
  32.375 -    }                                               \
  32.376 -}
  32.377 -
  32.378 -DEFINE_GUID(IID_ValveStreamingGamepad,  MAKELONG(0x28DE, 0x11FF),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
  32.379 -DEFINE_GUID(IID_X360WiredGamepad,  MAKELONG(0x045E, 0x02A1),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
  32.380 -DEFINE_GUID(IID_X360WirelessGamepad,  MAKELONG(0x045E, 0x028E),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
  32.381 -
  32.382 -static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
  32.383 -static UINT SDL_RawDevListCount = 0;
  32.384 -
  32.385 -static SDL_bool
  32.386 -SDL_XInputUseOldJoystickMapping()
  32.387 -{
  32.388 -	static int s_XInputUseOldJoystickMapping = -1;
  32.389 -	if (s_XInputUseOldJoystickMapping < 0) {
  32.390 -		const char *hint = SDL_GetHint(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING);
  32.391 -		s_XInputUseOldJoystickMapping = (hint && *hint == '1') ? 1 : 0;
  32.392 -	}
  32.393 -	return (s_XInputUseOldJoystickMapping > 0);
  32.394 -}
  32.395 -
  32.396 -static SDL_bool
  32.397 -SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
  32.398 -{
  32.399 -    static const GUID *s_XInputProductGUID[] = {
  32.400 -        &IID_ValveStreamingGamepad,
  32.401 -        &IID_X360WiredGamepad,   /* Microsoft's wired X360 controller for Windows. */
  32.402 -        &IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */
  32.403 -    };
  32.404 -
  32.405 -    size_t iDevice;
  32.406 -    UINT i;
  32.407 -
  32.408 -    if (!s_bXInputEnabled) {
  32.409 -        return SDL_FALSE;
  32.410 -    }
  32.411 -
  32.412 -    /* Check for well known XInput device GUIDs */
  32.413 -    /* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
  32.414 -    for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
  32.415 -        if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
  32.416 -            return SDL_TRUE;
  32.417 -        }
  32.418 -    }
  32.419 -
  32.420 -    /* Go through RAWINPUT (WinXP and later) to find HID devices. */
  32.421 -    /* Cache this if we end up using it. */
  32.422 -    if (SDL_RawDevList == NULL) {
  32.423 -        if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof (RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
  32.424 -            return SDL_FALSE;  /* oh well. */
  32.425 -        }
  32.426 -
  32.427 -        SDL_RawDevList = (PRAWINPUTDEVICELIST) SDL_malloc(sizeof (RAWINPUTDEVICELIST) * SDL_RawDevListCount);
  32.428 -        if (SDL_RawDevList == NULL) {
  32.429 -            SDL_OutOfMemory();
  32.430 -            return SDL_FALSE;
  32.431 -        }
  32.432 -
  32.433 -        if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof (RAWINPUTDEVICELIST)) == -1) {
  32.434 -             SDL_free(SDL_RawDevList);
  32.435 -             SDL_RawDevList = NULL;
  32.436 -             return SDL_FALSE;  /* oh well. */
  32.437 -        }
  32.438 -    }
  32.439 -
  32.440 -    for (i = 0; i < SDL_RawDevListCount; i++) {
  32.441 -        RID_DEVICE_INFO rdi;
  32.442 -        char devName[128];
  32.443 -        UINT rdiSize = sizeof (rdi);
  32.444 -        UINT nameSize = SDL_arraysize(devName);
  32.445 -
  32.446 -        rdi.cbSize = sizeof (rdi);
  32.447 -        if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
  32.448 -             (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
  32.449 -             (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
  32.450 -             (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
  32.451 -             (SDL_strstr(devName, "IG_") != NULL)) {
  32.452 -             return SDL_TRUE;
  32.453 -        }
  32.454 -    }
  32.455 -
  32.456 -    return SDL_FALSE;
  32.457 -}
  32.458 -
  32.459 -
  32.460 -static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
  32.461 -
  32.462 -/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal
  32.463 - */
  32.464 -LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  32.465 -{
  32.466 -    switch (message) {
  32.467 -    case WM_DEVICECHANGE:
  32.468 -        switch (wParam) {
  32.469 -        case DBT_DEVICEARRIVAL:
  32.470 -            if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
  32.471 -                s_bWindowsDeviceChanged = SDL_TRUE;
  32.472 -            }
  32.473 -            break;
  32.474 -        case DBT_DEVICEREMOVECOMPLETE:
  32.475 -            if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
  32.476 -                s_bWindowsDeviceChanged = SDL_TRUE;
  32.477 -            }
  32.478 -            break;
  32.479 -        }
  32.480 -        return 0;
  32.481 -    }
  32.482 -
  32.483 -    return DefWindowProc (hwnd, message, wParam, lParam);
  32.484 -}
  32.485 -
  32.486 -
  32.487 -DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \
  32.488 -    0xC0, 0x4F, 0xB9, 0x51, 0xED);
  32.489 -
  32.490 -/* Function/thread to scan the system for joysticks.
  32.491 - */
  32.492 -static int
  32.493 -SDL_JoystickThread(void *_data)
  32.494 -{
  32.495 -    HWND messageWindow = 0;
  32.496 -    HDEVNOTIFY hNotify = 0;
  32.497 -    DEV_BROADCAST_DEVICEINTERFACE dbh;
  32.498 -    SDL_bool bOpenedXInputDevices[SDL_XINPUT_MAX_DEVICES];
  32.499 -    WNDCLASSEX wincl;
  32.500 -
  32.501 -    SDL_zero(bOpenedXInputDevices);
  32.502 -
  32.503 -    WIN_CoInitialize();
  32.504 -
  32.505 -    SDL_memset(&wincl, 0x0, sizeof(wincl));
  32.506 -    wincl.hInstance = GetModuleHandle(NULL);
  32.507 -    wincl.lpszClassName = L"Message";
  32.508 -    wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;      /* This function is called by windows */
  32.509 -    wincl.cbSize = sizeof (WNDCLASSEX);
  32.510 -
  32.511 -    if (!RegisterClassEx (&wincl)) {
  32.512 -        return WIN_SetError("Failed to create register class for joystick autodetect");
  32.513 -    }
  32.514 -
  32.515 -    messageWindow = (HWND)CreateWindowEx(0,  L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
  32.516 -    if (!messageWindow) {
  32.517 -        return WIN_SetError("Failed to create message window for joystick autodetect");
  32.518 -    }
  32.519 -
  32.520 -    SDL_zero(dbh);
  32.521 -
  32.522 -    dbh.dbcc_size = sizeof(dbh);
  32.523 -    dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  32.524 -    dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
  32.525 -
  32.526 -    hNotify = RegisterDeviceNotification(messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
  32.527 -    if (!hNotify) {
  32.528 -        return WIN_SetError("Failed to create notify device for joystick autodetect");
  32.529 -    }
  32.530 -
  32.531 -    SDL_LockMutex(s_mutexJoyStickEnum);
  32.532 -    while (s_bJoystickThreadQuit == SDL_FALSE) {
  32.533 -        MSG messages;
  32.534 -        SDL_bool bXInputChanged = SDL_FALSE;
  32.535 -
  32.536 -        SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 300);
  32.537 -
  32.538 -        while (s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE)) {
  32.539 -            if (GetMessage(&messages, messageWindow, 0, 0) != 0)  {
  32.540 -                TranslateMessage(&messages);
  32.541 -                DispatchMessage(&messages);
  32.542 -            }
  32.543 -        }
  32.544 -
  32.545 -        if (s_bXInputEnabled && XINPUTGETCAPABILITIES) {
  32.546 -            /* scan for any change in XInput devices */
  32.547 -            Uint8 userId;
  32.548 -            for (userId = 0; userId < SDL_XINPUT_MAX_DEVICES; userId++) {
  32.549 -                XINPUT_CAPABILITIES capabilities;
  32.550 -                const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
  32.551 -                const SDL_bool available = (result == ERROR_SUCCESS);
  32.552 -                if (bOpenedXInputDevices[userId] != available) {
  32.553 -                    bXInputChanged = SDL_TRUE;
  32.554 -                    bOpenedXInputDevices[userId] = available;
  32.555 -                }
  32.556 -            }
  32.557 -        }
  32.558 -
  32.559 -        if (s_bWindowsDeviceChanged || bXInputChanged) {
  32.560 -            SDL_UnlockMutex(s_mutexJoyStickEnum);  /* let main thread go while we SDL_Delay(). */
  32.561 -            SDL_Delay(300); /* wait for direct input to find out about this device */
  32.562 -            SDL_LockMutex(s_mutexJoyStickEnum);
  32.563 -
  32.564 -            s_bDeviceRemoved = SDL_TRUE;
  32.565 -            s_bDeviceAdded = SDL_TRUE;
  32.566 -            s_bWindowsDeviceChanged = SDL_FALSE;
  32.567 -        }
  32.568 -    }
  32.569 -    SDL_UnlockMutex(s_mutexJoyStickEnum);
  32.570 -
  32.571 -    if (hNotify)
  32.572 -        UnregisterDeviceNotification(hNotify);
  32.573 -
  32.574 -    if (messageWindow)
  32.575 -        DestroyWindow(messageWindow);
  32.576 -
  32.577 -    UnregisterClass(wincl.lpszClassName, wincl.hInstance);
  32.578 -    messageWindow = 0;
  32.579 -    WIN_CoUninitialize();
  32.580 -    return 1;
  32.581 -}
  32.582 -
  32.583 -
  32.584 -/* Function to scan the system for joysticks.
  32.585 - * This function should set SDL_numjoysticks to the number of available
  32.586 - * joysticks.  Joystick 0 should be the system default joystick.
  32.587 - * It should return 0, or -1 on an unrecoverable fatal error.
  32.588 - */
  32.589 -int
  32.590 -SDL_SYS_JoystickInit(void)
  32.591 -{
  32.592 -    HRESULT result;
  32.593 -    HINSTANCE instance;
  32.594 -    const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
  32.595 -    if (env && !SDL_atoi(env)) {
  32.596 -        s_bXInputEnabled = SDL_FALSE;
  32.597 -    }
  32.598 -
  32.599 -    result = WIN_CoInitialize();
  32.600 -    if (FAILED(result)) {
  32.601 -        return SetDIerror("CoInitialize", result);
  32.602 -    }
  32.603 -
  32.604 -    coinitialized = SDL_TRUE;
  32.605 -
  32.606 -    result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
  32.607 -                              &IID_IDirectInput8, (LPVOID)&dinput);
  32.608 -
  32.609 -    if (FAILED(result)) {
  32.610 -        SDL_SYS_JoystickQuit();
  32.611 -        return SetDIerror("CoCreateInstance", result);
  32.612 -    }
  32.613 -
  32.614 -    /* Because we used CoCreateInstance, we need to Initialize it, first. */
  32.615 -    instance = GetModuleHandle(NULL);
  32.616 -    if (instance == NULL) {
  32.617 -        SDL_SYS_JoystickQuit();
  32.618 -        return SDL_SetError("GetModuleHandle() failed with error code %d.", GetLastError());
  32.619 -    }
  32.620 -    result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
  32.621 -
  32.622 -    if (FAILED(result)) {
  32.623 -        SDL_SYS_JoystickQuit();
  32.624 -        return SetDIerror("IDirectInput::Initialize", result);
  32.625 -    }
  32.626 -
  32.627 -    if ((s_bXInputEnabled) && (WIN_LoadXInputDLL() == -1)) {
  32.628 -        s_bXInputEnabled = SDL_FALSE;  /* oh well. */
  32.629 -    }
  32.630 -
  32.631 -    s_mutexJoyStickEnum = SDL_CreateMutex();
  32.632 -    s_condJoystickThread = SDL_CreateCond();
  32.633 -    s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
  32.634 -
  32.635 -    SDL_SYS_JoystickDetect();
  32.636 -
  32.637 -    if (!s_threadJoystick) {
  32.638 -        s_bJoystickThreadQuit = SDL_FALSE;
  32.639 -        /* spin up the thread to detect hotplug of devices */
  32.640 -#if defined(__WIN32__) && !defined(HAVE_LIBC)
  32.641 -#undef SDL_CreateThread
  32.642 -#if SDL_DYNAMIC_API
  32.643 -        s_threadJoystick= SDL_CreateThread_REAL(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL);
  32.644 -#else
  32.645 -        s_threadJoystick= SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL);
  32.646 -#endif
  32.647 -#else
  32.648 -        s_threadJoystick = SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL);
  32.649 -#endif
  32.650 -    }
  32.651 -        return SDL_SYS_NumJoysticks();
  32.652 -}
  32.653 -
  32.654 -/* return the number of joysticks that are connected right now */
  32.655 -int SDL_SYS_NumJoysticks()
  32.656 -{
  32.657 -    int nJoysticks = 0;
  32.658 -    JoyStick_DeviceData *device = SYS_Joystick;
  32.659 -    while (device) {
  32.660 -        nJoysticks++;
  32.661 -        device = device->pNext;
  32.662 -    }
  32.663 -
  32.664 -    return nJoysticks;
  32.665 -}
  32.666 -
  32.667 -/* helper function for direct input, gets called for each connected joystick */
  32.668 -static BOOL CALLBACK
  32.669 -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
  32.670 -{
  32.671 -    JoyStick_DeviceData *pNewJoystick;
  32.672 -    JoyStick_DeviceData *pPrevJoystick = NULL;
  32.673 -
  32.674 -    if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
  32.675 -        return DIENUM_CONTINUE;  /* ignore XInput devices here, keep going. */
  32.676 -    }
  32.677 -
  32.678 -    pNewJoystick = *(JoyStick_DeviceData **)pContext;
  32.679 -    while (pNewJoystick) {
  32.680 -        if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) {
  32.681 -            /* if we are replacing the front of the list then update it */
  32.682 -            if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
  32.683 -                *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
  32.684 -            } else if (pPrevJoystick) {
  32.685 -                pPrevJoystick->pNext = pNewJoystick->pNext;
  32.686 -            }
  32.687 -
  32.688 -            pNewJoystick->pNext = SYS_Joystick;
  32.689 -            SYS_Joystick = pNewJoystick;
  32.690 -
  32.691 -            return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
  32.692 -        }
  32.693 -
  32.694 -        pPrevJoystick = pNewJoystick;
  32.695 -        pNewJoystick = pNewJoystick->pNext;
  32.696 -    }
  32.697 -
  32.698 -    pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
  32.699 -    if (!pNewJoystick) {
  32.700 -        return DIENUM_CONTINUE; /* better luck next time? */
  32.701 -    }
  32.702 -
  32.703 -    SDL_zerop(pNewJoystick);
  32.704 -    pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
  32.705 -    if (!pNewJoystick->joystickname) {
  32.706 -        SDL_free(pNewJoystick);
  32.707 -        return DIENUM_CONTINUE; /* better luck next time? */
  32.708 -    }
  32.709 -
  32.710 -    SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
  32.711 -        sizeof(DIDEVICEINSTANCE));
  32.712 -
  32.713 -    pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
  32.714 -    pNewJoystick->send_add_event = SDL_TRUE;
  32.715 -    pNewJoystick->nInstanceID = ++s_nInstanceID;
  32.716 -    SDL_memcpy(&pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid));
  32.717 -    pNewJoystick->pNext = SYS_Joystick;
  32.718 -    SYS_Joystick = pNewJoystick;
  32.719 -
  32.720 -    s_bDeviceAdded = SDL_TRUE;
  32.721 -
  32.722 -    return DIENUM_CONTINUE; /* get next device, please */
  32.723 -}
  32.724 -
  32.725 -static char *
  32.726 -GetXInputName(const Uint8 userid, BYTE SubType)
  32.727 -{
  32.728 -    char name[32];
  32.729 -
  32.730 -	if (SDL_XInputUseOldJoystickMapping()) {
  32.731 -		SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid);
  32.732 -	} else {
  32.733 -		switch (SubType) {
  32.734 -		case XINPUT_DEVSUBTYPE_GAMEPAD:
  32.735 -			SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid);
  32.736 -			break;
  32.737 -		case XINPUT_DEVSUBTYPE_WHEEL:
  32.738 -			SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid);
  32.739 -			break;
  32.740 -		case XINPUT_DEVSUBTYPE_ARCADE_STICK:
  32.741 -			SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid);
  32.742 -			break;
  32.743 -		case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
  32.744 -			SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid);
  32.745 -			break;
  32.746 -		case XINPUT_DEVSUBTYPE_DANCE_PAD:
  32.747 -			SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid);
  32.748 -			break;
  32.749 -		case XINPUT_DEVSUBTYPE_GUITAR:
  32.750 -		case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
  32.751 -		case XINPUT_DEVSUBTYPE_GUITAR_BASS:
  32.752 -			SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid);
  32.753 -			break;
  32.754 -		case XINPUT_DEVSUBTYPE_DRUM_KIT:
  32.755 -			SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid);
  32.756 -			break;
  32.757 -		case XINPUT_DEVSUBTYPE_ARCADE_PAD:
  32.758 -			SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid);
  32.759 -			break;
  32.760 -		default:
  32.761 -			SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid);
  32.762 -			break;
  32.763 -		}
  32.764 -	}
  32.765 -    return SDL_strdup(name);
  32.766 -}
  32.767 -
  32.768 -static void
  32.769 -AddXInputDevice(const Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
  32.770 -{
  32.771 -    JoyStick_DeviceData *pPrevJoystick = NULL;
  32.772 -	JoyStick_DeviceData *pNewJoystick = *pContext;
  32.773 -
  32.774 -	if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
  32.775 -		return;
  32.776 -
  32.777 -    if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
  32.778 -		return;
  32.779 -
  32.780 -    while (pNewJoystick) {
  32.781 -        if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) {
  32.782 -            /* if we are replacing the front of the list then update it */
  32.783 -            if (pNewJoystick == *pContext) {
  32.784 -                *pContext = pNewJoystick->pNext;
  32.785 -            } else if (pPrevJoystick) {
  32.786 -                pPrevJoystick->pNext = pNewJoystick->pNext;
  32.787 -            }
  32.788 -
  32.789 -            pNewJoystick->pNext = SYS_Joystick;
  32.790 -            SYS_Joystick = pNewJoystick;
  32.791 -            return;   /* already in the list. */